version 1.127, 2022/10/28 00:39:29 |
version 1.128, 2022/10/28 00:41:17 |
|
|
} |
} |
|
|
int |
int |
|
sshkey_copy_public_sk(const struct sshkey *from, struct sshkey *to) |
|
{ |
|
/* Append security-key application string */ |
|
if ((to->sk_application = strdup(from->sk_application)) == NULL) |
|
return SSH_ERR_ALLOC_FAIL; |
|
return 0; |
|
} |
|
|
|
int |
sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) |
sshkey_from_private(const struct sshkey *k, struct sshkey **pkp) |
{ |
{ |
struct sshkey *n = NULL; |
struct sshkey *n = NULL; |
int r = SSH_ERR_INTERNAL_ERROR; |
int r = SSH_ERR_INTERNAL_ERROR; |
#ifdef WITH_OPENSSL |
const struct sshkey_impl *impl; |
const BIGNUM *rsa_n, *rsa_e; |
|
BIGNUM *rsa_n_dup = NULL, *rsa_e_dup = NULL; |
|
const BIGNUM *dsa_p, *dsa_q, *dsa_g, *dsa_pub_key; |
|
BIGNUM *dsa_p_dup = NULL, *dsa_q_dup = NULL, *dsa_g_dup = NULL; |
|
BIGNUM *dsa_pub_key_dup = NULL; |
|
#endif /* WITH_OPENSSL */ |
|
|
|
*pkp = NULL; |
*pkp = NULL; |
|
if ((impl = sshkey_impl_from_key(k)) == NULL) |
|
return SSH_ERR_KEY_TYPE_UNKNOWN; |
if ((n = sshkey_new(k->type)) == NULL) { |
if ((n = sshkey_new(k->type)) == NULL) { |
r = SSH_ERR_ALLOC_FAIL; |
r = SSH_ERR_ALLOC_FAIL; |
goto out; |
goto out; |
} |
} |
switch (k->type) { |
if ((r = impl->funcs->copy_public(k, n)) != 0) |
#ifdef WITH_OPENSSL |
|
case KEY_DSA: |
|
case KEY_DSA_CERT: |
|
DSA_get0_pqg(k->dsa, &dsa_p, &dsa_q, &dsa_g); |
|
DSA_get0_key(k->dsa, &dsa_pub_key, NULL); |
|
if ((dsa_p_dup = BN_dup(dsa_p)) == NULL || |
|
(dsa_q_dup = BN_dup(dsa_q)) == NULL || |
|
(dsa_g_dup = BN_dup(dsa_g)) == NULL || |
|
(dsa_pub_key_dup = BN_dup(dsa_pub_key)) == NULL) { |
|
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
if (!DSA_set0_pqg(n->dsa, dsa_p_dup, dsa_q_dup, dsa_g_dup)) { |
|
r = SSH_ERR_LIBCRYPTO_ERROR; |
|
goto out; |
|
} |
|
dsa_p_dup = dsa_q_dup = dsa_g_dup = NULL; /* transferred */ |
|
if (!DSA_set0_key(n->dsa, dsa_pub_key_dup, NULL)) { |
|
r = SSH_ERR_LIBCRYPTO_ERROR; |
|
goto out; |
|
} |
|
dsa_pub_key_dup = NULL; /* transferred */ |
|
|
|
break; |
|
case KEY_ECDSA: |
|
case KEY_ECDSA_CERT: |
|
case KEY_ECDSA_SK: |
|
case KEY_ECDSA_SK_CERT: |
|
n->ecdsa_nid = k->ecdsa_nid; |
|
n->ecdsa = EC_KEY_new_by_curve_name(k->ecdsa_nid); |
|
if (n->ecdsa == NULL) { |
|
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
if (EC_KEY_set_public_key(n->ecdsa, |
|
EC_KEY_get0_public_key(k->ecdsa)) != 1) { |
|
r = SSH_ERR_LIBCRYPTO_ERROR; |
|
goto out; |
|
} |
|
if (k->type != KEY_ECDSA_SK && k->type != KEY_ECDSA_SK_CERT) |
|
break; |
|
/* Append security-key application string */ |
|
if ((n->sk_application = strdup(k->sk_application)) == NULL) |
|
goto out; |
|
break; |
|
case KEY_RSA: |
|
case KEY_RSA_CERT: |
|
RSA_get0_key(k->rsa, &rsa_n, &rsa_e, NULL); |
|
if ((rsa_n_dup = BN_dup(rsa_n)) == NULL || |
|
(rsa_e_dup = BN_dup(rsa_e)) == NULL) { |
|
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
if (!RSA_set0_key(n->rsa, rsa_n_dup, rsa_e_dup, NULL)) { |
|
r = SSH_ERR_LIBCRYPTO_ERROR; |
|
goto out; |
|
} |
|
rsa_n_dup = rsa_e_dup = NULL; /* transferred */ |
|
break; |
|
#endif /* WITH_OPENSSL */ |
|
case KEY_ED25519: |
|
case KEY_ED25519_CERT: |
|
case KEY_ED25519_SK: |
|
case KEY_ED25519_SK_CERT: |
|
if (k->ed25519_pk != NULL) { |
|
if ((n->ed25519_pk = malloc(ED25519_PK_SZ)) == NULL) { |
|
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
memcpy(n->ed25519_pk, k->ed25519_pk, ED25519_PK_SZ); |
|
} |
|
if (k->type != KEY_ED25519_SK && |
|
k->type != KEY_ED25519_SK_CERT) |
|
break; |
|
/* Append security-key application string */ |
|
if ((n->sk_application = strdup(k->sk_application)) == NULL) |
|
goto out; |
|
break; |
|
#ifdef WITH_XMSS |
|
case KEY_XMSS: |
|
case KEY_XMSS_CERT: |
|
if ((r = sshkey_xmss_init(n, k->xmss_name)) != 0) |
|
goto out; |
|
if (k->xmss_pk != NULL) { |
|
u_int32_t left; |
|
size_t pklen = sshkey_xmss_pklen(k); |
|
if (pklen == 0 || sshkey_xmss_pklen(n) != pklen) { |
|
r = SSH_ERR_INTERNAL_ERROR; |
|
goto out; |
|
} |
|
if ((n->xmss_pk = malloc(pklen)) == NULL) { |
|
r = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
|
} |
|
memcpy(n->xmss_pk, k->xmss_pk, pklen); |
|
/* simulate number of signatures left on pubkey */ |
|
left = sshkey_xmss_signatures_left(k); |
|
if (left) |
|
sshkey_xmss_enable_maxsign(n, left); |
|
} |
|
break; |
|
#endif /* WITH_XMSS */ |
|
default: |
|
r = SSH_ERR_KEY_TYPE_UNKNOWN; |
|
goto out; |
goto out; |
} |
|
if (sshkey_is_cert(k) && (r = sshkey_cert_copy(k, n)) != 0) |
if (sshkey_is_cert(k) && (r = sshkey_cert_copy(k, n)) != 0) |
goto out; |
goto out; |
/* success */ |
/* success */ |
|
|
r = 0; |
r = 0; |
out: |
out: |
sshkey_free(n); |
sshkey_free(n); |
#ifdef WITH_OPENSSL |
|
BN_clear_free(rsa_n_dup); |
|
BN_clear_free(rsa_e_dup); |
|
BN_clear_free(dsa_p_dup); |
|
BN_clear_free(dsa_q_dup); |
|
BN_clear_free(dsa_g_dup); |
|
BN_clear_free(dsa_pub_key_dup); |
|
#endif /* WITH_OPENSSL */ |
|
|
|
return r; |
return r; |
} |
} |
|
|