[openssh-commits] [openssh] 10/11: upstream: refactor sshkey_private_serialize_opt()

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Oct 28 12:47:35 AEDT 2022


This is an automated email from the git hooks/post-receive script.

djm pushed a commit to branch master
in repository openssh.

commit 2519a7077a9332f70935e5242ba91ee670ed6b87
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Fri Oct 28 00:44:17 2022 +0000

    upstream: refactor sshkey_private_serialize_opt()
    
    feedback/ok markus@
    
    OpenBSD-Commit-ID: 61e0fe989897901294efe7c3b6d670cefaf44cbd
---
 ssh-dss.c        |  21 +++++-
 ssh-ecdsa-sk.c   |  20 +++++-
 ssh-ecdsa.c      |  19 +++++-
 ssh-ed25519-sk.c |  17 ++++-
 ssh-ed25519.c    |  16 ++++-
 ssh-rsa.c        |  29 ++++++++-
 ssh-xmss.c       |  23 ++++++-
 sshd.c           |   4 +-
 sshkey.c         | 194 ++++++++-----------------------------------------------
 sshkey.h         |   6 +-
 10 files changed, 171 insertions(+), 178 deletions(-)

diff --git a/ssh-dss.c b/ssh-dss.c
index 58c66c7d..d7902157 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.
  *
@@ -125,6 +125,24 @@ ssh_dss_serialize_public(const struct sshkey *key, struct sshbuf *b,
 	return 0;
 }
 
+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)
 {
@@ -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 6e08d869..51e444a5 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.
@@ -95,6 +95,23 @@ ssh_ecdsa_sk_serialize_public(const struct sshkey *key, struct sshbuf *b,
 	return 0;
 }
 
+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)
 {
@@ -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 a7b1b7b2..27f91a25 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.
@@ -107,6 +107,22 @@ ssh_ecdsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
 	return 0;
 }
 
+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)
 {
@@ -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 1eef5424..3becf05d 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.
  *
@@ -69,6 +69,20 @@ ssh_ed25519_sk_serialize_public(const struct sshkey *key, struct sshbuf *b,
 	return 0;
 }
 
+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)
 {
@@ -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 8e6fabed..2707361b 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 at openbsd.org>
  *
@@ -65,6 +65,19 @@ ssh_ed25519_serialize_public(const struct sshkey *key, struct sshbuf *b,
 	return 0;
 }
 
+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)
 {
@@ -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 07620a8d..b6bfe684 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 at openbsd.org>
  *
@@ -123,6 +123,32 @@ ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
 	return 0;
 }
 
+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)
 {
@@ -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 2193aaab..2b57b2d7 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.
@@ -81,6 +81,26 @@ ssh_xmss_serialize_public(const struct sshkey *key, struct sshbuf *b,
 	return 0;
 }
 
+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)
 {
@@ -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 395ef493..b4bb7d65 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 at cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo at 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 339b379f..f6d3d313 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 d740c20b..9ee9d6c5 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

-- 
To stop receiving notification emails like this one, please contact
djm at mindrot.org.


More information about the openssh-commits mailing list