diff options
author | Adam Langley <agl@google.com> | 2014-11-04 04:57:47 +0300 |
---|---|---|
committer | Adam Langley <agl@google.com> | 2014-11-11 00:45:31 +0300 |
commit | 9f5a314d35e7eb8be36206f6903a818dfaf24eba (patch) | |
tree | f769c5b3cfd6213c27fe196abb19636dd886c09b /crypto/ec/ec_asn1.c | |
parent | 1a8b549098d963911ee2a406a646127e8094b83b (diff) |
Automatically generate a missing EC public key.
When d2i_ECPrivateKey reads a private key with a missing (optional)
public key, generate one automatically from the group and private key.
(Imported from upstream's 2083f7c465d07867dd9867b8742bb71c03d1f203)
Change-Id: I9e5090de87cf846ab92e4be5b6bf64e6091d02e4
Diffstat (limited to 'crypto/ec/ec_asn1.c')
-rw-r--r-- | crypto/ec/ec_asn1.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c index 36f1cd59..add2f53d 100644 --- a/crypto/ec/ec_asn1.c +++ b/crypto/ec/ec_asn1.c @@ -341,19 +341,19 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) { goto err; } - /* TODO(fork): loading the public key is silly. Why not calculate it? */ + if (ret->pub_key) { + EC_POINT_free(ret->pub_key); + } + ret->pub_key = EC_POINT_new(ret->group); + if (ret->pub_key == NULL) { + OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB); + goto err; + } + if (priv_key->publicKey) { const uint8_t *pub_oct; size_t pub_oct_len; - if (ret->pub_key) { - EC_POINT_free(ret->pub_key); - } - ret->pub_key = EC_POINT_new(ret->group); - if (ret->pub_key == NULL) { - OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB); - goto err; - } pub_oct = M_ASN1_STRING_data(priv_key->publicKey); pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey); /* save the point conversion form */ @@ -363,6 +363,14 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) { OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB); goto err; } + } else { + if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL, + NULL)) { + OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB); + goto err; + } + /* Remember the original private-key-only encoding. */ + ret->enc_flag |= EC_PKEY_NO_PUBKEY; } ok = 1; |