Handle empty keys in EVP_marshal_public_key()

Instead of crashing when an empty key is passed to
EVP_marshal_public_key(), return with an
EVP_R_UNSUPPORTED_ALGORITHM_ERROR. This brings e.g. X509_PUBKEY_set()
closer to how it behaved before 68772b31 (previously, it returned an
error on an empty public key rather than dereferencing pkey->ameth).

Change-Id: Ieac368725adb7f22329c035d9d0685b44b885888
Reviewed-on: https://boringssl-review.googlesource.com/7351
Reviewed-by: David Benjamin <davidben@google.com>
This commit is contained in:
Emily Stark 2016-03-06 23:41:16 -08:00 committed by David Benjamin
parent ad004af661
commit 62e0219679
2 changed files with 27 additions and 2 deletions

View File

@ -107,7 +107,7 @@ err:
}
int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) {
if (key->ameth->pub_encode == NULL) {
if (key->ameth == NULL || key->ameth->pub_encode == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
return 0;
}
@ -155,7 +155,7 @@ err:
}
int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) {
if (key->ameth->priv_encode == NULL) {
if (key->ameth == NULL || key->ameth->priv_encode == NULL) {
OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
return 0;
}

View File

@ -586,6 +586,25 @@ static bool TestEVP_PKCS82PKEY(void) {
return true;
}
// TestEVPMarshalEmptyPublicKey tests |EVP_marshal_public_key| on an empty key.
static bool TestEVPMarshalEmptyPublicKey(void) {
ScopedEVP_PKEY empty(EVP_PKEY_new());
if (!empty) {
return false;
}
ScopedCBB cbb;
if (EVP_marshal_public_key(cbb.get(), empty.get())) {
fprintf(stderr, "Marshalled empty public key.\n");
return false;
}
if (ERR_GET_REASON(ERR_peek_last_error()) != EVP_R_UNSUPPORTED_ALGORITHM) {
fprintf(stderr, "Marshalling an empty public key gave wrong error.\n");
return false;
}
ERR_clear_error();
return true;
}
// Testd2i_PrivateKey tests |d2i_PrivateKey|.
static bool Testd2i_PrivateKey(void) {
const uint8_t *derp = kExampleRSAKeyDER;
@ -685,6 +704,12 @@ int main(void) {
return 1;
}
if (!TestEVPMarshalEmptyPublicKey()) {
fprintf(stderr, "TestEVPMarshalEmptyPublicKey failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
if (!Testd2i_PrivateKey()) {
fprintf(stderr, "Testd2i_PrivateKey failed\n");
ERR_print_errors_fp(stderr);