summaryrefslogtreecommitdiffstats
path: root/sshkey-xmss.c
diff options
context:
space:
mode:
authormarkus@openbsd.org <markus@openbsd.org>2019-11-13 08:53:10 +0100
committerDamien Miller <djm@mindrot.org>2019-11-14 22:50:10 +0100
commitbf219920b70cafbf29ebc9890ef67d0efa54e738 (patch)
tree58f360f1387c7238a4bc1f8c63cdc5ccbfb88dd5 /sshkey-xmss.c
parentupstream: remove size_t gl_pathc < 0 test, it is invalid. the (diff)
downloadopenssh-bf219920b70cafbf29ebc9890ef67d0efa54e738.tar.xz
openssh-bf219920b70cafbf29ebc9890ef67d0efa54e738.zip
upstream: fix shield/unshield for xmss keys: - in ssh-agent we need
to delay the call to shield until we have received key specific options. - when serializing xmss keys for shield we need to deal with all optional components (e.g. state might not be loaded). ok djm@ OpenBSD-Commit-ID: cc2db82524b209468eb176d6b4d6b9486422f41f
Diffstat (limited to 'sshkey-xmss.c')
-rw-r--r--sshkey-xmss.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/sshkey-xmss.c b/sshkey-xmss.c
index e8e2e3816..88e9ddf4d 100644
--- a/sshkey-xmss.c
+++ b/sshkey-xmss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey-xmss.c,v 1.7 2019/10/14 06:00:02 djm Exp $ */
+/* $OpenBSD: sshkey-xmss.c,v 1.8 2019/11/13 07:53:10 markus Exp $ */
/*
* Copyright (c) 2017 Markus Friedl. All rights reserved.
*
@@ -69,7 +69,7 @@ struct ssh_xmss_state {
u_int32_t maxidx; /* restricted # of signatures */
int have_state; /* .state file exists */
int lockfd; /* locked in sshkey_xmss_get_state() */
- int allow_update; /* allow sshkey_xmss_update_state() */
+ u_char allow_update; /* allow sshkey_xmss_update_state() */
char *enc_ciphername;/* encrypt state with cipher */
u_char *enc_keyiv; /* encrypt state with key */
u_int32_t enc_keyiv_len; /* length of enc_keyiv */
@@ -716,6 +716,7 @@ sshkey_xmss_serialize_state_opt(const struct sshkey *k, struct sshbuf *b,
{
struct ssh_xmss_state *state = k->xmss_state;
int r = SSH_ERR_INVALID_ARGUMENT;
+ u_char have_stack, have_filename, have_enc;
if (state == NULL)
return SSH_ERR_INVALID_ARGUMENT;
@@ -727,9 +728,35 @@ sshkey_xmss_serialize_state_opt(const struct sshkey *k, struct sshbuf *b,
break;
case SSHKEY_SERIALIZE_FULL:
if ((r = sshkey_xmss_serialize_enc_key(k, b)) != 0)
- break;
+ return r;
r = sshkey_xmss_serialize_state(k, b);
break;
+ case SSHKEY_SERIALIZE_SHIELD:
+ /* all of stack/filename/enc are optional */
+ have_stack = state->stack != NULL;
+ if ((r = sshbuf_put_u8(b, have_stack)) != 0)
+ return r;
+ if (have_stack) {
+ state->idx = PEEK_U32(k->xmss_sk); /* update */
+ if ((r = sshkey_xmss_serialize_state(k, b)) != 0)
+ return r;
+ }
+ have_filename = k->xmss_filename != NULL;
+ if ((r = sshbuf_put_u8(b, have_filename)) != 0)
+ return r;
+ if (have_filename &&
+ (r = sshbuf_put_cstring(b, k->xmss_filename)) != 0)
+ return r;
+ have_enc = state->enc_keyiv != NULL;
+ if ((r = sshbuf_put_u8(b, have_enc)) != 0)
+ return r;
+ if (have_enc &&
+ (r = sshkey_xmss_serialize_enc_key(k, b)) != 0)
+ return r;
+ if ((r = sshbuf_put_u32(b, state->maxidx)) != 0 ||
+ (r = sshbuf_put_u8(b, state->allow_update)) != 0)
+ return r;
+ break;
case SSHKEY_SERIALIZE_DEFAULT:
r = 0;
break;
@@ -808,8 +835,9 @@ sshkey_xmss_deserialize_state(struct sshkey *k, struct sshbuf *b)
int
sshkey_xmss_deserialize_state_opt(struct sshkey *k, struct sshbuf *b)
{
+ struct ssh_xmss_state *state = k->xmss_state;
enum sshkey_serialize_rep opts;
- u_char have_state;
+ u_char have_state, have_stack, have_filename, have_enc;
int r;
if ((r = sshbuf_get_u8(b, &have_state)) != 0)
@@ -820,6 +848,26 @@ sshkey_xmss_deserialize_state_opt(struct sshkey *k, struct sshbuf *b)
case SSHKEY_SERIALIZE_DEFAULT:
r = 0;
break;
+ case SSHKEY_SERIALIZE_SHIELD:
+ if ((r = sshbuf_get_u8(b, &have_stack)) != 0)
+ return r;
+ if (have_stack &&
+ (r = sshkey_xmss_deserialize_state(k, b)) != 0)
+ return r;
+ if ((r = sshbuf_get_u8(b, &have_filename)) != 0)
+ return r;
+ if (have_filename &&
+ (r = sshbuf_get_cstring(b, &k->xmss_filename, NULL)) != 0)
+ return r;
+ if ((r = sshbuf_get_u8(b, &have_enc)) != 0)
+ return r;
+ if (have_enc &&
+ (r = sshkey_xmss_deserialize_enc_key(k, b)) != 0)
+ return r;
+ if ((r = sshbuf_get_u32(b, &state->maxidx)) != 0 ||
+ (r = sshbuf_get_u8(b, &state->allow_update)) != 0)
+ return r;
+ break;
case SSHKEY_SERIALIZE_STATE:
if ((r = sshkey_xmss_deserialize_state(k, b)) != 0)
return r;