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:42:09 +0000 (19:42 +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>
(cherry picked from commit b391570bdeb386d4fd325917c248d593d3c43930)

crypto/ec/ec_ameth.c
crypto/ec/ec_asn1.c

index 66c0d6c4d1706544515854be43307aa3cdb6083d..6738040f6995edb0697b59f7b5282061e5c606c2 100644 (file)
@@ -453,14 +453,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 0fb5c1407625f86c1754f496ba2e4f7abcdf97fc..4e6a74cfaded393a46c74a48dcf018bd99f260fc 100644 (file)
@@ -1214,7 +1214,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);