version 1.24, 2022/10/28 00:44:17 |
version 1.25, 2022/10/28 00:44:44 |
|
|
ssh_ecdsa_deserialize_public(const char *ktype, struct sshbuf *b, |
ssh_ecdsa_deserialize_public(const char *ktype, struct sshbuf *b, |
struct sshkey *key) |
struct sshkey *key) |
{ |
{ |
int ret = SSH_ERR_INTERNAL_ERROR; |
int r; |
char *curve = NULL; |
char *curve = NULL; |
EC_POINT *q = NULL; |
|
|
|
key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype); |
if ((key->ecdsa_nid = sshkey_ecdsa_nid_from_name(ktype)) == -1) |
if (sshbuf_get_cstring(b, &curve, NULL) != 0) { |
return SSH_ERR_INVALID_ARGUMENT; |
ret = SSH_ERR_INVALID_FORMAT; |
if ((r = sshbuf_get_cstring(b, &curve, NULL)) != 0) |
goto out; |
goto out; |
} |
|
if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) { |
if (key->ecdsa_nid != sshkey_curve_name_to_nid(curve)) { |
ret = SSH_ERR_EC_CURVE_MISMATCH; |
r = SSH_ERR_EC_CURVE_MISMATCH; |
goto out; |
goto out; |
} |
} |
EC_KEY_free(key->ecdsa); |
EC_KEY_free(key->ecdsa); |
|
key->ecdsa = NULL; |
if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL) { |
if ((key->ecdsa = EC_KEY_new_by_curve_name(key->ecdsa_nid)) == NULL) { |
ret = SSH_ERR_EC_CURVE_INVALID; |
r = SSH_ERR_LIBCRYPTO_ERROR; |
goto out; |
goto out; |
} |
} |
if ((q = EC_POINT_new(EC_KEY_get0_group(key->ecdsa))) == NULL) { |
if ((r = sshbuf_get_eckey(b, key->ecdsa)) != 0) |
ret = SSH_ERR_ALLOC_FAIL; |
|
goto out; |
goto out; |
} |
if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), |
if (sshbuf_get_ec(b, q, EC_KEY_get0_group(key->ecdsa)) != 0) { |
EC_KEY_get0_public_key(key->ecdsa)) != 0) { |
ret = SSH_ERR_INVALID_FORMAT; |
r = SSH_ERR_KEY_INVALID_EC_VALUE; |
goto out; |
goto out; |
} |
} |
if (sshkey_ec_validate_public(EC_KEY_get0_group(key->ecdsa), q) != 0) { |
/* success */ |
ret = SSH_ERR_KEY_INVALID_EC_VALUE; |
r = 0; |
goto out; |
#ifdef DEBUG_PK |
|
sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), |
|
EC_KEY_get0_public_key(key->ecdsa)); |
|
#endif |
|
out: |
|
free(curve); |
|
if (r != 0) { |
|
EC_KEY_free(key->ecdsa); |
|
key->ecdsa = NULL; |
} |
} |
if (EC_KEY_set_public_key(key->ecdsa, q) != 1) { |
return r; |
/* XXX assume it is a allocation error */ |
} |
ret = SSH_ERR_ALLOC_FAIL; |
|
|
static int |
|
ssh_ecdsa_deserialize_private(const char *ktype, struct sshbuf *b, |
|
struct sshkey *key) |
|
{ |
|
int r; |
|
BIGNUM *exponent = NULL; |
|
|
|
if (!sshkey_is_cert(key)) { |
|
if ((r = ssh_ecdsa_deserialize_public(ktype, b, key)) != 0) |
|
return r; |
|
} |
|
if ((r = sshbuf_get_bignum2(b, &exponent)) != 0) |
goto out; |
goto out; |
|
if (EC_KEY_set_private_key(key->ecdsa, exponent) != 1) { |
|
r = SSH_ERR_LIBCRYPTO_ERROR; |
|
goto out; |
} |
} |
#ifdef DEBUG_PK |
if ((r = sshkey_ec_validate_private(key->ecdsa)) != 0) |
sshkey_dump_ec_point(EC_KEY_get0_group(key->ecdsa), q); |
goto out; |
#endif |
|
/* success */ |
/* success */ |
ret = 0; |
r = 0; |
out: |
out: |
free(curve); |
BN_clear_free(exponent); |
EC_POINT_free(q); |
return r; |
return ret; |
|
} |
} |
|
|
/* ARGSUSED */ |
/* ARGSUSED */ |
|
|
/* .ssh_serialize_public = */ ssh_ecdsa_serialize_public, |
/* .ssh_serialize_public = */ ssh_ecdsa_serialize_public, |
/* .ssh_deserialize_public = */ ssh_ecdsa_deserialize_public, |
/* .ssh_deserialize_public = */ ssh_ecdsa_deserialize_public, |
/* .ssh_serialize_private = */ ssh_ecdsa_serialize_private, |
/* .ssh_serialize_private = */ ssh_ecdsa_serialize_private, |
|
/* .ssh_deserialize_private = */ ssh_ecdsa_deserialize_private, |
/* .generate = */ ssh_ecdsa_generate, |
/* .generate = */ ssh_ecdsa_generate, |
/* .copy_public = */ ssh_ecdsa_copy_public, |
/* .copy_public = */ ssh_ecdsa_copy_public, |
/* .sign = */ ssh_ecdsa_sign, |
/* .sign = */ ssh_ecdsa_sign, |