version 1.92, 2019/11/13 22:00:21 |
version 1.93, 2019/11/15 06:00:20 |
|
|
sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) |
sshkey_equal_public(const struct sshkey *a, const struct sshkey *b) |
{ |
{ |
#ifdef WITH_OPENSSL |
#ifdef WITH_OPENSSL |
BN_CTX *bnctx; |
|
const BIGNUM *rsa_e_a, *rsa_n_a; |
const BIGNUM *rsa_e_a, *rsa_n_a; |
const BIGNUM *rsa_e_b, *rsa_n_b; |
const BIGNUM *rsa_e_b, *rsa_n_b; |
const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a; |
const BIGNUM *dsa_p_a, *dsa_q_a, *dsa_g_a, *dsa_pub_key_a; |
|
|
EC_KEY_get0_public_key(a->ecdsa) == NULL || |
EC_KEY_get0_public_key(a->ecdsa) == NULL || |
EC_KEY_get0_public_key(b->ecdsa) == NULL) |
EC_KEY_get0_public_key(b->ecdsa) == NULL) |
return 0; |
return 0; |
if ((bnctx = BN_CTX_new()) == NULL) |
|
return 0; |
|
if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), |
if (EC_GROUP_cmp(EC_KEY_get0_group(a->ecdsa), |
EC_KEY_get0_group(b->ecdsa), bnctx) != 0 || |
EC_KEY_get0_group(b->ecdsa), NULL) != 0 || |
EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), |
EC_POINT_cmp(EC_KEY_get0_group(a->ecdsa), |
EC_KEY_get0_public_key(a->ecdsa), |
EC_KEY_get0_public_key(a->ecdsa), |
EC_KEY_get0_public_key(b->ecdsa), bnctx) != 0) { |
EC_KEY_get0_public_key(b->ecdsa), NULL) != 0) |
BN_CTX_free(bnctx); |
|
return 0; |
return 0; |
} |
|
BN_CTX_free(bnctx); |
|
return 1; |
return 1; |
#endif /* WITH_OPENSSL */ |
#endif /* WITH_OPENSSL */ |
case KEY_ED25519_SK: |
case KEY_ED25519_SK: |
|
|
}; |
}; |
int nid; |
int nid; |
u_int i; |
u_int i; |
BN_CTX *bnctx; |
|
const EC_GROUP *g = EC_KEY_get0_group(k); |
const EC_GROUP *g = EC_KEY_get0_group(k); |
|
|
/* |
/* |
|
|
*/ |
*/ |
if ((nid = EC_GROUP_get_curve_name(g)) > 0) |
if ((nid = EC_GROUP_get_curve_name(g)) > 0) |
return nid; |
return nid; |
if ((bnctx = BN_CTX_new()) == NULL) |
|
return -1; |
|
for (i = 0; nids[i] != -1; i++) { |
for (i = 0; nids[i] != -1; i++) { |
if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) { |
if ((eg = EC_GROUP_new_by_curve_name(nids[i])) == NULL) |
BN_CTX_free(bnctx); |
|
return -1; |
return -1; |
} |
if (EC_GROUP_cmp(g, eg, NULL) == 0) |
if (EC_GROUP_cmp(g, eg, bnctx) == 0) |
|
break; |
break; |
EC_GROUP_free(eg); |
EC_GROUP_free(eg); |
} |
} |
BN_CTX_free(bnctx); |
|
if (nids[i] != -1) { |
if (nids[i] != -1) { |
/* Use the group with the NID attached */ |
/* Use the group with the NID attached */ |
EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); |
EC_GROUP_set_asn1_flag(eg, OPENSSL_EC_NAMED_CURVE); |
|
|
int |
int |
sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) |
sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public) |
{ |
{ |
BN_CTX *bnctx; |
|
EC_POINT *nq = NULL; |
EC_POINT *nq = NULL; |
BIGNUM *order, *x, *y, *tmp; |
BIGNUM *order = NULL, *x = NULL, *y = NULL, *tmp = NULL; |
int ret = SSH_ERR_KEY_INVALID_EC_VALUE; |
int ret = SSH_ERR_KEY_INVALID_EC_VALUE; |
|
|
/* |
/* |
|
|
* EC_POINT_oct2point then the caller will need to explicitly check. |
* EC_POINT_oct2point then the caller will need to explicitly check. |
*/ |
*/ |
|
|
if ((bnctx = BN_CTX_new()) == NULL) |
|
return SSH_ERR_ALLOC_FAIL; |
|
BN_CTX_start(bnctx); |
|
|
|
/* |
/* |
* We shouldn't ever hit this case because bignum_get_ecpoint() |
* We shouldn't ever hit this case because bignum_get_ecpoint() |
* refuses to load GF2m points. |
* refuses to load GF2m points. |
|
|
if (EC_POINT_is_at_infinity(group, public)) |
if (EC_POINT_is_at_infinity(group, public)) |
goto out; |
goto out; |
|
|
if ((x = BN_CTX_get(bnctx)) == NULL || |
if ((x = BN_new()) == NULL || |
(y = BN_CTX_get(bnctx)) == NULL || |
(y = BN_new()) == NULL || |
(order = BN_CTX_get(bnctx)) == NULL || |
(order = BN_new()) == NULL || |
(tmp = BN_CTX_get(bnctx)) == NULL) { |
(tmp = BN_new()) == NULL) { |
ret = SSH_ERR_ALLOC_FAIL; |
ret = SSH_ERR_ALLOC_FAIL; |
goto out; |
goto out; |
} |
} |
|
|
/* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ |
/* log2(x) > log2(order)/2, log2(y) > log2(order)/2 */ |
if (EC_GROUP_get_order(group, order, bnctx) != 1 || |
if (EC_GROUP_get_order(group, order, NULL) != 1 || |
EC_POINT_get_affine_coordinates_GFp(group, public, |
EC_POINT_get_affine_coordinates_GFp(group, public, |
x, y, bnctx) != 1) { |
x, y, NULL) != 1) { |
ret = SSH_ERR_LIBCRYPTO_ERROR; |
ret = SSH_ERR_LIBCRYPTO_ERROR; |
goto out; |
goto out; |
} |
} |
|
|
ret = SSH_ERR_ALLOC_FAIL; |
ret = SSH_ERR_ALLOC_FAIL; |
goto out; |
goto out; |
} |
} |
if (EC_POINT_mul(group, nq, NULL, public, order, bnctx) != 1) { |
if (EC_POINT_mul(group, nq, NULL, public, order, NULL) != 1) { |
ret = SSH_ERR_LIBCRYPTO_ERROR; |
ret = SSH_ERR_LIBCRYPTO_ERROR; |
goto out; |
goto out; |
} |
} |
|
|
goto out; |
goto out; |
ret = 0; |
ret = 0; |
out: |
out: |
BN_CTX_free(bnctx); |
BN_clear_free(x); |
|
BN_clear_free(y); |
|
BN_clear_free(order); |
|
BN_clear_free(tmp); |
EC_POINT_free(nq); |
EC_POINT_free(nq); |
return ret; |
return ret; |
} |
} |
|
|
int |
int |
sshkey_ec_validate_private(const EC_KEY *key) |
sshkey_ec_validate_private(const EC_KEY *key) |
{ |
{ |
BN_CTX *bnctx; |
BIGNUM *order = NULL, *tmp = NULL; |
BIGNUM *order, *tmp; |
|
int ret = SSH_ERR_KEY_INVALID_EC_VALUE; |
int ret = SSH_ERR_KEY_INVALID_EC_VALUE; |
|
|
if ((bnctx = BN_CTX_new()) == NULL) |
if ((order = BN_new()) == NULL || (tmp = BN_new()) == NULL) { |
return SSH_ERR_ALLOC_FAIL; |
|
BN_CTX_start(bnctx); |
|
|
|
if ((order = BN_CTX_get(bnctx)) == NULL || |
|
(tmp = BN_CTX_get(bnctx)) == NULL) { |
|
ret = SSH_ERR_ALLOC_FAIL; |
ret = SSH_ERR_ALLOC_FAIL; |
goto out; |
goto out; |
} |
} |
|
|
/* log2(private) > log2(order)/2 */ |
/* log2(private) > log2(order)/2 */ |
if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, bnctx) != 1) { |
if (EC_GROUP_get_order(EC_KEY_get0_group(key), order, NULL) != 1) { |
ret = SSH_ERR_LIBCRYPTO_ERROR; |
ret = SSH_ERR_LIBCRYPTO_ERROR; |
goto out; |
goto out; |
} |
} |
|
|
goto out; |
goto out; |
ret = 0; |
ret = 0; |
out: |
out: |
BN_CTX_free(bnctx); |
BN_clear_free(order); |
|
BN_clear_free(tmp); |
return ret; |
return ret; |
} |
} |
|
|
void |
void |
sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) |
sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point) |
{ |
{ |
BIGNUM *x, *y; |
BIGNUM *x = NULL, *y = NULL; |
BN_CTX *bnctx; |
|
|
|
if (point == NULL) { |
if (point == NULL) { |
fputs("point=(NULL)\n", stderr); |
fputs("point=(NULL)\n", stderr); |
return; |
return; |
} |
} |
if ((bnctx = BN_CTX_new()) == NULL) { |
if ((x = BN_new()) == NULL || (y = BN_new()) == NULL) { |
fprintf(stderr, "%s: BN_CTX_new failed\n", __func__); |
fprintf(stderr, "%s: BN_new failed\n", __func__); |
return; |
goto out; |
} |
} |
BN_CTX_start(bnctx); |
|
if ((x = BN_CTX_get(bnctx)) == NULL || |
|
(y = BN_CTX_get(bnctx)) == NULL) { |
|
fprintf(stderr, "%s: BN_CTX_get failed\n", __func__); |
|
return; |
|
} |
|
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != |
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != |
NID_X9_62_prime_field) { |
NID_X9_62_prime_field) { |
fprintf(stderr, "%s: group is not a prime field\n", __func__); |
fprintf(stderr, "%s: group is not a prime field\n", __func__); |
return; |
goto out; |
} |
} |
if (EC_POINT_get_affine_coordinates_GFp(group, point, x, y, |
if (EC_POINT_get_affine_coordinates_GFp(group, point, |
bnctx) != 1) { |
x, y, NULL) != 1) { |
fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n", |
fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n", |
__func__); |
__func__); |
return; |
goto out; |
} |
} |
fputs("x=", stderr); |
fputs("x=", stderr); |
BN_print_fp(stderr, x); |
BN_print_fp(stderr, x); |
fputs("\ny=", stderr); |
fputs("\ny=", stderr); |
BN_print_fp(stderr, y); |
BN_print_fp(stderr, y); |
fputs("\n", stderr); |
fputs("\n", stderr); |
BN_CTX_free(bnctx); |
out: |
|
BN_clear_free(x); |
|
BN_clear_free(y); |
} |
} |
|
|
void |
void |