diff options
author | inoguchi <> | 2018-03-12 13:14:21 +0000 |
---|---|---|
committer | inoguchi <> | 2018-03-12 13:14:21 +0000 |
commit | 7232fedecfd1782f7a08e49519de4e1c7990edb6 (patch) | |
tree | 70fcd8bdcb756233389e3bf8967307f6b2d3072c | |
parent | 52e498cc6e72760b900f1eda649a36103523e200 (diff) | |
download | openbsd-7232fedecfd1782f7a08e49519de4e1c7990edb6.tar.gz openbsd-7232fedecfd1782f7a08e49519de4e1c7990edb6.tar.bz2 openbsd-7232fedecfd1782f7a08e49519de4e1c7990edb6.zip |
Fix for processing of EC public key
Prevents segmentation fault while reading EC private key without public key.
Generates missing EC public key when reading EC private key.
Refer to these OpenSSL commits:
1f2b943254ce590867717375e4f364860a9b7154
2083f7c465d07867dd9867b8742bb71c03d1f203
Reported on GitHub https://github.com/libressl-portable/portable/issues/395
by Anton Bukov (@k06a) .
ok beck@
-rw-r--r-- | src/lib/libcrypto/ec/ec_ameth.c | 14 | ||||
-rw-r--r-- | src/lib/libcrypto/ec/ec_asn1.c | 28 |
2 files changed, 27 insertions, 15 deletions
diff --git a/src/lib/libcrypto/ec/ec_ameth.c b/src/lib/libcrypto/ec/ec_ameth.c index 8d0cdb733b..0932f1e3c9 100644 --- a/src/lib/libcrypto/ec/ec_ameth.c +++ b/src/lib/libcrypto/ec/ec_ameth.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_ameth.c,v 1.18 2017/01/29 17:49:23 beck Exp $ */ | 1 | /* $OpenBSD: ec_ameth.c,v 1.19 2018/03/12 13:14:21 inoguchi Exp $ */ |
2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL | 2 | /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL |
3 | * project 2006. | 3 | * project 2006. |
4 | */ | 4 | */ |
@@ -433,13 +433,15 @@ do_EC_KEY_print(BIO * bp, const EC_KEY * x, int off, int ktype) | |||
433 | } | 433 | } |
434 | if (ktype > 0) { | 434 | if (ktype > 0) { |
435 | public_key = EC_KEY_get0_public_key(x); | 435 | public_key = EC_KEY_get0_public_key(x); |
436 | if ((pub_key = EC_POINT_point2bn(group, public_key, | 436 | if (public_key != NULL) { |
437 | if ((pub_key = EC_POINT_point2bn(group, public_key, | ||
437 | EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) { | 438 | EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) { |
438 | reason = ERR_R_EC_LIB; | 439 | reason = ERR_R_EC_LIB; |
439 | goto err; | 440 | goto err; |
441 | } | ||
442 | if (pub_key) | ||
443 | buf_len = (size_t) BN_num_bytes(pub_key); | ||
440 | } | 444 | } |
441 | if (pub_key) | ||
442 | buf_len = (size_t) BN_num_bytes(pub_key); | ||
443 | } | 445 | } |
444 | if (ktype == 2) { | 446 | if (ktype == 2) { |
445 | priv_key = EC_KEY_get0_private_key(x); | 447 | priv_key = EC_KEY_get0_private_key(x); |
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c index b64b7e14d3..381addfcf6 100644 --- a/src/lib/libcrypto/ec/ec_asn1.c +++ b/src/lib/libcrypto/ec/ec_asn1.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_asn1.c,v 1.24 2017/05/26 16:32:14 jsing Exp $ */ | 1 | /* $OpenBSD: ec_asn1.c,v 1.25 2018/03/12 13:14:21 inoguchi Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Nils Larsch for the OpenSSL project. | 3 | * Written by Nils Larsch for the OpenSSL project. |
4 | */ | 4 | */ |
@@ -1380,17 +1380,18 @@ d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len) | |||
1380 | goto err; | 1380 | goto err; |
1381 | } | 1381 | } |
1382 | 1382 | ||
1383 | if (ret->pub_key) | ||
1384 | EC_POINT_clear_free(ret->pub_key); | ||
1385 | ret->pub_key = EC_POINT_new(ret->group); | ||
1386 | if (ret->pub_key == NULL) { | ||
1387 | ECerror(ERR_R_EC_LIB); | ||
1388 | goto err; | ||
1389 | } | ||
1390 | |||
1383 | if (priv_key->publicKey) { | 1391 | if (priv_key->publicKey) { |
1384 | const unsigned char *pub_oct; | 1392 | const unsigned char *pub_oct; |
1385 | size_t pub_oct_len; | 1393 | size_t pub_oct_len; |
1386 | 1394 | ||
1387 | EC_POINT_clear_free(ret->pub_key); | ||
1388 | ret->pub_key = EC_POINT_new(ret->group); | ||
1389 | if (ret->pub_key == NULL) { | ||
1390 | ECerror(ERR_R_EC_LIB); | ||
1391 | goto err; | ||
1392 | } | ||
1393 | |||
1394 | pub_oct = ASN1_STRING_data(priv_key->publicKey); | 1395 | pub_oct = ASN1_STRING_data(priv_key->publicKey); |
1395 | pub_oct_len = ASN1_STRING_length(priv_key->publicKey); | 1396 | pub_oct_len = ASN1_STRING_length(priv_key->publicKey); |
1396 | if (pub_oct == NULL || pub_oct_len <= 0) { | 1397 | if (pub_oct == NULL || pub_oct_len <= 0) { |
@@ -1405,6 +1406,14 @@ d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len) | |||
1405 | ECerror(ERR_R_EC_LIB); | 1406 | ECerror(ERR_R_EC_LIB); |
1406 | goto err; | 1407 | goto err; |
1407 | } | 1408 | } |
1409 | } else { | ||
1410 | if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, | ||
1411 | NULL, NULL, NULL)) { | ||
1412 | ECerror(ERR_R_EC_LIB); | ||
1413 | goto err; | ||
1414 | } | ||
1415 | /* Remember the original private-key-only encoding. */ | ||
1416 | ret->enc_flag |= EC_PKEY_NO_PUBKEY; | ||
1408 | } | 1417 | } |
1409 | 1418 | ||
1410 | EC_PRIVATEKEY_free(priv_key); | 1419 | EC_PRIVATEKEY_free(priv_key); |
@@ -1429,7 +1438,8 @@ i2d_ECPrivateKey(EC_KEY * a, unsigned char **out) | |||
1429 | size_t buf_len = 0, tmp_len; | 1438 | size_t buf_len = 0, tmp_len; |
1430 | EC_PRIVATEKEY *priv_key = NULL; | 1439 | EC_PRIVATEKEY *priv_key = NULL; |
1431 | 1440 | ||
1432 | if (a == NULL || a->group == NULL || a->priv_key == NULL) { | 1441 | if (a == NULL || a->group == NULL || a->priv_key == NULL || |
1442 | (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { | ||
1433 | ECerror(ERR_R_PASSED_NULL_PARAMETER); | 1443 | ECerror(ERR_R_PASSED_NULL_PARAMETER); |
1434 | goto err; | 1444 | goto err; |
1435 | } | 1445 | } |