From f71a27920a903c9c36bcb31e68781b17674d3fd2 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Fri, 20 Jun 2014 12:00:00 -0700 Subject: [PATCH] Fix EC crash. This change saves several EC routines from crashing when an EC_KEY is missing a public key. The public key is optional in the EC private key format and, without this patch, running the following through `openssl ec` causes a crash: -----BEGIN EC PRIVATE KEY----- MBkCAQEECAECAwQFBgcIoAoGCCqGSM49AwEH -----END EC PRIVATE KEY----- --- crypto/ec/ec_asn1.c | 2 +- crypto/evp/p_ec_asn1.c | 38 ++++++++++++++++++++------------------ 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index 7b4f74f2..2aa319b1 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -405,7 +405,7 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) { } /* TODO(fork): replace this flexibility with key sensible default? */ - if (!(key->enc_flag & EC_PKEY_NO_PUBKEY)) { + if (!(key->enc_flag & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) { priv_key->publicKey = M_ASN1_BIT_STRING_new(); if (priv_key->publicKey == NULL) { OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE); diff --git a/crypto/evp/p_ec_asn1.c b/crypto/evp/p_ec_asn1.c index d4eec13c..3038b9ea 100644 --- a/crypto/evp/p_ec_asn1.c +++ b/crypto/evp/p_ec_asn1.c @@ -410,25 +410,27 @@ static int 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); - pub_key_bytes_len = EC_POINT_point2oct( - group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx); - if (pub_key_bytes_len == 0) { - reason = ERR_R_MALLOC_FAILURE; - goto err; + if (public_key != NULL) { + pub_key_bytes_len = EC_POINT_point2oct( + group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx); + if (pub_key_bytes_len == 0) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len); + if (pub_key_bytes == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + pub_key_bytes_len = + EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x), + pub_key_bytes, pub_key_bytes_len, ctx); + if (pub_key_bytes_len == 0) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + buf_len = pub_key_bytes_len; } - pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len); - if (pub_key_bytes == NULL) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - pub_key_bytes_len = - EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x), - pub_key_bytes, pub_key_bytes_len, ctx); - if (pub_key_bytes_len == 0) { - reason = ERR_R_MALLOC_FAILURE; - goto err; - } - buf_len = pub_key_bytes_len; } if (ktype == 2) {