diff options
-rw-r--r-- | ssh-dss.c | 21 | ||||
-rw-r--r-- | ssh-ecdsa-sk.c | 20 | ||||
-rw-r--r-- | ssh-ecdsa.c | 19 | ||||
-rw-r--r-- | ssh-ed25519-sk.c | 17 | ||||
-rw-r--r-- | ssh-ed25519.c | 16 | ||||
-rw-r--r-- | ssh-rsa.c | 29 | ||||
-rw-r--r-- | ssh-xmss.c | 23 | ||||
-rw-r--r-- | sshd.c | 4 | ||||
-rw-r--r-- | sshkey.c | 194 | ||||
-rw-r--r-- | sshkey.h | 6 |
10 files changed, 171 insertions, 178 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-dss.c,v 1.46 2022/10/28 00:43:08 djm Exp $ */ +/* $OpenBSD: ssh-dss.c,v 1.47 2022/10/28 00:44:17 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -126,6 +126,24 @@ ssh_dss_serialize_public(const struct sshkey *key, struct sshbuf *b, } static int +ssh_dss_serialize_private(const struct sshkey *key, struct sshbuf *b, + enum sshkey_serialize_rep opts) +{ + int r; + const BIGNUM *dsa_priv_key; + + DSA_get0_key(key->dsa, NULL, &dsa_priv_key); + if (!sshkey_is_cert(key)) { + if ((r = ssh_dss_serialize_public(key, b, opts)) != 0) + return r; + } + if ((r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0) + return r; + + return 0; +} + +static int ssh_dss_generate(struct sshkey *k, int bits) { DSA *private; @@ -384,6 +402,7 @@ static const struct sshkey_impl_funcs sshkey_dss_funcs = { /* .equal = */ ssh_dss_equal, /* .ssh_serialize_public = */ ssh_dss_serialize_public, /* .ssh_deserialize_public = */ ssh_dss_deserialize_public, + /* .ssh_serialize_private = */ ssh_dss_serialize_private, /* .generate = */ ssh_dss_generate, /* .copy_public = */ ssh_dss_copy_public, /* .sign = */ ssh_dss_sign, diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c index 6e08d8696..51e444a52 100644 --- a/ssh-ecdsa-sk.c +++ b/ssh-ecdsa-sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa-sk.c,v 1.15 2022/10/28 00:43:08 djm Exp $ */ +/* $OpenBSD: ssh-ecdsa-sk.c,v 1.16 2022/10/28 00:44:17 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -96,6 +96,23 @@ ssh_ecdsa_sk_serialize_public(const struct sshkey *key, struct sshbuf *b, } static int +ssh_ecdsa_sk_serialize_private(const struct sshkey *key, struct sshbuf *b, + enum sshkey_serialize_rep opts) +{ + int r; + + if (!sshkey_is_cert(key)) { + if ((r = sshkey_ecdsa_funcs.serialize_public(key, + b, opts)) != 0) + return r; + } + if ((r = sshkey_serialize_private_sk(key, b)) != 0) + return r; + + return 0; +} + +static int ssh_ecdsa_sk_copy_public(const struct sshkey *from, struct sshkey *to) { int r; @@ -387,6 +404,7 @@ static const struct sshkey_impl_funcs sshkey_ecdsa_sk_funcs = { /* .equal = */ ssh_ecdsa_sk_equal, /* .ssh_serialize_public = */ ssh_ecdsa_sk_serialize_public, /* .ssh_deserialize_public = */ ssh_ecdsa_sk_deserialize_public, + /* .ssh_serialize_private = */ ssh_ecdsa_sk_serialize_private, /* .generate = */ NULL, /* .copy_public = */ ssh_ecdsa_sk_copy_public, /* .sign = */ NULL, diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c index a7b1b7b21..27f91a251 100644 --- a/ssh-ecdsa.c +++ b/ssh-ecdsa.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ecdsa.c,v 1.23 2022/10/28 00:43:08 djm Exp $ */ +/* $OpenBSD: ssh-ecdsa.c,v 1.24 2022/10/28 00:44:17 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -108,6 +108,22 @@ ssh_ecdsa_serialize_public(const struct sshkey *key, struct sshbuf *b, } static int +ssh_ecdsa_serialize_private(const struct sshkey *key, struct sshbuf *b, + enum sshkey_serialize_rep opts) +{ + int r; + + if (!sshkey_is_cert(key)) { + if ((r = ssh_ecdsa_serialize_public(key, b, opts)) != 0) + return r; + } + if ((r = sshbuf_put_bignum2(b, + EC_KEY_get0_private_key(key->ecdsa))) != 0) + return r; + return 0; +} + +static int ssh_ecdsa_generate(struct sshkey *k, int bits) { EC_KEY *private; @@ -350,6 +366,7 @@ const struct sshkey_impl_funcs sshkey_ecdsa_funcs = { /* .equal = */ ssh_ecdsa_equal, /* .ssh_serialize_public = */ ssh_ecdsa_serialize_public, /* .ssh_deserialize_public = */ ssh_ecdsa_deserialize_public, + /* .ssh_serialize_private = */ ssh_ecdsa_serialize_private, /* .generate = */ ssh_ecdsa_generate, /* .copy_public = */ ssh_ecdsa_copy_public, /* .sign = */ ssh_ecdsa_sign, diff --git a/ssh-ed25519-sk.c b/ssh-ed25519-sk.c index 1eef5424c..3becf05d5 100644 --- a/ssh-ed25519-sk.c +++ b/ssh-ed25519-sk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ed25519-sk.c,v 1.13 2022/10/28 00:43:08 djm Exp $ */ +/* $OpenBSD: ssh-ed25519-sk.c,v 1.14 2022/10/28 00:44:17 djm Exp $ */ /* * Copyright (c) 2019 Markus Friedl. All rights reserved. * @@ -70,6 +70,20 @@ ssh_ed25519_sk_serialize_public(const struct sshkey *key, struct sshbuf *b, } static int +ssh_ed25519_sk_serialize_private(const struct sshkey *key, struct sshbuf *b, + enum sshkey_serialize_rep opts) +{ + int r; + + if ((r = sshkey_ed25519_funcs.serialize_public(key, b, opts)) != 0) + return r; + if ((r = sshkey_serialize_private_sk(key, b)) != 0) + return r; + + return 0; +} + +static int ssh_ed25519_sk_copy_public(const struct sshkey *from, struct sshkey *to) { int r; @@ -228,6 +242,7 @@ static const struct sshkey_impl_funcs sshkey_ed25519_sk_funcs = { /* .equal = */ ssh_ed25519_sk_equal, /* .ssh_serialize_public = */ ssh_ed25519_sk_serialize_public, /* .ssh_deserialize_public = */ ssh_ed25519_sk_deserialize_public, + /* .ssh_serialize_private = */ ssh_ed25519_sk_serialize_private, /* .generate = */ NULL, /* .copy_public = */ ssh_ed25519_sk_copy_public, /* .sign = */ NULL, diff --git a/ssh-ed25519.c b/ssh-ed25519.c index 8e6fabed0..2707361b1 100644 --- a/ssh-ed25519.c +++ b/ssh-ed25519.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-ed25519.c,v 1.17 2022/10/28 00:43:08 djm Exp $ */ +/* $OpenBSD: ssh-ed25519.c,v 1.18 2022/10/28 00:44:17 djm Exp $ */ /* * Copyright (c) 2013 Markus Friedl <markus@openbsd.org> * @@ -66,6 +66,19 @@ ssh_ed25519_serialize_public(const struct sshkey *key, struct sshbuf *b, } static int +ssh_ed25519_serialize_private(const struct sshkey *key, struct sshbuf *b, + enum sshkey_serialize_rep opts) +{ + int r; + + if ((r = sshbuf_put_string(b, key->ed25519_pk, ED25519_PK_SZ)) != 0 || + (r = sshbuf_put_string(b, key->ed25519_sk, ED25519_SK_SZ)) != 0) + return r; + + return 0; +} + +static int ssh_ed25519_generate(struct sshkey *k, int bits) { if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL || @@ -242,6 +255,7 @@ const struct sshkey_impl_funcs sshkey_ed25519_funcs = { /* .equal = */ ssh_ed25519_equal, /* .ssh_serialize_public = */ ssh_ed25519_serialize_public, /* .ssh_deserialize_public = */ ssh_ed25519_deserialize_public, + /* .ssh_serialize_private = */ ssh_ed25519_serialize_private, /* .generate = */ ssh_ed25519_generate, /* .copy_public = */ ssh_ed25519_copy_public, /* .sign = */ ssh_ed25519_sign, @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-rsa.c,v 1.75 2022/10/28 00:43:08 djm Exp $ */ +/* $OpenBSD: ssh-rsa.c,v 1.76 2022/10/28 00:44:17 djm Exp $ */ /* * Copyright (c) 2000, 2003 Markus Friedl <markus@openbsd.org> * @@ -124,6 +124,32 @@ ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b, } static int +ssh_rsa_serialize_private(const struct sshkey *key, struct sshbuf *b, + enum sshkey_serialize_rep opts) +{ + int r; + const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q; + + RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d); + RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); + RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp); + + if (!sshkey_is_cert(key)) { + /* Note: can't reuse ssh_rsa_serialize_public: e, n vs. n, e */ + if ((r = sshbuf_put_bignum2(b, rsa_n)) != 0 || + (r = sshbuf_put_bignum2(b, rsa_e)) != 0) + return r; + } + if ((r = sshbuf_put_bignum2(b, rsa_d)) != 0 || + (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 || + (r = sshbuf_put_bignum2(b, rsa_p)) != 0 || + (r = sshbuf_put_bignum2(b, rsa_q)) != 0) + return r; + + return 0; +} + +static int ssh_rsa_generate(struct sshkey *k, int bits) { RSA *private = NULL; @@ -625,6 +651,7 @@ static const struct sshkey_impl_funcs sshkey_rsa_funcs = { /* .equal = */ ssh_rsa_equal, /* .ssh_serialize_public = */ ssh_rsa_serialize_public, /* .ssh_deserialize_public = */ ssh_rsa_deserialize_public, + /* .ssh_serialize_private = */ ssh_rsa_serialize_private, /* .generate = */ ssh_rsa_generate, /* .copy_public = */ ssh_rsa_copy_public, /* .sign = */ ssh_rsa_sign, diff --git a/ssh-xmss.c b/ssh-xmss.c index 2193aaab5..2b57b2d79 100644 --- a/ssh-xmss.c +++ b/ssh-xmss.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-xmss.c,v 1.12 2022/10/28 00:43:08 djm Exp $*/ +/* $OpenBSD: ssh-xmss.c,v 1.13 2022/10/28 00:44:17 djm Exp $*/ /* * Copyright (c) 2017 Stefan-Lukas Gazdag. * Copyright (c) 2017 Markus Friedl. @@ -82,6 +82,26 @@ ssh_xmss_serialize_public(const struct sshkey *key, struct sshbuf *b, } static int +ssh_xmss_serialize_private(const struct sshkey *key, struct sshbuf *b, + enum sshkey_serialize_rep opts) +{ + int r; + + if (key->xmss_name == NULL) + return SSH_ERR_INVALID_ARGUMENT; + /* Note: can't reuse ssh_xmss_serialize_public because of sk order */ + if ((r = sshbuf_put_cstring(b, key->xmss_name)) != 0 || + (r = sshbuf_put_string(b, key->xmss_pk, + sshkey_xmss_pklen(key))) != 0 || + (r = sshbuf_put_string(b, key->xmss_sk, + sshkey_xmss_sklen(key))) != 0 || + (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0) + return r; + + return 0; +} + +static int ssh_xmss_copy_public(const struct sshkey *from, struct sshkey *to) { int r = SSH_ERR_INTERNAL_ERROR; @@ -296,6 +316,7 @@ static const struct sshkey_impl_funcs sshkey_xmss_funcs = { /* .equal = */ ssh_xmss_equal, /* .ssh_serialize_public = */ ssh_xmss_serialize_public, /* .ssh_deserialize_public = */ ssh_xmss_deserialize_public, + /* .ssh_serialize_private = */ ssh_xmss_serialize_private, /* .generate = */ sshkey_xmss_generate_private_key, /* .copy_public = */ ssh_xmss_copy_public, /* .sign = */ ssh_xmss_sign, @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.591 2022/09/17 10:34:29 djm Exp $ */ +/* $OpenBSD: sshd.c,v 1.592 2022/10/28 00:44:17 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1514,7 +1514,7 @@ accumulate_host_timing_secret(struct sshbuf *server_cfg, if ((buf = sshbuf_new()) == NULL) fatal_f("could not allocate buffer"); if ((r = sshkey_private_serialize(key, buf)) != 0) - fatal_fr(r, "decode key"); + fatal_fr(r, "encode %s key", sshkey_ssh_name(key)); if (ssh_digest_update(ctx, sshbuf_ptr(buf), sshbuf_len(buf)) != 0) fatal_f("ssh_digest_update"); sshbuf_reset(buf); @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.c,v 1.131 2022/10/28 00:43:30 djm Exp $ */ +/* $OpenBSD: sshkey.c,v 1.132 2022/10/28 00:44:17 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved. @@ -2397,6 +2397,21 @@ sshkey_format_cert_validity(const struct sshkey_cert *cert, char *s, size_t l) return strlcpy(s, ret, l); } +/* Common serialization for FIDO private keys */ +int +sshkey_serialize_private_sk(const struct sshkey *key, struct sshbuf *b) +{ + int r; + + if ((r = sshbuf_put_cstring(b, key->sk_application)) != 0 || + (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || + (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || + (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) + return r; + + return 0; +} + int sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf, enum sshkey_serialize_rep opts) @@ -2404,185 +2419,28 @@ sshkey_private_serialize_opt(struct sshkey *key, struct sshbuf *buf, int r = SSH_ERR_INTERNAL_ERROR; int was_shielded = sshkey_is_shielded(key); struct sshbuf *b = NULL; -#ifdef WITH_OPENSSL - const BIGNUM *rsa_n, *rsa_e, *rsa_d, *rsa_iqmp, *rsa_p, *rsa_q; - const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key, *dsa_priv_key; -#endif /* WITH_OPENSSL */ + const struct sshkey_impl *impl; + if ((impl = sshkey_impl_from_key(key)) == NULL) + return SSH_ERR_INTERNAL_ERROR; if ((r = sshkey_unshield_private(key)) != 0) return r; if ((b = sshbuf_new()) == NULL) return SSH_ERR_ALLOC_FAIL; if ((r = sshbuf_put_cstring(b, sshkey_ssh_name(key))) != 0) goto out; - switch (key->type) { -#ifdef WITH_OPENSSL - case KEY_RSA: - RSA_get0_key(key->rsa, &rsa_n, &rsa_e, &rsa_d); - RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); - RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp); - if ((r = sshbuf_put_bignum2(b, rsa_n)) != 0 || - (r = sshbuf_put_bignum2(b, rsa_e)) != 0 || - (r = sshbuf_put_bignum2(b, rsa_d)) != 0 || - (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 || - (r = sshbuf_put_bignum2(b, rsa_p)) != 0 || - (r = sshbuf_put_bignum2(b, rsa_q)) != 0) - goto out; - break; - case KEY_RSA_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - RSA_get0_key(key->rsa, NULL, NULL, &rsa_d); - RSA_get0_factors(key->rsa, &rsa_p, &rsa_q); - RSA_get0_crt_params(key->rsa, NULL, NULL, &rsa_iqmp); - if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || - (r = sshbuf_put_bignum2(b, rsa_d)) != 0 || - (r = sshbuf_put_bignum2(b, rsa_iqmp)) != 0 || - (r = sshbuf_put_bignum2(b, rsa_p)) != 0 || - (r = sshbuf_put_bignum2(b, rsa_q)) != 0) - goto out; - break; - case KEY_DSA: - DSA_get0_pqg(key->dsa, &dsa_p, &dsa_q, &dsa_g); - DSA_get0_key(key->dsa, &dsa_pub_key, &dsa_priv_key); - if ((r = sshbuf_put_bignum2(b, dsa_p)) != 0 || - (r = sshbuf_put_bignum2(b, dsa_q)) != 0 || - (r = sshbuf_put_bignum2(b, dsa_g)) != 0 || - (r = sshbuf_put_bignum2(b, dsa_pub_key)) != 0 || - (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0) - goto out; - break; - case KEY_DSA_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - DSA_get0_key(key->dsa, NULL, &dsa_priv_key); - if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || - (r = sshbuf_put_bignum2(b, dsa_priv_key)) != 0) - goto out; - break; -# ifdef OPENSSL_HAS_ECC - case KEY_ECDSA: - if ((r = sshbuf_put_cstring(b, - sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || - (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 || - (r = sshbuf_put_bignum2(b, - EC_KEY_get0_private_key(key->ecdsa))) != 0) - goto out; - break; - case KEY_ECDSA_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || - (r = sshbuf_put_bignum2(b, - EC_KEY_get0_private_key(key->ecdsa))) != 0) - goto out; - break; - case KEY_ECDSA_SK: - if ((r = sshbuf_put_cstring(b, - sshkey_curve_nid_to_name(key->ecdsa_nid))) != 0 || - (r = sshbuf_put_eckey(b, key->ecdsa)) != 0 || - (r = sshbuf_put_cstring(b, key->sk_application)) != 0 || - (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || - (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || - (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) - goto out; - break; - case KEY_ECDSA_SK_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || - (r = sshbuf_put_cstring(b, key->sk_application)) != 0 || - (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || - (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || - (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) - goto out; - break; -# endif /* OPENSSL_HAS_ECC */ -#endif /* WITH_OPENSSL */ - case KEY_ED25519: - if ((r = sshbuf_put_string(b, key->ed25519_pk, - ED25519_PK_SZ)) != 0 || - (r = sshbuf_put_string(b, key->ed25519_sk, - ED25519_SK_SZ)) != 0) - goto out; - break; - case KEY_ED25519_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || - (r = sshbuf_put_string(b, key->ed25519_pk, - ED25519_PK_SZ)) != 0 || - (r = sshbuf_put_string(b, key->ed25519_sk, - ED25519_SK_SZ)) != 0) - goto out; - break; - case KEY_ED25519_SK: - if ((r = sshbuf_put_string(b, key->ed25519_pk, - ED25519_PK_SZ)) != 0 || - (r = sshbuf_put_cstring(b, key->sk_application)) != 0 || - (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || - (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || - (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) - goto out; - break; - case KEY_ED25519_SK_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || - (r = sshbuf_put_string(b, key->ed25519_pk, - ED25519_PK_SZ)) != 0 || - (r = sshbuf_put_cstring(b, key->sk_application)) != 0 || - (r = sshbuf_put_u8(b, key->sk_flags)) != 0 || - (r = sshbuf_put_stringb(b, key->sk_key_handle)) != 0 || - (r = sshbuf_put_stringb(b, key->sk_reserved)) != 0) - goto out; - break; -#ifdef WITH_XMSS - case KEY_XMSS: - if (key->xmss_name == NULL) { - r = SSH_ERR_INVALID_ARGUMENT; - goto out; - } - if ((r = sshbuf_put_cstring(b, key->xmss_name)) != 0 || - (r = sshbuf_put_string(b, key->xmss_pk, - sshkey_xmss_pklen(key))) != 0 || - (r = sshbuf_put_string(b, key->xmss_sk, - sshkey_xmss_sklen(key))) != 0 || - (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0) - goto out; - break; - case KEY_XMSS_CERT: - if (key->cert == NULL || sshbuf_len(key->cert->certblob) == 0 || - key->xmss_name == NULL) { + if (sshkey_is_cert(key)) { + if (key->cert == NULL || + sshbuf_len(key->cert->certblob) == 0) { r = SSH_ERR_INVALID_ARGUMENT; goto out; } - if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0 || - (r = sshbuf_put_cstring(b, key->xmss_name)) != 0 || - (r = sshbuf_put_string(b, key->xmss_pk, - sshkey_xmss_pklen(key))) != 0 || - (r = sshbuf_put_string(b, key->xmss_sk, - sshkey_xmss_sklen(key))) != 0 || - (r = sshkey_xmss_serialize_state_opt(key, b, opts)) != 0) + if ((r = sshbuf_put_stringb(b, key->cert->certblob)) != 0) goto out; - break; -#endif /* WITH_XMSS */ - default: - r = SSH_ERR_INVALID_ARGUMENT; - goto out; } + if ((r = impl->funcs->serialize_private(key, b, opts)) != 0) + goto out; + /* * success (but we still need to append the output to buf after * possibly re-shielding the private key) @@ -1,4 +1,4 @@ -/* $OpenBSD: sshkey.h,v 1.59 2022/10/28 00:43:08 djm Exp $ */ +/* $OpenBSD: sshkey.h,v 1.60 2022/10/28 00:44:17 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. @@ -173,6 +173,8 @@ struct sshkey_impl_funcs { enum sshkey_serialize_rep); int (*deserialize_public)(const char *, struct sshbuf *, struct sshkey *); + int (*serialize_private)(const struct sshkey *, struct sshbuf *, + enum sshkey_serialize_rep); int (*generate)(struct sshkey *, int); /* optional */ int (*copy_public)(const struct sshkey *, struct sshkey *); int (*sign)(struct sshkey *, u_char **, size_t *, @@ -324,6 +326,8 @@ void sshkey_sk_cleanup(struct sshkey *k); int sshkey_serialize_sk(const struct sshkey *key, struct sshbuf *b); int sshkey_copy_public_sk(const struct sshkey *from, struct sshkey *to); int sshkey_deserialize_sk(struct sshbuf *b, struct sshkey *key); +int sshkey_serialize_private_sk(const struct sshkey *key, + struct sshbuf *buf); #ifdef WITH_OPENSSL int check_rsa_length(const RSA *rsa); /* XXX remove */ #endif |