[openssh-commits] [openssh] 05/11: upstream: factor out key generation

git+noreply at mindrot.org git+noreply at mindrot.org
Fri Oct 28 12:47:30 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 262647c2e920492ca57f1b9320d74f4a0f6e482b
Author: djm at openbsd.org <djm at openbsd.org>
Date:   Fri Oct 28 00:39:29 2022 +0000

    upstream: factor out key generation
    
    feedback/ok markus@
    
    OpenBSD-Commit-ID: 5b4211bff4de8d9adb84bc72857a8c42c44e7ceb
---
 ssh-dss.c        |  21 ++++++++-
 ssh-ecdsa-sk.c   |   3 +-
 ssh-ecdsa.c      |  21 ++++++++-
 ssh-ed25519-sk.c |   3 +-
 ssh-ed25519.c    |  13 +++++-
 ssh-rsa.c        |  31 +++++++++++-
 ssh-xmss.c       |   3 +-
 sshkey-xmss.c    |   4 +-
 sshkey-xmss.h    |   4 +-
 sshkey.c         | 140 ++++++-------------------------------------------------
 sshkey.h         |   3 +-
 11 files changed, 108 insertions(+), 138 deletions(-)

diff --git a/ssh-dss.c b/ssh-dss.c
index e955fdd5..bc8fb4e1 100644
--- a/ssh-dss.c
+++ b/ssh-dss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-dss.c,v 1.42 2022/10/28 00:37:24 djm Exp $ */
+/* $OpenBSD: ssh-dss.c,v 1.43 2022/10/28 00:39:29 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,
 	return 0;
 }
 
+static int
+ssh_dss_generate(struct sshkey *k, int bits)
+{
+	DSA *private;
+
+	if (bits != 1024)
+		return SSH_ERR_KEY_LENGTH;
+	if ((private = DSA_new()) == NULL)
+		return SSH_ERR_ALLOC_FAIL;
+	if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
+	    NULL, NULL) || !DSA_generate_key(private)) {
+		DSA_free(private);
+		return SSH_ERR_LIBCRYPTO_ERROR;
+	}
+	k->dsa = private;
+	return 0;
+}
+
 int
 ssh_dss_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
     const u_char *data, size_t datalen, u_int compat)
@@ -289,6 +307,7 @@ static const struct sshkey_impl_funcs sshkey_dss_funcs = {
 	/* .cleanup = */	ssh_dss_cleanup,
 	/* .equal = */		ssh_dss_equal,
 	/* .ssh_serialize_public = */ ssh_dss_serialize_public,
+	/* .generate = */	ssh_dss_generate,
 };
 
 const struct sshkey_impl sshkey_dss_impl = {
diff --git a/ssh-ecdsa-sk.c b/ssh-ecdsa-sk.c
index 228e1b09..cbc9b0e1 100644
--- a/ssh-ecdsa-sk.c
+++ b/ssh-ecdsa-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ecdsa-sk.c,v 1.11 2022/10/28 00:37:24 djm Exp $ */
+/* $OpenBSD: ssh-ecdsa-sk.c,v 1.12 2022/10/28 00:39:29 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -362,6 +362,7 @@ static const struct sshkey_impl_funcs sshkey_ecdsa_sk_funcs = {
 	/* .cleanup = */	ssh_ecdsa_sk_cleanup,
 	/* .equal = */		ssh_ecdsa_sk_equal,
 	/* .ssh_serialize_public = */ ssh_ecdsa_sk_serialize_public,
+	/* .generate = */	NULL,
 };
 
 const struct sshkey_impl sshkey_ecdsa_sk_impl = {
diff --git a/ssh-ecdsa.c b/ssh-ecdsa.c
index 24f66bdc..16a8ea87 100644
--- a/ssh-ecdsa.c
+++ b/ssh-ecdsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ecdsa.c,v 1.19 2022/10/28 00:37:24 djm Exp $ */
+/* $OpenBSD: ssh-ecdsa.c,v 1.20 2022/10/28 00:39:29 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2010 Damien Miller.  All rights reserved.
@@ -108,6 +108,24 @@ ssh_ecdsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
 	return 0;
 }
 
+static int
+ssh_ecdsa_generate(struct sshkey *k, int bits)
+{
+	EC_KEY *private;
+
+	if ((k->ecdsa_nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
+		return SSH_ERR_KEY_LENGTH;
+	if ((private = EC_KEY_new_by_curve_name(k->ecdsa_nid)) == NULL)
+		return SSH_ERR_ALLOC_FAIL;
+	if (EC_KEY_generate_key(private) != 1) {
+		EC_KEY_free(private);
+		return SSH_ERR_LIBCRYPTO_ERROR;
+	}
+	EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
+	k->ecdsa = private;
+	return 0;
+}
+
 /* ARGSUSED */
 int
 ssh_ecdsa_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
@@ -267,6 +285,7 @@ const struct sshkey_impl_funcs sshkey_ecdsa_funcs = {
 	/* .cleanup = */	ssh_ecdsa_cleanup,
 	/* .equal = */		ssh_ecdsa_equal,
 	/* .ssh_serialize_public = */ ssh_ecdsa_serialize_public,
+	/* .generate = */	ssh_ecdsa_generate,
 };
 
 const struct sshkey_impl sshkey_ecdsa_nistp256_impl = {
diff --git a/ssh-ed25519-sk.c b/ssh-ed25519-sk.c
index b95227c0..6236ee12 100644
--- a/ssh-ed25519-sk.c
+++ b/ssh-ed25519-sk.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ed25519-sk.c,v 1.9 2022/10/28 00:37:24 djm Exp $ */
+/* $OpenBSD: ssh-ed25519-sk.c,v 1.10 2022/10/28 00:39:29 djm Exp $ */
 /*
  * Copyright (c) 2019 Markus Friedl.  All rights reserved.
  *
@@ -203,6 +203,7 @@ static const struct sshkey_impl_funcs sshkey_ed25519_sk_funcs = {
 	/* .cleanup = */	ssh_ed25519_sk_cleanup,
 	/* .equal = */		ssh_ed25519_sk_equal,
 	/* .ssh_serialize_public = */ ssh_ed25519_sk_serialize_public,
+	/* .generate = */	NULL,
 };
 
 const struct sshkey_impl sshkey_ed25519_sk_impl = {
diff --git a/ssh-ed25519.c b/ssh-ed25519.c
index 72c85000..f2a38c28 100644
--- a/ssh-ed25519.c
+++ b/ssh-ed25519.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-ed25519.c,v 1.13 2022/10/28 00:37:24 djm Exp $ */
+/* $OpenBSD: ssh-ed25519.c,v 1.14 2022/10/28 00:39:29 djm Exp $ */
 /*
  * Copyright (c) 2013 Markus Friedl <markus at openbsd.org>
  *
@@ -66,6 +66,16 @@ ssh_ed25519_serialize_public(const struct sshkey *key, struct sshbuf *b,
 	return 0;
 }
 
+static int
+ssh_ed25519_generate(struct sshkey *k, int bits)
+{
+	if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL ||
+	    (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL)
+		return SSH_ERR_ALLOC_FAIL;
+	crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
+	return 0;
+}
+
 int
 ssh_ed25519_sign(const struct sshkey *key, u_char **sigp, size_t *lenp,
     const u_char *data, size_t datalen, u_int compat)
@@ -200,6 +210,7 @@ const struct sshkey_impl_funcs sshkey_ed25519_funcs = {
 	/* .cleanup = */	ssh_ed25519_cleanup,
 	/* .equal = */		ssh_ed25519_equal,
 	/* .ssh_serialize_public = */ ssh_ed25519_serialize_public,
+	/* .generate = */	ssh_ed25519_generate,
 };
 
 const struct sshkey_impl sshkey_ed25519_impl = {
diff --git a/ssh-rsa.c b/ssh-rsa.c
index 4ece09f7..87956a46 100644
--- a/ssh-rsa.c
+++ b/ssh-rsa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-rsa.c,v 1.71 2022/10/28 00:37:24 djm Exp $ */
+/* $OpenBSD: ssh-rsa.c,v 1.72 2022/10/28 00:39:29 djm Exp $ */
 /*
  * Copyright (c) 2000, 2003 Markus Friedl <markus at openbsd.org>
  *
@@ -104,6 +104,34 @@ ssh_rsa_serialize_public(const struct sshkey *key, struct sshbuf *b,
 	return 0;
 }
 
+static int
+ssh_rsa_generate(struct sshkey *k, int bits)
+{
+	RSA *private = NULL;
+	BIGNUM *f4 = NULL;
+	int ret = SSH_ERR_INTERNAL_ERROR;
+
+	if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
+	    bits > SSHBUF_MAX_BIGNUM * 8)
+		return SSH_ERR_KEY_LENGTH;
+	if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
+		ret = SSH_ERR_ALLOC_FAIL;
+		goto out;
+	}
+	if (!BN_set_word(f4, RSA_F4) ||
+	    !RSA_generate_key_ex(private, bits, f4, NULL)) {
+		ret = SSH_ERR_LIBCRYPTO_ERROR;
+		goto out;
+	}
+	k->rsa = private;
+	private = NULL;
+	ret = 0;
+ out:
+	RSA_free(private);
+	BN_free(f4);
+	return ret;
+}
+
 static const char *
 rsa_hash_alg_ident(int hash_alg)
 {
@@ -518,6 +546,7 @@ static const struct sshkey_impl_funcs sshkey_rsa_funcs = {
 	/* .cleanup = */	ssh_rsa_cleanup,
 	/* .equal = */		ssh_rsa_equal,
 	/* .ssh_serialize_public = */ ssh_rsa_serialize_public,
+	/* .generate = */	ssh_rsa_generate,
 };
 
 const struct sshkey_impl sshkey_rsa_impl = {
diff --git a/ssh-xmss.c b/ssh-xmss.c
index 7031baf9..da8b4cc3 100644
--- a/ssh-xmss.c
+++ b/ssh-xmss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssh-xmss.c,v 1.8 2022/10/28 00:37:24 djm Exp $*/
+/* $OpenBSD: ssh-xmss.c,v 1.9 2022/10/28 00:39:29 djm Exp $*/
 /*
  * Copyright (c) 2017 Stefan-Lukas Gazdag.
  * Copyright (c) 2017 Markus Friedl.
@@ -236,6 +236,7 @@ static const struct sshkey_impl_funcs sshkey_xmss_funcs = {
 	/* .cleanup = */	ssh_xmss_cleanup,
 	/* .equal = */		ssh_xmss_equal,
 	/* .ssh_serialize_public = */ ssh_xmss_serialize_public,
+	/* .generate = */	sshkey_xmss_generate_private_key,
 };
 
 const struct sshkey_impl sshkey_xmss_impl = {
diff --git a/sshkey-xmss.c b/sshkey-xmss.c
index f5235ef2..818aba90 100644
--- a/sshkey-xmss.c
+++ b/sshkey-xmss.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey-xmss.c,v 1.11 2021/04/03 06:18:41 djm Exp $ */
+/* $OpenBSD: sshkey-xmss.c,v 1.12 2022/10/28 00:39:29 djm Exp $ */
 /*
  * Copyright (c) 2017 Markus Friedl.  All rights reserved.
  *
@@ -365,7 +365,7 @@ sshkey_xmss_deserialize_pk_info(struct sshkey *k, struct sshbuf *b)
 }
 
 int
-sshkey_xmss_generate_private_key(struct sshkey *k, u_int bits)
+sshkey_xmss_generate_private_key(struct sshkey *k, int bits)
 {
 	int r;
 	const char *name;
diff --git a/sshkey-xmss.h b/sshkey-xmss.h
index 32a12be6..ab8b9c90 100644
--- a/sshkey-xmss.h
+++ b/sshkey-xmss.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey-xmss.h,v 1.3 2021/04/03 06:18:41 djm Exp $ */
+/* $OpenBSD: sshkey-xmss.h,v 1.4 2022/10/28 00:39:29 djm Exp $ */
 /*
  * Copyright (c) 2017 Markus Friedl.  All rights reserved.
  *
@@ -34,7 +34,7 @@ size_t	 sshkey_xmss_pklen(const struct sshkey *);
 size_t	 sshkey_xmss_sklen(const struct sshkey *);
 int	 sshkey_xmss_init(struct sshkey *, const char *);
 void	 sshkey_xmss_free_state(struct sshkey *);
-int	 sshkey_xmss_generate_private_key(struct sshkey *, u_int);
+int	 sshkey_xmss_generate_private_key(struct sshkey *, int);
 int	 sshkey_xmss_serialize_state(const struct sshkey *, struct sshbuf *);
 int	 sshkey_xmss_serialize_state_opt(const struct sshkey *, struct sshbuf *,
 	    enum sshkey_serialize_rep);
diff --git a/sshkey.c b/sshkey.c
index 31419299..61f1ee4b 100644
--- a/sshkey.c
+++ b/sshkey.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.c,v 1.126 2022/10/28 00:38:58 djm Exp $ */
+/* $OpenBSD: sshkey.c,v 1.127 2022/10/28 00:39:29 djm Exp $ */
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
  * Copyright (c) 2008 Alexander von Gernler.  All rights reserved.
@@ -1295,65 +1295,6 @@ sshkey_cert_type(const struct sshkey *k)
 }
 
 #ifdef WITH_OPENSSL
-static int
-rsa_generate_private_key(u_int bits, RSA **rsap)
-{
-	RSA *private = NULL;
-	BIGNUM *f4 = NULL;
-	int ret = SSH_ERR_INTERNAL_ERROR;
-
-	if (rsap == NULL)
-		return SSH_ERR_INVALID_ARGUMENT;
-	if (bits < SSH_RSA_MINIMUM_MODULUS_SIZE ||
-	    bits > SSHBUF_MAX_BIGNUM * 8)
-		return SSH_ERR_KEY_LENGTH;
-	*rsap = NULL;
-	if ((private = RSA_new()) == NULL || (f4 = BN_new()) == NULL) {
-		ret = SSH_ERR_ALLOC_FAIL;
-		goto out;
-	}
-	if (!BN_set_word(f4, RSA_F4) ||
-	    !RSA_generate_key_ex(private, bits, f4, NULL)) {
-		ret = SSH_ERR_LIBCRYPTO_ERROR;
-		goto out;
-	}
-	*rsap = private;
-	private = NULL;
-	ret = 0;
- out:
-	RSA_free(private);
-	BN_free(f4);
-	return ret;
-}
-
-static int
-dsa_generate_private_key(u_int bits, DSA **dsap)
-{
-	DSA *private;
-	int ret = SSH_ERR_INTERNAL_ERROR;
-
-	if (dsap == NULL)
-		return SSH_ERR_INVALID_ARGUMENT;
-	if (bits != 1024)
-		return SSH_ERR_KEY_LENGTH;
-	if ((private = DSA_new()) == NULL) {
-		ret = SSH_ERR_ALLOC_FAIL;
-		goto out;
-	}
-	*dsap = NULL;
-	if (!DSA_generate_parameters_ex(private, bits, NULL, 0, NULL,
-	    NULL, NULL) || !DSA_generate_key(private)) {
-		ret = SSH_ERR_LIBCRYPTO_ERROR;
-		goto out;
-	}
-	*dsap = private;
-	private = NULL;
-	ret = 0;
- out:
-	DSA_free(private);
-	return ret;
-}
-
 # ifdef OPENSSL_HAS_ECC
 int
 sshkey_ecdsa_key_to_nid(EC_KEY *k)
@@ -1398,34 +1339,6 @@ sshkey_ecdsa_key_to_nid(EC_KEY *k)
 	}
 	return nids[i];
 }
-
-static int
-ecdsa_generate_private_key(u_int bits, int *nid, EC_KEY **ecdsap)
-{
-	EC_KEY *private;
-	int ret = SSH_ERR_INTERNAL_ERROR;
-
-	if (nid == NULL || ecdsap == NULL)
-		return SSH_ERR_INVALID_ARGUMENT;
-	if ((*nid = sshkey_ecdsa_bits_to_nid(bits)) == -1)
-		return SSH_ERR_KEY_LENGTH;
-	*ecdsap = NULL;
-	if ((private = EC_KEY_new_by_curve_name(*nid)) == NULL) {
-		ret = SSH_ERR_ALLOC_FAIL;
-		goto out;
-	}
-	if (EC_KEY_generate_key(private) != 1) {
-		ret = SSH_ERR_LIBCRYPTO_ERROR;
-		goto out;
-	}
-	EC_KEY_set_asn1_flag(private, OPENSSL_EC_NAMED_CURVE);
-	*ecdsap = private;
-	private = NULL;
-	ret = 0;
- out:
-	EC_KEY_free(private);
-	return ret;
-}
 # endif /* OPENSSL_HAS_ECC */
 #endif /* WITH_OPENSSL */
 
@@ -1434,50 +1347,25 @@ sshkey_generate(int type, u_int bits, struct sshkey **keyp)
 {
 	struct sshkey *k;
 	int ret = SSH_ERR_INTERNAL_ERROR;
+	const struct sshkey_impl *impl;
 
-	if (keyp == NULL)
+	if (keyp == NULL || sshkey_type_is_cert(type))
 		return SSH_ERR_INVALID_ARGUMENT;
 	*keyp = NULL;
+	if ((impl = sshkey_impl_from_type(type)) == NULL)
+		return SSH_ERR_KEY_TYPE_UNKNOWN;
+	if (impl->funcs->generate == NULL)
+		return SSH_ERR_FEATURE_UNSUPPORTED;
 	if ((k = sshkey_new(KEY_UNSPEC)) == NULL)
 		return SSH_ERR_ALLOC_FAIL;
-	switch (type) {
-	case KEY_ED25519:
-		if ((k->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL ||
-		    (k->ed25519_sk = malloc(ED25519_SK_SZ)) == NULL) {
-			ret = SSH_ERR_ALLOC_FAIL;
-			break;
-		}
-		crypto_sign_ed25519_keypair(k->ed25519_pk, k->ed25519_sk);
-		ret = 0;
-		break;
-#ifdef WITH_XMSS
-	case KEY_XMSS:
-		ret = sshkey_xmss_generate_private_key(k, bits);
-		break;
-#endif /* WITH_XMSS */
-#ifdef WITH_OPENSSL
-	case KEY_DSA:
-		ret = dsa_generate_private_key(bits, &k->dsa);
-		break;
-# ifdef OPENSSL_HAS_ECC
-	case KEY_ECDSA:
-		ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid,
-		    &k->ecdsa);
-		break;
-# endif /* OPENSSL_HAS_ECC */
-	case KEY_RSA:
-		ret = rsa_generate_private_key(bits, &k->rsa);
-		break;
-#endif /* WITH_OPENSSL */
-	default:
-		ret = SSH_ERR_INVALID_ARGUMENT;
-	}
-	if (ret == 0) {
-		k->type = type;
-		*keyp = k;
-	} else
+	k->type = type;
+	if ((ret = impl->funcs->generate(k, bits)) != 0) {
 		sshkey_free(k);
-	return ret;
+		return ret;
+	}
+	/* success */
+	*keyp = k;
+	return 0;
 }
 
 int
diff --git a/sshkey.h b/sshkey.h
index 03d82aed..64708020 100644
--- a/sshkey.h
+++ b/sshkey.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshkey.h,v 1.55 2022/10/28 00:37:24 djm Exp $ */
+/* $OpenBSD: sshkey.h,v 1.56 2022/10/28 00:39:29 djm Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -171,6 +171,7 @@ struct sshkey_impl_funcs {
 	int (*equal)(const struct sshkey *, const struct sshkey *);
 	int (*serialize_public)(const struct sshkey *, struct sshbuf *,
 	    const char *, enum sshkey_serialize_rep);
+	int (*generate)(struct sshkey *, int);	/* optional */
 };
 
 struct sshkey_impl {

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


More information about the openssh-commits mailing list