version 1.126, 2022/10/28 00:38:58 |
version 1.127, 2022/10/28 00:39:29 |
|
|
} |
} |
|
|
#ifdef WITH_OPENSSL |
#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; |
|
} |
|
|
|
int |
int |
sshkey_ecdsa_key_to_nid(EC_KEY *k) |
sshkey_ecdsa_key_to_nid(EC_KEY *k) |
{ |
{ |
|
|
return nids[i]; |
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 /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
|
|
int |
int |
|
|
{ |
{ |
struct sshkey *k; |
struct sshkey *k; |
int ret = SSH_ERR_INTERNAL_ERROR; |
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; |
return SSH_ERR_INVALID_ARGUMENT; |
*keyp = NULL; |
*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) |
if ((k = sshkey_new(KEY_UNSPEC)) == NULL) |
return SSH_ERR_ALLOC_FAIL; |
return SSH_ERR_ALLOC_FAIL; |
switch (type) { |
k->type = type; |
case KEY_ED25519: |
if ((ret = impl->funcs->generate(k, bits)) != 0) { |
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; |
|
case KEY_ECDSA: |
|
ret = ecdsa_generate_private_key(bits, &k->ecdsa_nid, |
|
&k->ecdsa); |
|
break; |
|
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 |
|
sshkey_free(k); |
sshkey_free(k); |
return ret; |
return ret; |
|
} |
|
/* success */ |
|
*keyp = k; |
|
return 0; |
} |
} |
|
|
int |
int |