RT3065: ec_private_key_dont_crash
authorAdam Langley <agl@chromium.org>
Tue, 23 Apr 2013 19:12:36 +0000 (15:12 -0400)
committerEmilia Kasper <emilia@openssl.org>
Wed, 27 Aug 2014 17:49:34 +0000 (19:49 +0200)
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-----

Reviewed-by: Dr Stephen Henson <steve@openssl.org>
crypto/ec/ec_ameth.c
crypto/ec/ec_asn1.c

index bede19b2c7099a89dde272bb1a476309242eafe9..a149bf6c2765bec172dee51c4ab3146184a38257 100644 (file)
@@ -473,14 +473,16 @@ 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);
-               if ((pub_key = EC_POINT_point2bn(group, public_key,
-                       EC_KEY_get_conv_form(x), NULL, ctx)) == NULL)
+               if (public_key != NULL)
                        {
-                       reason = ERR_R_EC_LIB;
-                       goto err;
-                       }
-               if (pub_key)
+                       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;
+                               }
                        buf_len = (size_t)BN_num_bytes(pub_key);
+                       }
                }
 
        if (ktype == 2)
index e94f34e11b7ca36e0f449a2181745088921fbb2c..510295ef2bf08bf54a80ba333a6d7ea94fe8ee97 100644 (file)
@@ -1230,7 +1230,8 @@ int       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))
                {
                ECerr(EC_F_I2D_ECPRIVATEKEY,
                       ERR_R_PASSED_NULL_PARAMETER);