summaryrefslogtreecommitdiffstats
path: root/src/crypto/evp
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto/evp')
-rw-r--r--src/crypto/evp/evp.c53
-rw-r--r--src/crypto/evp/evp_ctx.c3
-rw-r--r--src/crypto/evp/evp_extra_test.cc265
-rw-r--r--src/crypto/evp/evp_test.cc14
-rw-r--r--src/crypto/evp/internal.h7
-rw-r--r--src/crypto/evp/p_ec_asn1.c24
-rw-r--r--src/crypto/evp/p_rsa.c2
-rw-r--r--src/crypto/evp/p_rsa_asn1.c2
8 files changed, 264 insertions, 106 deletions
diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c
index 5822379..afe5c38 100644
--- a/src/crypto/evp/evp.c
+++ b/src/crypto/evp/evp.c
@@ -60,7 +60,6 @@
#include <string.h>
#include <openssl/bio.h>
-#include <openssl/dh.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/err.h>
@@ -73,10 +72,6 @@
#include "../internal.h"
-extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
-
EVP_PKEY *EVP_PKEY_new(void) {
EVP_PKEY *ret;
@@ -235,15 +230,22 @@ int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) {
return EVP_PKEY_assign(pkey, EVP_PKEY_RSA, key);
}
-RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_RSA) {
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY);
return NULL;
}
- RSA_up_ref(pkey->pkey.rsa);
return pkey->pkey.rsa;
}
+RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
+ RSA *rsa = EVP_PKEY_get0_RSA(pkey);
+ if (rsa != NULL) {
+ RSA_up_ref(rsa);
+ }
+ return rsa;
+}
+
int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) {
if (EVP_PKEY_assign_DSA(pkey, key)) {
DSA_up_ref(key);
@@ -256,15 +258,22 @@ int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) {
return EVP_PKEY_assign(pkey, EVP_PKEY_DSA, key);
}
-DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) {
+DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_DSA) {
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY);
return NULL;
}
- DSA_up_ref(pkey->pkey.dsa);
return pkey->pkey.dsa;
}
+DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) {
+ DSA *dsa = EVP_PKEY_get0_DSA(pkey);
+ if (dsa != NULL) {
+ DSA_up_ref(dsa);
+ }
+ return dsa;
+}
+
int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
if (EVP_PKEY_assign_EC_KEY(pkey, key)) {
EC_KEY_up_ref(key);
@@ -277,34 +286,20 @@ int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key);
}
-EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) {
+EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_EC) {
OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY);
return NULL;
}
- EC_KEY_up_ref(pkey->pkey.ec);
return pkey->pkey.ec;
}
-int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) {
- if (EVP_PKEY_assign_DH(pkey, key)) {
- DH_up_ref(key);
- return 1;
- }
- return 0;
-}
-
-int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) {
- return EVP_PKEY_assign(pkey, EVP_PKEY_DH, key);
-}
-
-DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) {
- if (pkey->type != EVP_PKEY_DH) {
- OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DH_KEY);
- return NULL;
+EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) {
+ EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey);
+ if (ec_key != NULL) {
+ EC_KEY_up_ref(ec_key);
}
- DH_up_ref(pkey->pkey.dh);
- return pkey->pkey.dh;
+ return ec_key;
}
int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) {
diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c
index a8e71fe..9e038cd 100644
--- a/src/crypto/evp/evp_ctx.c
+++ b/src/crypto/evp/evp_ctx.c
@@ -66,9 +66,6 @@
#include "internal.h"
-extern const EVP_PKEY_METHOD rsa_pkey_meth;
-extern const EVP_PKEY_METHOD ec_pkey_meth;
-
static const EVP_PKEY_METHOD *const evp_methods[] = {
&rsa_pkey_meth,
&ec_pkey_meth,
diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc
index bd70040..fe7a002 100644
--- a/src/crypto/evp/evp_extra_test.cc
+++ b/src/crypto/evp/evp_extra_test.cc
@@ -16,6 +16,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <utility>
#include <vector>
#include <openssl/bytestring.h>
@@ -233,6 +234,85 @@ static const uint8_t kExamplePSSCert[] = {
0x8c, 0x16,
};
+// kBadPSSCert is an example RSA-PSS certificate with bad parameters.
+static const uint8_t kBadPSSCert[] = {
+ 0x30, 0x82, 0x03, 0x76, 0x30, 0x82, 0x02, 0x3a, 0xa0, 0x03, 0x02, 0x01,
+ 0x02, 0x02, 0x09, 0x00, 0xd7, 0x30, 0x64, 0xbc, 0x9f, 0x12, 0xfe, 0xc3,
+ 0x30, 0x3e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x0a, 0x30, 0x31, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x1a, 0x30, 0x18, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0x30, 0x0b, 0x06,
+ 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa2, 0x04,
+ 0x02, 0x02, 0x00, 0xde, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03,
+ 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6e,
+ 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63, 0x65,
+ 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1e, 0x17,
+ 0x0d, 0x31, 0x35, 0x31, 0x31, 0x30, 0x34, 0x31, 0x36, 0x30, 0x32, 0x33,
+ 0x35, 0x5a, 0x17, 0x0d, 0x31, 0x35, 0x31, 0x32, 0x30, 0x34, 0x31, 0x36,
+ 0x30, 0x32, 0x33, 0x35, 0x5a, 0x30, 0x27, 0x31, 0x25, 0x30, 0x23, 0x06,
+ 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49,
+ 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x20, 0x50, 0x53, 0x53, 0x20, 0x63,
+ 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x82,
+ 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
+ 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0xda, 0x33, 0xb5, 0x87,
+ 0xa9, 0x50, 0x80, 0x18, 0x02, 0x00, 0xfb, 0x32, 0xf5, 0x29, 0x6b, 0xef,
+ 0x01, 0x24, 0xeb, 0x86, 0x5a, 0xbe, 0xd5, 0xe3, 0xdd, 0x3b, 0xbc, 0x2c,
+ 0xad, 0x65, 0xf6, 0x2a, 0x26, 0x28, 0x4d, 0x8a, 0xc9, 0x61, 0x39, 0xf1,
+ 0x84, 0xb9, 0xe7, 0xd3, 0x0a, 0xc7, 0xa8, 0x0a, 0x6d, 0xef, 0xd9, 0xcb,
+ 0x20, 0x11, 0xbb, 0x71, 0xf4, 0xa1, 0xc9, 0x9a, 0x85, 0x1c, 0xe6, 0x3f,
+ 0x23, 0x39, 0x58, 0x3c, 0xc5, 0x6d, 0xfa, 0x03, 0xe8, 0xdb, 0xdd, 0xe0,
+ 0xc3, 0xde, 0x85, 0x76, 0xce, 0x49, 0x06, 0xc8, 0xe1, 0x8e, 0x4c, 0x86,
+ 0x9c, 0xec, 0xab, 0xf4, 0xe5, 0x27, 0xb4, 0x5a, 0xaf, 0xc4, 0x36, 0xd3,
+ 0x20, 0x81, 0x54, 0xee, 0x8f, 0x48, 0x77, 0x10, 0xf8, 0x79, 0xd6, 0xaa,
+ 0x8d, 0x1b, 0xfe, 0x7d, 0xe8, 0x15, 0x13, 0xe0, 0x7b, 0xf6, 0x90, 0xe4,
+ 0xe2, 0xcd, 0x2e, 0x8e, 0xc9, 0x3a, 0x75, 0x42, 0xed, 0x0a, 0x0f, 0x51,
+ 0xb2, 0xdd, 0x2e, 0x70, 0x61, 0x68, 0xd7, 0xd9, 0xab, 0xf9, 0xbe, 0xe4,
+ 0x75, 0xb7, 0xe7, 0xf2, 0x96, 0x7b, 0xd9, 0x93, 0x43, 0x24, 0xfb, 0x9e,
+ 0x55, 0xda, 0xd4, 0x01, 0x6c, 0x3d, 0xa2, 0x59, 0x7a, 0xd5, 0x47, 0x18,
+ 0x7e, 0x4e, 0xf9, 0x5d, 0xda, 0xcb, 0x93, 0xa2, 0x65, 0x2f, 0x8d, 0x46,
+ 0xad, 0x81, 0xdc, 0xf0, 0xa9, 0x5f, 0x5d, 0xfe, 0x37, 0x80, 0x64, 0x2a,
+ 0x41, 0xfa, 0xe9, 0x1e, 0x48, 0x38, 0x22, 0x1d, 0x9c, 0x23, 0xa5, 0xad,
+ 0xda, 0x78, 0x45, 0x18, 0x0c, 0xeb, 0x95, 0xca, 0x2b, 0xcc, 0xb9, 0x62,
+ 0x40, 0x85, 0x09, 0x44, 0x88, 0x4c, 0xf2, 0x1e, 0x08, 0x80, 0x37, 0xe9,
+ 0x06, 0x96, 0x8f, 0x75, 0x54, 0x0b, 0xa9, 0x2d, 0xa9, 0x15, 0xb5, 0xda,
+ 0xe5, 0xe4, 0x23, 0xaa, 0x2c, 0x89, 0xc1, 0xa9, 0x36, 0xbc, 0x9f, 0x02,
+ 0x03, 0x01, 0x00, 0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06, 0x03,
+ 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78,
+ 0xa0, 0x65, 0x2d, 0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6,
+ 0xe1, 0x5f, 0x7b, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+ 0x30, 0x16, 0x80, 0x14, 0x2b, 0x75, 0xf3, 0x43, 0x78, 0xa0, 0x65, 0x2d,
+ 0xe4, 0xb6, 0xf3, 0x07, 0x04, 0x38, 0x21, 0xaf, 0xb6, 0xe1, 0x5f, 0x7b,
+ 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01,
+ 0x01, 0xff, 0x30, 0x31, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
+ 0x01, 0x01, 0x0a, 0x30, 0x24, 0xa0, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60,
+ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0xa1, 0x0d, 0x30, 0x0b,
+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, 0xa2,
+ 0x04, 0x02, 0x02, 0x00, 0xde, 0x03, 0x82, 0x01, 0x01, 0x00, 0x08, 0xc1,
+ 0xb6, 0x6f, 0x74, 0x94, 0x6c, 0x60, 0x75, 0xd8, 0xdc, 0xe1, 0x7b, 0xbf,
+ 0x9d, 0xb5, 0xd7, 0x14, 0x75, 0x6c, 0xdb, 0x35, 0x5c, 0x1e, 0xff, 0xe6,
+ 0xa8, 0xe6, 0x68, 0x42, 0x41, 0x81, 0xf6, 0xbf, 0xc1, 0x56, 0x02, 0xdb,
+ 0xc6, 0x11, 0xeb, 0x15, 0x9d, 0xa9, 0x1c, 0x61, 0x25, 0x6d, 0x46, 0x0f,
+ 0x7e, 0x27, 0xdd, 0x4b, 0xdc, 0xed, 0x07, 0xbd, 0xde, 0xd5, 0xde, 0x09,
+ 0xf8, 0xfd, 0xbd, 0xa3, 0x4c, 0x81, 0xa9, 0xf7, 0x78, 0xff, 0x01, 0x80,
+ 0x73, 0xf2, 0x40, 0xf2, 0xa8, 0x27, 0xe8, 0x00, 0x04, 0x3b, 0xf5, 0xe7,
+ 0xa6, 0x58, 0x45, 0x79, 0x34, 0x49, 0x42, 0xd2, 0xd9, 0x56, 0x5e, 0xf9,
+ 0x0a, 0x41, 0xd7, 0x81, 0x41, 0x94, 0x77, 0x78, 0x7e, 0x00, 0x3b, 0xca,
+ 0xb5, 0xc0, 0x6e, 0x5b, 0xd7, 0x52, 0x52, 0x77, 0x1a, 0x52, 0xb8, 0x0d,
+ 0x29, 0x1f, 0x2e, 0xfe, 0x1f, 0xf6, 0xb0, 0xc1, 0xb7, 0xf1, 0x15, 0x98,
+ 0x0f, 0x30, 0x5d, 0x74, 0x2f, 0xfa, 0xe9, 0x84, 0xda, 0xde, 0xbe, 0xca,
+ 0x91, 0x55, 0x1f, 0x5b, 0xbc, 0xaa, 0x45, 0x07, 0xc4, 0x2e, 0x21, 0x8a,
+ 0x75, 0xc9, 0xbe, 0x6e, 0x39, 0x53, 0x10, 0xcb, 0x2f, 0x4b, 0xe1, 0x21,
+ 0x1e, 0xea, 0x7d, 0x0b, 0x36, 0xe9, 0xa0, 0x2c, 0x76, 0x17, 0x1f, 0x69,
+ 0x34, 0xfb, 0x45, 0x63, 0x7c, 0x84, 0x39, 0xb4, 0x21, 0x98, 0xbd, 0x49,
+ 0xca, 0x80, 0x91, 0x5a, 0xa0, 0x44, 0xef, 0x91, 0xb3, 0x14, 0xf6, 0xd1,
+ 0x6a, 0x2b, 0xb1, 0xe5, 0x4a, 0x44, 0x92, 0x7b, 0x3e, 0x8b, 0x7b, 0x6b,
+ 0x90, 0x6b, 0x2c, 0x67, 0x3b, 0x0e, 0xb9, 0x5a, 0x87, 0x35, 0x33, 0x59,
+ 0x94, 0x2f, 0x7e, 0xf6, 0x13, 0xc7, 0x22, 0x87, 0x3d, 0x50, 0xc9, 0x80,
+ 0x40, 0xda, 0x35, 0xbc, 0x62, 0x16, 0xdc, 0xd5, 0x95, 0xa1, 0xe1, 0x9b,
+ 0x68, 0x9f,
+};
+
// kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8
// PrivateKeyInfo.
static const uint8_t kExampleRSAKeyPKCS8[] = {
@@ -342,6 +422,22 @@ static const uint8_t kExampleBadECKeyDER2[] = {
0x07,
};
+// kInvalidPrivateKey is an invalid private key. See
+// https://rt.openssl.org/Ticket/Display.html?id=4131.
+static const uint8_t kInvalidPrivateKey[] = {
+ 0x30, 0x39, 0x02, 0x01, 0x02, 0x30, 0x09, 0x06, 0x01, 0x38, 0x08,
+ 0x04, 0x69, 0x30, 0x30, 0x80, 0x30, 0x19, 0x01, 0x02, 0x9f, 0xf8,
+ 0x8b, 0x29, 0x80, 0x30, 0xb0, 0x1b, 0x06, 0x09, 0x22, 0xbe, 0x08,
+ 0x04, 0xe9, 0x30, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x3a, 0x01, 0x80,
+ 0x09, 0x30, 0x80, 0x06, 0x01, 0x02, 0x30, 0x80, 0x30, 0x01, 0x3b,
+ 0x02, 0x00, 0x00, 0x04, 0x20, 0x30, 0x82, 0x04, 0xe9, 0x30, 0xc3,
+ 0xe8, 0x30, 0x01, 0x05, 0x30, 0x80, 0x30, 0x01, 0x3b, 0x01, 0x04,
+ 0x02, 0x02, 0xff, 0x00, 0x30, 0x29, 0x02, 0x11, 0x03, 0x29, 0x29,
+ 0x02, 0x00, 0x99, 0x30, 0x80, 0x06, 0x21, 0x02, 0x24, 0x04, 0xe8,
+ 0x30, 0x01, 0x01, 0x04, 0x30, 0x80, 0x1b, 0x06, 0x09, 0x2a, 0x86,
+ 0x48, 0x30, 0x01, 0xaa, 0x02, 0x86, 0xc0, 0x30, 0xdf, 0xe9, 0x80,
+};
+
static ScopedEVP_PKEY LoadExampleRSAKey() {
ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
sizeof(kExampleRSAKeyDER)));
@@ -376,16 +472,17 @@ static bool TestEVP_DigestSignInit(void) {
std::vector<uint8_t> sig;
sig.resize(sig_len);
- if (!EVP_DigestSignFinal(md_ctx.get(), bssl::vector_data(&sig), &sig_len)) {
+ if (!EVP_DigestSignFinal(md_ctx.get(), sig.data(), &sig_len)) {
return false;
}
sig.resize(sig_len);
// Ensure that the signature round-trips.
md_ctx.Reset();
- if (!EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL, pkey.get()) ||
+ if (!EVP_DigestVerifyInit(md_ctx.get(), NULL, EVP_sha256(), NULL,
+ pkey.get()) ||
!EVP_DigestVerifyUpdate(md_ctx.get(), kMsg, sizeof(kMsg)) ||
- !EVP_DigestVerifyFinal(md_ctx.get(), bssl::vector_data(&sig), sig_len)) {
+ !EVP_DigestVerifyFinal(md_ctx.get(), sig.data(), sig_len)) {
return false;
}
@@ -432,7 +529,7 @@ static bool TestAlgorithmRoundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
std::vector<uint8_t> sig;
sig.resize(sig_len);
- if (!EVP_DigestSignFinal(md_ctx, bssl::vector_data(&sig), &sig_len)) {
+ if (!EVP_DigestSignFinal(md_ctx, sig.data(), &sig_len)) {
return false;
}
sig.resize(sig_len);
@@ -442,8 +539,7 @@ static bool TestAlgorithmRoundtrip(EVP_MD_CTX *md_ctx, EVP_PKEY *pkey) {
if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx_verify.get(), algor.get(),
pkey) ||
!EVP_DigestVerifyUpdate(md_ctx_verify.get(), kMsg, sizeof(kMsg)) ||
- !EVP_DigestVerifyFinal(md_ctx_verify.get(), bssl::vector_data(&sig),
- sig_len)) {
+ !EVP_DigestVerifyFinal(md_ctx_verify.get(), sig.data(), sig_len)) {
return false;
}
@@ -477,16 +573,52 @@ static bool TestEVP_DigestSignAlgorithm(void) {
return true;
}
-static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
- CBS cert, cert_body, tbs_cert, algorithm, signature;
- CBS_init(&cert, kExamplePSSCert, sizeof(kExamplePSSCert));
- if (!CBS_get_asn1(&cert, &cert_body, CBS_ASN1_SEQUENCE) ||
- CBS_len(&cert) != 0 ||
+static bool ParseCertificate(CBS *out_tbs_cert,
+ ScopedEVP_PKEY *out_pubkey,
+ ScopedX509_ALGOR *out_algor,
+ CBS *out_signature,
+ const CBS *in_) {
+ CBS in = *in_;
+ CBS cert_body, tbs_cert, algorithm, signature;
+ if (!CBS_get_asn1(&in, &cert_body, CBS_ASN1_SEQUENCE) ||
+ CBS_len(&in) != 0 ||
!CBS_get_any_asn1_element(&cert_body, &tbs_cert, NULL, NULL) ||
!CBS_get_asn1_element(&cert_body, &algorithm, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&cert_body, &signature, CBS_ASN1_BITSTRING) ||
CBS_len(&cert_body) != 0) {
- fprintf(stderr, "Failed to parse certificate\n");
+ return false;
+ }
+
+ CBS tbs_cert_copy = tbs_cert;
+ CBS tbs_cert_body, discard, spki;
+ if (!CBS_get_asn1(&tbs_cert_copy, &tbs_cert_body, CBS_ASN1_SEQUENCE) ||
+ CBS_len(&tbs_cert_copy) != 0 ||
+ !CBS_get_optional_asn1(
+ &tbs_cert_body, &discard, NULL,
+ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) ||
+ !CBS_get_asn1(&tbs_cert_body, &discard /* serialNumber */,
+ CBS_ASN1_INTEGER) ||
+ !CBS_get_asn1(&tbs_cert_body, &discard /* signature */,
+ CBS_ASN1_SEQUENCE) ||
+ !CBS_get_any_asn1_element(&tbs_cert_body, &discard /* issuer */,
+ NULL, NULL) ||
+ !CBS_get_asn1(&tbs_cert_body, &discard /* validity */,
+ CBS_ASN1_SEQUENCE) ||
+ !CBS_get_any_asn1_element(&tbs_cert_body, &discard /* subject */,
+ NULL, NULL) ||
+ !CBS_get_asn1_element(&tbs_cert_body, &spki, CBS_ASN1_SEQUENCE)) {
+ return false;
+ }
+
+ const uint8_t *derp = CBS_data(&spki);
+ ScopedEVP_PKEY pubkey(d2i_PUBKEY(NULL, &derp, CBS_len(&spki)));
+ if (!pubkey || derp != CBS_data(&spki) + CBS_len(&spki)) {
+ return false;
+ }
+
+ derp = CBS_data(&algorithm);
+ ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
+ if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
return false;
}
@@ -494,21 +626,28 @@ static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
// leading phase byte is just a zero.
uint8_t padding;
if (!CBS_get_u8(&signature, &padding) || padding != 0) {
- fprintf(stderr, "Invalid signature padding\n");
return false;
}
- const uint8_t *derp = CBS_data(&algorithm);
- ScopedX509_ALGOR algor(d2i_X509_ALGOR(NULL, &derp, CBS_len(&algorithm)));
- if (!algor || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) {
- fprintf(stderr, "Failed to parse algorithm\n");
+ *out_tbs_cert = tbs_cert;
+ *out_pubkey = std::move(pubkey);
+ *out_algor = std::move(algor);
+ *out_signature = signature;
+ return true;
+}
+
+static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
+ CBS in, tbs_cert, signature;
+ ScopedEVP_PKEY pkey;
+ ScopedX509_ALGOR algor;
+ CBS_init(&in, kExamplePSSCert, sizeof(kExamplePSSCert));
+ if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) {
+ fprintf(stderr, "Failed to parse certificate\n");
return false;
}
- ScopedEVP_PKEY pkey = LoadExampleRSAKey();
ScopedEVP_MD_CTX md_ctx;
- if (!pkey ||
- !EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
+ if (!EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
pkey.get()) ||
!EVP_DigestVerifyUpdate(md_ctx.get(), CBS_data(&tbs_cert),
CBS_len(&tbs_cert)) ||
@@ -519,8 +658,28 @@ static bool TestEVP_DigestVerifyInitFromAlgorithm(void) {
return true;
}
-static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
- int expected_id) {
+static bool TestBadPSSParameters(void) {
+ CBS in, tbs_cert, signature;
+ ScopedEVP_PKEY pkey;
+ ScopedX509_ALGOR algor;
+ CBS_init(&in, kBadPSSCert, sizeof(kBadPSSCert));
+ if (!ParseCertificate(&tbs_cert, &pkey, &algor, &signature, &in)) {
+ fprintf(stderr, "Failed to parse certificate\n");
+ return false;
+ }
+
+ ScopedEVP_MD_CTX md_ctx;
+ if (EVP_DigestVerifyInitFromAlgorithm(md_ctx.get(), algor.get(),
+ pkey.get())) {
+ fprintf(stderr, "Unexpectedly processed bad signature parameters\n");
+ return false;
+ }
+ ERR_clear_error();
+ return true;
+}
+
+static bool TestValidPrivateKey(const uint8_t *input, size_t input_len,
+ int expected_id) {
const uint8_t *p = input;
ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, input_len));
if (!pkey || p != input + input_len) {
@@ -536,6 +695,42 @@ static bool Testd2i_AutoPrivateKey(const uint8_t *input, size_t input_len,
return true;
}
+static bool Testd2i_AutoPrivateKey() {
+ if (!TestValidPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
+ EVP_PKEY_RSA)) {
+ fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
+ return false;
+ }
+
+ if (!TestValidPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
+ EVP_PKEY_RSA)) {
+ fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
+ return false;
+ }
+
+ if (!TestValidPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
+ EVP_PKEY_EC)) {
+ fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
+ return false;
+ }
+
+ if (!TestValidPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
+ EVP_PKEY_DSA)) {
+ fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
+ return false;
+ }
+
+ const uint8_t *p = kInvalidPrivateKey;
+ ScopedEVP_PKEY pkey(d2i_AutoPrivateKey(NULL, &p, sizeof(kInvalidPrivateKey)));
+ if (pkey) {
+ fprintf(stderr, "Parsed invalid private key\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ return true;
+}
+
// TestEVP_PKCS82PKEY tests loading a bad key in PKCS8 format.
static bool TestEVP_PKCS82PKEY(void) {
const uint8_t *derp = kExampleBadECKeyDER;
@@ -602,7 +797,7 @@ static bool Testd2i_PrivateKey(void) {
// Copy the input into a |malloc|'d vector to flag memory errors.
std::vector<uint8_t> copy(kExampleBadECKeyDER2, kExampleBadECKeyDER2 +
sizeof(kExampleBadECKeyDER2));
- derp = bssl::vector_data(&copy);
+ derp = copy.data();
pkey.reset(d2i_PrivateKey(EVP_PKEY_EC, nullptr, &derp, copy.size()));
if (pkey) {
fprintf(stderr, "Imported invalid EC key #2.\n");
@@ -641,30 +836,14 @@ int main(void) {
return 1;
}
- if (!Testd2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER),
- EVP_PKEY_RSA)) {
- fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n");
- ERR_print_errors_fp(stderr);
- return 1;
- }
-
- if (!Testd2i_AutoPrivateKey(kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8),
- EVP_PKEY_RSA)) {
- fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n");
+ if (!TestBadPSSParameters()) {
+ fprintf(stderr, "TestBadPSSParameters failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
- if (!Testd2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER),
- EVP_PKEY_EC)) {
- fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n");
- ERR_print_errors_fp(stderr);
- return 1;
- }
-
- if (!Testd2i_AutoPrivateKey(kExampleDSAKeyDER, sizeof(kExampleDSAKeyDER),
- EVP_PKEY_DSA)) {
- fprintf(stderr, "d2i_AutoPrivateKey(kExampleDSAKeyDER) failed\n");
+ if (!Testd2i_AutoPrivateKey()) {
+ fprintf(stderr, "Testd2i_AutoPrivateKey failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc
index c7ac908..7fedc15 100644
--- a/src/crypto/evp/evp_test.cc
+++ b/src/crypto/evp/evp_test.cc
@@ -78,7 +78,6 @@
#include "../test/file_test.h"
#include "../test/scoped_types.h"
-#include "../test/stl_compat.h"
// evp_test dispatches between multiple test types. PrivateKey tests take a key
@@ -179,8 +178,8 @@ static bool TestEVP(FileTest *t, void *arg) {
}
if (t->GetType() == "Verify") {
- if (!EVP_PKEY_verify(ctx.get(), bssl::vector_data(&output), output.size(),
- bssl::vector_data(&input), input.size())) {
+ if (!EVP_PKEY_verify(ctx.get(), output.data(), output.size(), input.data(),
+ input.size())) {
// ECDSA sometimes doesn't push an error code. Push one on the error queue
// so it's distinguishable from other errors.
OPENSSL_PUT_ERROR(USER, ERR_R_EVP_LIB);
@@ -191,18 +190,15 @@ static bool TestEVP(FileTest *t, void *arg) {
size_t len;
std::vector<uint8_t> actual;
- if (!key_op(ctx.get(), nullptr, &len, bssl::vector_data(&input),
- input.size())) {
+ if (!key_op(ctx.get(), nullptr, &len, input.data(), input.size())) {
return false;
}
actual.resize(len);
- if (!key_op(ctx.get(), bssl::vector_data(&actual), &len,
- bssl::vector_data(&input), input.size())) {
+ if (!key_op(ctx.get(), actual.data(), &len, input.data(), input.size())) {
return false;
}
actual.resize(len);
- if (!t->ExpectBytesEqual(bssl::vector_data(&output), output.size(),
- bssl::vector_data(&actual), len)) {
+ if (!t->ExpectBytesEqual(output.data(), output.size(), actual.data(), len)) {
return false;
}
return true;
diff --git a/src/crypto/evp/internal.h b/src/crypto/evp/internal.h
index 60881e3..aa52d53 100644
--- a/src/crypto/evp/internal.h
+++ b/src/crypto/evp/internal.h
@@ -263,6 +263,13 @@ struct evp_pkey_method_st {
int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
} /* EVP_PKEY_METHOD */;
+extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
+extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
+
+extern const EVP_PKEY_METHOD rsa_pkey_meth;
+extern const EVP_PKEY_METHOD ec_pkey_meth;
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/evp/p_ec_asn1.c b/src/crypto/evp/p_ec_asn1.c
index c583e0f..f40b976 100644
--- a/src/crypto/evp/p_ec_asn1.c
+++ b/src/crypto/evp/p_ec_asn1.c
@@ -337,23 +337,12 @@ static int int_ec_size(const EVP_PKEY *pkey) {
}
static int ec_bits(const EVP_PKEY *pkey) {
- BIGNUM *order = BN_new();
- const EC_GROUP *group;
- int ret;
-
- if (!order) {
+ const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec);
+ if (group == NULL) {
ERR_clear_error();
return 0;
}
- group = EC_KEY_get0_group(pkey->pkey.ec);
- if (!EC_GROUP_get_order(group, order, NULL)) {
- ERR_clear_error();
- return 0;
- }
-
- ret = BN_num_bits(order);
- BN_free(order);
- return ret;
+ return BN_num_bits(EC_GROUP_get0_order(group));
}
static int ec_missing_parameters(const EVP_PKEY *pkey) {
@@ -387,7 +376,6 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
const char *ecstr;
size_t buf_len = 0, i;
int ret = 0, reason = ERR_R_BIO_LIB;
- BIGNUM *order = NULL;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
const EC_POINT *public_key;
@@ -458,9 +446,8 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
if (!BIO_indent(bp, off, 128)) {
goto err;
}
- order = BN_new();
- if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
- BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
+ const BIGNUM *order = EC_GROUP_get0_order(group);
+ if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
goto err;
}
@@ -482,7 +469,6 @@ err:
OPENSSL_PUT_ERROR(EVP, reason);
}
OPENSSL_free(pub_key_bytes);
- BN_free(order);
BN_CTX_free(ctx);
OPENSSL_free(buffer);
return ret;
diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c
index cfecbfd..895d351 100644
--- a/src/crypto/evp/p_rsa.c
+++ b/src/crypto/evp/p_rsa.c
@@ -456,8 +456,6 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
}
OPENSSL_free(rctx->oaep_label);
if (p2 && p1 > 0) {
- /* TODO(fork): this seems wrong. Shouldn't it take a copy of the
- * buffer? */
rctx->oaep_label = p2;
rctx->oaep_labellen = p1;
} else {
diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c
index f60625b..db38d5c 100644
--- a/src/crypto/evp/p_rsa_asn1.c
+++ b/src/crypto/evp/p_rsa_asn1.c
@@ -303,7 +303,7 @@ static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) {
const uint8_t *p;
int plen;
- if (alg == NULL ||
+ if (alg == NULL || alg->parameter == NULL ||
OBJ_obj2nid(alg->algorithm) != NID_mgf1 ||
alg->parameter->type != V_ASN1_SEQUENCE) {
return NULL;