diff options
author | markus@openbsd.org <markus@openbsd.org> | 2019-11-13 08:53:10 +0100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2019-11-14 22:50:10 +0100 |
commit | bf219920b70cafbf29ebc9890ef67d0efa54e738 (patch) | |
tree | 58f360f1387c7238a4bc1f8c63cdc5ccbfb88dd5 /sshkey-xmss.c | |
parent | upstream: remove size_t gl_pathc < 0 test, it is invalid. the (diff) | |
download | openssh-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.c | 56 |
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; |