Enforce that d2i_PrivateKey returns a key of the specified type.
If d2i_PrivateKey hit the PKCS#8 codepath, it didn't enforce that the key was of the specified type. Note that this requires tweaking d2i_AutoPrivateKey slightly. A PKCS #8 PrivateKeyInfo may have 3 or 4 elements (optional attributes), so we were relying on this bug for d2i_AutoPrivateKey to work. Change-Id: If50b7a742f535d208e944ba37c3a585689d1da43 Reviewed-on: https://boringssl-review.googlesource.com/7253 Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
886119b9f7
commit
2c198fae28
@ -223,6 +223,11 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
|
|||||||
if (ret == NULL) {
|
if (ret == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (ret->type != type) {
|
||||||
|
OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
|
||||||
|
EVP_PKEY_free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out != NULL) {
|
if (out != NULL) {
|
||||||
@ -261,24 +266,22 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Count the elements to determine the format. */
|
/* Parse the input as a PKCS#8 PrivateKeyInfo. */
|
||||||
switch (num_elements(*inp, (size_t)len)) {
|
CBS cbs;
|
||||||
case 3: {
|
CBS_init(&cbs, *inp, (size_t)len);
|
||||||
/* Parse the input as a PKCS#8 PrivateKeyInfo. */
|
EVP_PKEY *ret = EVP_parse_private_key(&cbs);
|
||||||
CBS cbs;
|
if (ret != NULL) {
|
||||||
CBS_init(&cbs, *inp, (size_t)len);
|
if (out != NULL) {
|
||||||
EVP_PKEY *ret = EVP_parse_private_key(&cbs);
|
EVP_PKEY_free(*out);
|
||||||
if (ret == NULL) {
|
*out = ret;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (out != NULL) {
|
|
||||||
EVP_PKEY_free(*out);
|
|
||||||
*out = ret;
|
|
||||||
}
|
|
||||||
*inp = CBS_data(&cbs);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
*inp = CBS_data(&cbs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
|
/* Count the elements to determine the legacy key format. */
|
||||||
|
switch (num_elements(*inp, (size_t)len)) {
|
||||||
case 4:
|
case 4:
|
||||||
return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len);
|
return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len);
|
||||||
|
|
||||||
|
@ -640,6 +640,15 @@ static bool Testd2i_PrivateKey(void) {
|
|||||||
}
|
}
|
||||||
ERR_clear_error();
|
ERR_clear_error();
|
||||||
|
|
||||||
|
derp = kExampleRSAKeyPKCS8;
|
||||||
|
pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp,
|
||||||
|
sizeof(kExampleRSAKeyPKCS8)));
|
||||||
|
if (pkey) {
|
||||||
|
fprintf(stderr, "Imported RSA key as EC key.\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ERR_clear_error();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user