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-----
This commit is contained in:
Adam Langley 2014-06-20 12:00:00 -07:00
parent 27ae9ed774
commit f71a27920a
2 changed files with 21 additions and 19 deletions

View File

@ -405,7 +405,7 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
} }
/* TODO(fork): replace this flexibility with key sensible default? */ /* 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(); priv_key->publicKey = M_ASN1_BIT_STRING_new();
if (priv_key->publicKey == NULL) { if (priv_key->publicKey == NULL) {
OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE); OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);

View File

@ -410,25 +410,27 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
if (ktype > 0) { if (ktype > 0) {
public_key = EC_KEY_get0_public_key(x); public_key = EC_KEY_get0_public_key(x);
pub_key_bytes_len = EC_POINT_point2oct( if (public_key != NULL) {
group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx); pub_key_bytes_len = EC_POINT_point2oct(
if (pub_key_bytes_len == 0) { group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
reason = ERR_R_MALLOC_FAILURE; if (pub_key_bytes_len == 0) {
goto err; 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) { if (ktype == 2) {