From 7232fedecfd1782f7a08e49519de4e1c7990edb6 Mon Sep 17 00:00:00 2001 From: inoguchi <> Date: Mon, 12 Mar 2018 13:14:21 +0000 Subject: 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@ --- src/lib/libcrypto/ec/ec_ameth.c | 14 ++++++++------ src/lib/libcrypto/ec/ec_asn1.c | 28 +++++++++++++++++++--------- 2 files changed, 27 insertions(+), 15 deletions(-) (limited to 'src') 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 @@ -/* $OpenBSD: ec_ameth.c,v 1.18 2017/01/29 17:49:23 beck Exp $ */ +/* $OpenBSD: ec_ameth.c,v 1.19 2018/03/12 13:14:21 inoguchi Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -433,13 +433,15 @@ do_EC_KEY_print(BIO * bp, const EC_KEY * x, int off, int ktype) } if (ktype > 0) { public_key = EC_KEY_get0_public_key(x); - if ((pub_key = EC_POINT_point2bn(group, public_key, + if (public_key != NULL) { + if ((pub_key = EC_POINT_point2bn(group, public_key, EC_KEY_get_conv_form(x), NULL, ctx)) == NULL) { - reason = ERR_R_EC_LIB; - goto err; + reason = ERR_R_EC_LIB; + goto err; + } + if (pub_key) + buf_len = (size_t) BN_num_bytes(pub_key); } - if (pub_key) - buf_len = (size_t) BN_num_bytes(pub_key); } if (ktype == 2) { 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 @@ -/* $OpenBSD: ec_asn1.c,v 1.24 2017/05/26 16:32:14 jsing Exp $ */ +/* $OpenBSD: ec_asn1.c,v 1.25 2018/03/12 13:14:21 inoguchi Exp $ */ /* * Written by Nils Larsch for the OpenSSL project. */ @@ -1380,17 +1380,18 @@ d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len) goto err; } + if (ret->pub_key) + EC_POINT_clear_free(ret->pub_key); + ret->pub_key = EC_POINT_new(ret->group); + if (ret->pub_key == NULL) { + ECerror(ERR_R_EC_LIB); + goto err; + } + if (priv_key->publicKey) { const unsigned char *pub_oct; size_t pub_oct_len; - EC_POINT_clear_free(ret->pub_key); - ret->pub_key = EC_POINT_new(ret->group); - if (ret->pub_key == NULL) { - ECerror(ERR_R_EC_LIB); - goto err; - } - pub_oct = ASN1_STRING_data(priv_key->publicKey); pub_oct_len = ASN1_STRING_length(priv_key->publicKey); if (pub_oct == NULL || pub_oct_len <= 0) { @@ -1405,6 +1406,14 @@ d2i_ECPrivateKey(EC_KEY ** a, const unsigned char **in, long len) ECerror(ERR_R_EC_LIB); goto err; } + } else { + if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, + NULL, NULL, NULL)) { + ECerror(ERR_R_EC_LIB); + goto err; + } + /* Remember the original private-key-only encoding. */ + ret->enc_flag |= EC_PKEY_NO_PUBKEY; } EC_PRIVATEKEY_free(priv_key); @@ -1429,7 +1438,8 @@ i2d_ECPrivateKey(EC_KEY * a, unsigned char **out) size_t buf_len = 0, tmp_len; EC_PRIVATEKEY *priv_key = NULL; - if (a == NULL || a->group == NULL || a->priv_key == NULL) { + if (a == NULL || a->group == NULL || a->priv_key == NULL || + (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { ECerror(ERR_R_PASSED_NULL_PARAMETER); goto err; } -- cgit v1.2.3-55-g6feb