summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ssh-dss.c21
-rw-r--r--ssh-ecdsa-sk.c20
-rw-r--r--ssh-ecdsa.c19
-rw-r--r--ssh-ed25519-sk.c17
-rw-r--r--ssh-ed25519.c16
-rw-r--r--ssh-rsa.c29
-rw-r--r--ssh-xmss.c23
-rw-r--r--sshd.c4
-rw-r--r--sshkey.c194
-rw-r--r--sshkey.h6
10 files changed, 171 insertions, 178 deletions
diff --git a/ssh-dss.c b/ssh-dss.c
index 58c66c7da..d79021579 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -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,
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 07620a8d6..b6bfe6848 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -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,
diff --git a/sshd.c b/sshd.c
index 395ef493d..b4bb7d654 100644
--- a/sshd.c
+++ b/sshd.c
@@ -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);
diff --git a/sshkey.c b/sshkey.c
index 339b379f6..f6d3d313e 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -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)
diff --git a/sshkey.h b/sshkey.h
index d740c20bd..9ee9d6c5c 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -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