diff options
Diffstat (limited to 'src/crypto/evp')
-rw-r--r-- | src/crypto/evp/evp.c | 53 | ||||
-rw-r--r-- | src/crypto/evp/evp_ctx.c | 3 | ||||
-rw-r--r-- | src/crypto/evp/evp_extra_test.cc | 265 | ||||
-rw-r--r-- | src/crypto/evp/evp_test.cc | 14 | ||||
-rw-r--r-- | src/crypto/evp/internal.h | 7 | ||||
-rw-r--r-- | src/crypto/evp/p_ec_asn1.c | 24 | ||||
-rw-r--r-- | src/crypto/evp/p_rsa.c | 2 | ||||
-rw-r--r-- | src/crypto/evp/p_rsa_asn1.c | 2 |
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(©); + 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; |