summaryrefslogtreecommitdiffstats
path: root/sshkey.c
diff options
context:
space:
mode:
authordjm@openbsd.org <djm@openbsd.org>2022-10-28 02:39:29 +0200
committerDamien Miller <djm@mindrot.org>2022-10-28 03:46:58 +0200
commit262647c2e920492ca57f1b9320d74f4a0f6e482b (patch)
tree1ce89f627b8230d5ce9611ebe698e5b3f4338fa1 /sshkey.c
parentupstream: refactor and simplify sshkey_read() (diff)
downloadopenssh-262647c2e920492ca57f1b9320d74f4a0f6e482b.tar.xz
openssh-262647c2e920492ca57f1b9320d74f4a0f6e482b.zip
upstream: factor out key generation
feedback/ok markus@ OpenBSD-Commit-ID: 5b4211bff4de8d9adb84bc72857a8c42c44e7ceb
Diffstat (limited to 'sshkey.c')
-rw-r--r--sshkey.c140
1 files changed, 14 insertions, 126 deletions
diff --git a/sshkey.c b/sshkey.c
index 31419299d..61f1ee4bd 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