diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp index 67db085f4ba6..e24957888a6e 100644 --- a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp +++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp @@ -12,11 +12,37 @@ #include "secder.h" #include "secerr.h" +namespace mozilla { namespace pkix { namespace test { + +// Ownership of privateKey is transfered. +TestKeyPair* CreateTestKeyPair(const ByteString& spki, + const ByteString& spk, + SECKEYPrivateKey* privateKey); + +} } } // namespace mozilla::pkix::test + using namespace mozilla; using namespace mozilla::pkix; using namespace mozilla::pkix::test; using namespace mozilla::test; +static TestKeyPair* +CreateTestKeyPairFromCert(CERTCertificate& cert) +{ + ScopedSECKEYPrivateKey privateKey(PK11_FindKeyByAnyCert(&cert, nullptr)); + if (!privateKey) { + return nullptr; + } + ByteString subjectPublicKeyInfo(cert.derPublicKey.data, + cert.derPublicKey.len); + SECItem subjectPublicKeyItem = cert.subjectPublicKeyInfo.subjectPublicKey; + DER_ConvertBitString(&subjectPublicKeyItem); // bits to bytes + ByteString subjectPublicKey(subjectPublicKeyItem.data, + subjectPublicKeyItem.len); + return CreateTestKeyPair(subjectPublicKeyInfo, subjectPublicKey, + privateKey.forget()); +} + SECItemArray * GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate *aCert, PLArenaPool *aArena, const char *aAdditionalCertName) @@ -166,8 +192,8 @@ GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate *aCert, if (!signerCert) { signerCert = CERT_DupCertificate(issuerCert.get()); } - context.signerPrivateKey = PK11_FindKeyByAnyCert(signerCert.get(), nullptr); - if (!context.signerPrivateKey) { + context.signerKeyPair = CreateTestKeyPairFromCert(*signerCert); + if (!context.signerKeyPair) { PrintPRError("PK11_FindKeyByAnyCert failed"); return nullptr; } diff --git a/security/pkix/test/gtest/pkixbuild_tests.cpp b/security/pkix/test/gtest/pkixbuild_tests.cpp index c5c9e2e5bf49..bec270047e4b 100644 --- a/security/pkix/test/gtest/pkixbuild_tests.cpp +++ b/security/pkix/test/gtest/pkixbuild_tests.cpp @@ -25,11 +25,8 @@ #include "cert.h" #include "nssgtest.h" #include "pkix/pkix.h" -#include "pkix/pkixnss.h" #include "pkixgtest.h" #include "pkixtestutil.h" -#include "prinit.h" -#include "secerr.h" using namespace mozilla::pkix; using namespace mozilla::pkix::test; @@ -42,8 +39,8 @@ static ByteString CreateCert(const char* issuerCN, const char* subjectCN, EndEntityOrCA endEntityOrCA, - /*optional*/ SECKEYPrivateKey* issuerKey, - /*out*/ ScopedSECKEYPrivateKey& subjectKey, + /*optional*/ TestKeyPair* issuerKey, + /*out*/ ScopedTestKeyPair& subjectKey, /*out*/ ScopedCERTCertificate* subjectCert = nullptr) { static long serialNumberValue = 0; @@ -196,7 +193,7 @@ private: ScopedCERTCertificate certChainTail[7]; public: - ScopedSECKEYPrivateKey leafCAKey; + ScopedTestKeyPair leafCAKey; CERTCertificate* GetLeafCACert() const { return certChainTail[MOZILLA_PKIX_ARRAY_LENGTH(certChainTail) - 1].get(); @@ -238,11 +235,11 @@ TEST_F(pkixbuild, MaxAcceptableCertChainLength) } { - ScopedSECKEYPrivateKey privateKey; + ScopedTestKeyPair unusedKeyPair; ScopedCERTCertificate cert; ByteString certDER(CreateCert("CA7", "Direct End-Entity", EndEntityOrCA::MustBeEndEntity, - trustDomain.leafCAKey.get(), privateKey)); + trustDomain.leafCAKey.get(), unusedKeyPair)); ASSERT_NE(ENCODING_FAILED, certDER); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); @@ -259,7 +256,7 @@ TEST_F(pkixbuild, MaxAcceptableCertChainLength) TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) { static char const* const caCertName = "CA Too Far"; - ScopedSECKEYPrivateKey caPrivateKey; + ScopedTestKeyPair caKeyPair; // We need a CERTCertificate for caCert so that the trustdomain's FindIssuer // method can find it through the NSS cert DB. @@ -267,7 +264,7 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) { ByteString certDER(CreateCert("CA7", caCertName, EndEntityOrCA::MustBeCA, - trustDomain.leafCAKey.get(), caPrivateKey, + trustDomain.leafCAKey.get(), caKeyPair, &caCert)); ASSERT_NE(ENCODING_FAILED, certDER); Input certDERInput; @@ -282,10 +279,10 @@ TEST_F(pkixbuild, BeyondMaxAcceptableCertChainLength) } { - ScopedSECKEYPrivateKey privateKey; + ScopedTestKeyPair unusedKeyPair; ByteString certDER(CreateCert(caCertName, "End-Entity Too Far", EndEntityOrCA::MustBeEndEntity, - caPrivateKey.get(), privateKey)); + caKeyPair.get(), unusedKeyPair)); ASSERT_NE(ENCODING_FAILED, certDER); Input certDERInput; ASSERT_EQ(Success, certDERInput.Init(certDER.data(), certDER.length())); diff --git a/security/pkix/test/gtest/pkixcert_extension_tests.cpp b/security/pkix/test/gtest/pkixcert_extension_tests.cpp index fb7a80821aa7..c346762d40b1 100644 --- a/security/pkix/test/gtest/pkixcert_extension_tests.cpp +++ b/security/pkix/test/gtest/pkixcert_extension_tests.cpp @@ -26,7 +26,6 @@ #include "pkix/pkix.h" #include "pkix/pkixnss.h" #include "pkixtestutil.h" -#include "secerr.h" using namespace mozilla::pkix; using namespace mozilla::pkix::test; @@ -35,7 +34,7 @@ using namespace mozilla::pkix::test; static ByteString CreateCert(const char* subjectCN, const ByteString* extensions, // empty-string-terminated array - /*out*/ ScopedSECKEYPrivateKey& subjectKey) + /*out*/ ScopedTestKeyPair& subjectKey) { static long serialNumberValue = 0; ++serialNumberValue; @@ -58,7 +57,7 @@ CreateCert(const char* subjectCN, static ByteString CreateCert(const char* subjectStr, const ByteString& extension, - /*out*/ ScopedSECKEYPrivateKey& subjectKey) + /*out*/ ScopedTestKeyPair& subjectKey) { const ByteString extensions[] = { extension, ByteString() }; return CreateCert(subjectStr, extensions, subjectKey); @@ -145,7 +144,7 @@ TEST_F(pkixcert_extension, UnknownCriticalExtension) unknownCriticalExtension(unknownCriticalExtensionBytes, sizeof(unknownCriticalExtensionBytes)); const char* certCN = "Cert With Unknown Critical Extension"; - ScopedSECKEYPrivateKey key; + ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, unknownCriticalExtension, key)); ASSERT_NE(ENCODING_FAILED, cert); Input certInput; @@ -175,7 +174,7 @@ TEST_F(pkixcert_extension, UnknownNonCriticalExtension) unknownNonCriticalExtension(unknownNonCriticalExtensionBytes, sizeof(unknownNonCriticalExtensionBytes)); const char* certCN = "Cert With Unknown NonCritical Extension"; - ScopedSECKEYPrivateKey key; + ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, unknownNonCriticalExtension, key)); ASSERT_NE(ENCODING_FAILED, cert); Input certInput; @@ -206,7 +205,7 @@ TEST_F(pkixcert_extension, WrongOIDCriticalExtension) wrongOIDCriticalExtension(wrongOIDCriticalExtensionBytes, sizeof(wrongOIDCriticalExtensionBytes)); const char* certCN = "Cert With Critical Wrong OID Extension"; - ScopedSECKEYPrivateKey key; + ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, wrongOIDCriticalExtension, key)); ASSERT_NE(ENCODING_FAILED, cert); Input certInput; @@ -239,7 +238,7 @@ TEST_F(pkixcert_extension, CriticalAIAExtension) criticalAIAExtension(criticalAIAExtensionBytes, sizeof(criticalAIAExtensionBytes)); const char* certCN = "Cert With Critical AIA Extension"; - ScopedSECKEYPrivateKey key; + ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, criticalAIAExtension, key)); ASSERT_NE(ENCODING_FAILED, cert); Input certInput; @@ -269,7 +268,7 @@ TEST_F(pkixcert_extension, UnknownCriticalCEExtension) unknownCriticalCEExtension(unknownCriticalCEExtensionBytes, sizeof(unknownCriticalCEExtensionBytes)); const char* certCN = "Cert With Unknown Critical id-ce Extension"; - ScopedSECKEYPrivateKey key; + ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, unknownCriticalCEExtension, key)); ASSERT_NE(ENCODING_FAILED, cert); Input certInput; @@ -299,7 +298,7 @@ TEST_F(pkixcert_extension, KnownCriticalCEExtension) criticalCEExtension(criticalCEExtensionBytes, sizeof(criticalCEExtensionBytes)); const char* certCN = "Cert With Known Critical id-ce Extension"; - ScopedSECKEYPrivateKey key; + ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, criticalCEExtension, key)); ASSERT_NE(ENCODING_FAILED, cert); Input certInput; @@ -328,7 +327,7 @@ TEST_F(pkixcert_extension, DuplicateSubjectAltName) static const ByteString DER(DER_BYTES, sizeof(DER_BYTES)); static const ByteString extensions[] = { DER, DER, ByteString() }; static const char* certCN = "Cert With Duplicate subjectAltName"; - ScopedSECKEYPrivateKey key; + ScopedTestKeyPair key; ByteString cert(CreateCert(certCN, extensions, key)); ASSERT_NE(ENCODING_FAILED, cert); Input certInput; diff --git a/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp b/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp index c52eb897189f..c1596713b9f7 100644 --- a/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp +++ b/security/pkix/test/gtest/pkixocsp_CreateEncodedOCSPRequest_tests.cpp @@ -23,11 +23,10 @@ */ #include "nssgtest.h" -#include "pkix/pkix.h" #include "pkix/pkixnss.h" +#include "pkix/pkix.h" #include "pkixder.h" #include "pkixtestutil.h" -#include "secerr.h" using namespace mozilla::pkix; using namespace mozilla::pkix::test; @@ -90,15 +89,9 @@ protected: issuerDER = CNToDERName(issuerASCII); ASSERT_NE(ENCODING_FAILED, issuerDER); - ScopedSECKEYPublicKey issuerPublicKey; - ScopedSECKEYPrivateKey issuerPrivateKey; - ASSERT_EQ(Success, GenerateKeyPair(issuerPublicKey, issuerPrivateKey)); - - ScopedSECItem issuerSPKIOriginal( - SECKEY_EncodeDERSubjectPublicKeyInfo(issuerPublicKey.get())); - ASSERT_TRUE(issuerSPKIOriginal); - - issuerSPKI.assign(issuerSPKIOriginal->data, issuerSPKIOriginal->len); + ScopedTestKeyPair keyPair(GenerateKeyPair()); + ASSERT_TRUE(keyPair); + issuerSPKI = keyPair->subjectPublicKeyInfo; } CreateEncodedOCSPRequestTrustDomain trustDomain; diff --git a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp index 362a11814ab9..e035556515d5 100644 --- a/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp +++ b/security/pkix/test/gtest/pkixocsp_VerifyEncodedOCSPResponse.cpp @@ -22,14 +22,10 @@ * limitations under the License. */ -#include "nss.h" #include "nssgtest.h" #include "pkix/pkix.h" -#include "pkix/pkixnss.h" #include "pkixgtest.h" #include "pkixtestutil.h" -#include "prinit.h" -#include "secerr.h" using namespace mozilla::pkix; using namespace mozilla::pkix::test; @@ -107,17 +103,8 @@ class pkixocsp_VerifyEncodedResponse : public NSSTest public: static bool SetUpTestCaseInner() { - ScopedSECKEYPublicKey rootPublicKey; - if (GenerateKeyPair(rootPublicKey, rootPrivateKey) != Success) { - return false; - } - ScopedSECItem rootSPKIItem( - SECKEY_EncodeDERSubjectPublicKeyInfo(rootPublicKey.get())); - if (!rootSPKIItem) { - return false; - } - rootSPKI.assign(rootSPKIItem->data, rootSPKIItem->len); - return true; + rootKeyPair = GenerateKeyPair(); + return rootKeyPair.get() != nullptr; } static void SetUpTestCase() @@ -153,7 +140,9 @@ public: } Input rootSPKIDER; - if (rootSPKIDER.Init(rootSPKI.data(), rootSPKI.length()) != Success) { + if (rootSPKIDER.Init(rootKeyPair->subjectPublicKeyInfo.data(), + rootKeyPair->subjectPublicKeyInfo.length()) + != Success) { abort(); } endEntityCertID = new (std::nothrow) CertID(rootNameDERInput, rootSPKIDER, @@ -163,20 +152,18 @@ public: } } - static ScopedSECKEYPrivateKey rootPrivateKey; - static ByteString rootSPKI; + static ScopedTestKeyPair rootKeyPair; static long rootIssuedCount; OCSPTestTrustDomain trustDomain; + // endEntityCertID references rootKeyPair, rootNameDER, and serialNumberDER. ByteString rootNameDER; ByteString serialNumberDER; - // endEntityCertID references rootSPKI, rootNameDER, and serialNumberDER. + // endEntityCertID references rootKeyPair, rootNameDER, and serialNumberDER. ScopedPtr endEntityCertID; }; -/*static*/ ScopedSECKEYPrivateKey - pkixocsp_VerifyEncodedResponse::rootPrivateKey; -/*static*/ ByteString pkixocsp_VerifyEncodedResponse::rootSPKI; +/*static*/ ScopedTestKeyPair pkixocsp_VerifyEncodedResponse::rootKeyPair; /*static*/ long pkixocsp_VerifyEncodedResponse::rootIssuedCount = 0; /////////////////////////////////////////////////////////////////////////////// @@ -263,7 +250,7 @@ public: OCSPResponseContext::CertStatus certStatus, const CertID& certID, /*optional*/ const char* signerName, - const ScopedSECKEYPrivateKey& signerPrivateKey, + const TestKeyPair& signerKeyPair, time_t producedAt, time_t thisUpdate, /*optional*/ const time_t* nextUpdate, /*optional*/ const ByteString* certs = nullptr) @@ -273,8 +260,8 @@ public: context.signerNameDER = CNToDERName(signerName); EXPECT_NE(ENCODING_FAILED, context.signerNameDER); } - context.signerPrivateKey = SECKEY_CopyPrivateKey(signerPrivateKey.get()); - EXPECT_TRUE(context.signerPrivateKey); + context.signerKeyPair = signerKeyPair.Clone(); + EXPECT_TRUE(context.signerKeyPair); context.responseStatus = OCSPResponseContext::successful; context.producedAt = producedAt; context.certs = certs; @@ -293,7 +280,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_successful, good_byKey) ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, byKey, - rootPrivateKey, oneDayBeforeNow, + *rootKeyPair, oneDayBeforeNow, oneDayBeforeNow, &oneDayAfterNow)); Input response; ASSERT_EQ(Success, @@ -311,7 +298,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_successful, good_byName) ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, rootName, - rootPrivateKey, oneDayBeforeNow, + *rootKeyPair, oneDayBeforeNow, oneDayBeforeNow, &oneDayAfterNow)); Input response; ASSERT_EQ(Success, @@ -329,7 +316,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_successful, good_byKey_without_nextUpdate) ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, byKey, - rootPrivateKey, oneDayBeforeNow, + *rootKeyPair, oneDayBeforeNow, oneDayBeforeNow, nullptr)); Input response; ASSERT_EQ(Success, @@ -347,7 +334,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_successful, revoked) ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::revoked, *endEntityCertID, byKey, - rootPrivateKey, oneDayBeforeNow, + *rootKeyPair, oneDayBeforeNow, oneDayBeforeNow, &oneDayAfterNow)); Input response; ASSERT_EQ(Success, @@ -365,7 +352,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_successful, unknown) ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::unknown, *endEntityCertID, byKey, - rootPrivateKey, oneDayBeforeNow, + *rootKeyPair, oneDayBeforeNow, oneDayBeforeNow, &oneDayAfterNow)); Input response; ASSERT_EQ(Success, @@ -415,12 +402,12 @@ protected: : ByteString(), ByteString() }; - ScopedSECKEYPrivateKey signerPrivateKey; + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( ++rootIssuedCount, rootName, oneDayBeforeNow, oneDayAfterNow, certSubjectName, signerEKUDER ? extensions : nullptr, - rootPrivateKey.get(), signerPrivateKey)); + rootKeyPair.get(), signerKeyPair)); EXPECT_NE(ENCODING_FAILED, signerDER); if (signerDEROut) { *signerDEROut = signerDER; @@ -433,7 +420,7 @@ protected: } ByteString certs[] = { signerDER, ByteString() }; return CreateEncodedOCSPSuccessfulResponse(certStatus, *endEntityCertID, - signerName, signerPrivateKey, + signerName, *signerKeyPair, oneDayBeforeNow, oneDayBeforeNow, &oneDayAfterNow, certs); @@ -445,8 +432,8 @@ protected: time_t notAfter, const char* subject, /*optional*/ const ByteString* extensions, - /*optional*/ SECKEYPrivateKey* signerKey, - /*out*/ ScopedSECKEYPrivateKey& privateKey) + /*optional*/ TestKeyPair* signerKeyPair, + /*out*/ ScopedTestKeyPair& keyPair) { ByteString serialNumberDER(CreateEncodedSerialNumber(serialNumber)); if (serialNumberDER == ENCODING_FAILED) { @@ -465,9 +452,9 @@ protected: sha256WithRSAEncryption, serialNumberDER, issuerDER, notBefore, notAfter, subjectDER, extensions, - signerKey, + signerKeyPair, SignatureAlgorithm::rsa_pkcs1_with_sha256, - privateKey); + keyPair); } static const Input OCSPSigningEKUDER; @@ -513,14 +500,13 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_byName) TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_byKey_missing_signer) { - ScopedSECKEYPublicKey missingSignerPublicKey; - ScopedSECKEYPrivateKey missingSignerPrivateKey; - ASSERT_EQ(Success, GenerateKeyPair(missingSignerPublicKey, - missingSignerPrivateKey)); + ScopedTestKeyPair missingSignerKeyPair(GenerateKeyPair()); + ASSERT_TRUE(missingSignerKeyPair); + ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, byKey, - missingSignerPrivateKey, oneDayBeforeNow, + *missingSignerKeyPair, oneDayBeforeNow, oneDayBeforeNow, nullptr)); Input response; ASSERT_EQ(Success, @@ -536,14 +522,12 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_byName_missing_signer) { - ScopedSECKEYPublicKey missingSignerPublicKey; - ScopedSECKEYPrivateKey missingSignerPrivateKey; - ASSERT_EQ(Success, GenerateKeyPair(missingSignerPublicKey, - missingSignerPrivateKey)); + ScopedTestKeyPair missingSignerKeyPair(GenerateKeyPair()); + ASSERT_TRUE(missingSignerKeyPair); ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, - "missing", missingSignerPrivateKey, + "missing", *missingSignerKeyPair, oneDayBeforeNow, oneDayBeforeNow, nullptr)); Input response; ASSERT_EQ(Success, @@ -566,20 +550,20 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_expired) ByteString() }; - ScopedSECKEYPrivateKey signerPrivateKey; + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( ++rootIssuedCount, rootName, now - (10 * Time::ONE_DAY_IN_SECONDS), now - (2 * Time::ONE_DAY_IN_SECONDS), - signerName, extensions, rootPrivateKey.get(), - signerPrivateKey)); + signerName, extensions, rootKeyPair.get(), + signerKeyPair)); ASSERT_NE(ENCODING_FAILED, signerDER); ByteString certs[] = { signerDER, ByteString() }; ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, - signerName, signerPrivateKey, oneDayBeforeNow, + signerName, *signerKeyPair, oneDayBeforeNow, oneDayBeforeNow, &oneDayAfterNow, certs)); Input response; ASSERT_EQ(Success, @@ -601,20 +585,20 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_future) ByteString() }; - ScopedSECKEYPrivateKey signerPrivateKey; + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( ++rootIssuedCount, rootName, now + (2 * Time::ONE_DAY_IN_SECONDS), now + (10 * Time::ONE_DAY_IN_SECONDS), - signerName, extensions, rootPrivateKey.get(), - signerPrivateKey)); + signerName, extensions, rootKeyPair.get(), + signerKeyPair)); ASSERT_NE(ENCODING_FAILED, signerDER); ByteString certs[] = { signerDER, ByteString() }; ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, - signerName, signerPrivateKey, oneDayBeforeNow, + signerName, *signerKeyPair, oneDayBeforeNow, oneDayBeforeNow, &oneDayAfterNow, certs)); Input response; ASSERT_EQ(Success, @@ -694,9 +678,8 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_unknown_issuer) static const char* signerName = "good_indirect_unknown_issuer OCSP signer"; // unknown issuer - ScopedSECKEYPublicKey unknownPublicKey; - ScopedSECKEYPrivateKey unknownPrivateKey; - ASSERT_EQ(Success, GenerateKeyPair(unknownPublicKey, unknownPrivateKey)); + ScopedTestKeyPair unknownKeyPair(GenerateKeyPair()); + ASSERT_TRUE(unknownKeyPair); // Delegated responder cert signed by unknown issuer const ByteString extensions[] = { @@ -704,11 +687,11 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_unknown_issuer) ExtensionCriticality::NotCritical), ByteString() }; - ScopedSECKEYPrivateKey signerPrivateKey; + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( 1, subCAName, oneDayBeforeNow, oneDayAfterNow, - signerName, extensions, unknownPrivateKey.get(), - signerPrivateKey)); + signerName, extensions, unknownKeyPair.get(), + signerKeyPair)); ASSERT_NE(ENCODING_FAILED, signerDER); // OCSP response signed by that delegated responder @@ -716,7 +699,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, good_unknown_issuer) ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, - signerName, signerPrivateKey, oneDayBeforeNow, + signerName, *signerKeyPair, oneDayBeforeNow, oneDayBeforeNow, &oneDayAfterNow, certs)); Input response; ASSERT_EQ(Success, @@ -743,12 +726,12 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, CreateEncodedBasicConstraints(true, 0, ExtensionCriticality::NotCritical), ByteString() }; - ScopedSECKEYPrivateKey subCAPrivateKey; + ScopedTestKeyPair subCAKeyPair; ByteString subCADER(CreateEncodedCertificate( ++rootIssuedCount, rootName, oneDayBeforeNow, oneDayAfterNow, - subCAName, subCAExtensions, rootPrivateKey.get(), - subCAPrivateKey)); + subCAName, subCAExtensions, rootKeyPair.get(), + subCAKeyPair)); ASSERT_NE(ENCODING_FAILED, subCADER); // Delegated responder cert signed by that sub-CA @@ -757,11 +740,11 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, ExtensionCriticality::NotCritical), ByteString(), }; - ScopedSECKEYPrivateKey signerPrivateKey; + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( 1, subCAName, oneDayBeforeNow, oneDayAfterNow, - signerName, extensions, subCAPrivateKey.get(), - signerPrivateKey)); + signerName, extensions, subCAKeyPair.get(), + signerKeyPair)); ASSERT_NE(ENCODING_FAILED, signerDER); // OCSP response signed by the delegated responder issued by the sub-CA @@ -770,7 +753,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, - signerName, signerPrivateKey, oneDayBeforeNow, + signerName, *signerKeyPair, oneDayBeforeNow, oneDayBeforeNow, &oneDayAfterNow, certs)); Input response; ASSERT_EQ(Success, @@ -797,12 +780,12 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, CreateEncodedBasicConstraints(true, 0, ExtensionCriticality::NotCritical), ByteString() }; - ScopedSECKEYPrivateKey subCAPrivateKey; + ScopedTestKeyPair subCAKeyPair; ByteString subCADER(CreateEncodedCertificate(++rootIssuedCount, rootName, oneDayBeforeNow, oneDayAfterNow, subCAName, subCAExtensions, - rootPrivateKey.get(), - subCAPrivateKey)); + rootKeyPair.get(), + subCAKeyPair)); ASSERT_NE(ENCODING_FAILED, subCADER); // Delegated responder cert signed by that sub-CA @@ -811,11 +794,11 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, ExtensionCriticality::NotCritical), ByteString() }; - ScopedSECKEYPrivateKey signerPrivateKey; + ScopedTestKeyPair signerKeyPair; ByteString signerDER(CreateEncodedCertificate( 1, subCAName, oneDayBeforeNow, oneDayAfterNow, - signerName, extensions, subCAPrivateKey.get(), - signerPrivateKey)); + signerName, extensions, subCAKeyPair.get(), + signerKeyPair)); ASSERT_NE(ENCODING_FAILED, signerDER); // OCSP response signed by the delegated responder issued by the sub-CA @@ -824,7 +807,7 @@ TEST_F(pkixocsp_VerifyEncodedResponse_DelegatedResponder, ByteString responseString( CreateEncodedOCSPSuccessfulResponse( OCSPResponseContext::good, *endEntityCertID, - signerName, signerPrivateKey, oneDayBeforeNow, + signerName, *signerKeyPair, oneDayBeforeNow, oneDayBeforeNow, &oneDayAfterNow, certs)); Input response; ASSERT_EQ(Success, diff --git a/security/pkix/test/lib/moz.build b/security/pkix/test/lib/moz.build index 9374ea433027..ed6742cb3ffb 100644 --- a/security/pkix/test/lib/moz.build +++ b/security/pkix/test/lib/moz.build @@ -21,6 +21,7 @@ # limitations under the License. SOURCES += [ + 'pkixtestnss.cpp', 'pkixtestutil.cpp', ] diff --git a/security/pkix/test/lib/pkixtestnss.cpp b/security/pkix/test/lib/pkixtestnss.cpp new file mode 100644 index 000000000000..048519700876 --- /dev/null +++ b/security/pkix/test/lib/pkixtestnss.cpp @@ -0,0 +1,165 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This code is made available to you under your choice of the following sets + * of licensing terms: + */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +/* Copyright 2013 Mozilla Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "pkixtestutil.h" + +#include "cryptohi.h" +#include "keyhi.h" +#include "pk11pub.h" +#include "pkix/pkixnss.h" +#include "secerr.h" + +namespace mozilla { namespace pkix { namespace test { + +namespace { + +typedef ScopedPtr + ScopedSECKEYPublicKey; +typedef ScopedPtr + ScopedSECKEYPrivateKey; + +class NSSTestKeyPair : public TestKeyPair +{ +public: + // NSSTestKeyPair takes ownership of privateKey. + NSSTestKeyPair(const ByteString& spki, + const ByteString& spk, + SECKEYPrivateKey* privateKey) + : TestKeyPair(spki, spk) + , privateKey(privateKey) + { + } + + virtual Result SignData(const ByteString& tbs, + SignatureAlgorithm signatureAlgorithm, + /*out*/ ByteString& signature) const + { + SECOidTag signatureAlgorithmOidTag; + switch (signatureAlgorithm) { + case SignatureAlgorithm::rsa_pkcs1_with_sha256: + signatureAlgorithmOidTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; + break; + default: + return Result::FATAL_ERROR_INVALID_ARGS; + } + + SECItem signatureItem; + if (SEC_SignData(&signatureItem, tbs.data(), tbs.length(), + privateKey.get(), signatureAlgorithmOidTag) + != SECSuccess) { + return MapPRErrorCodeToResult(PR_GetError()); + } + signature.assign(signatureItem.data, signatureItem.len); + SECITEM_FreeItem(&signatureItem, false); + return Success; + } + + virtual TestKeyPair* Clone() const + { + ScopedSECKEYPrivateKey + privateKeyCopy(SECKEY_CopyPrivateKey(privateKey.get())); + if (!privateKeyCopy) { + return nullptr; + } + return new (std::nothrow) NSSTestKeyPair(subjectPublicKeyInfo, + subjectPublicKey, + privateKeyCopy.release()); + } + +private: + ScopedSECKEYPrivateKey privateKey; +}; + +} // unnamed namespace + +// This private function is also used by Gecko's PSM test framework +// (OCSPCommon.cpp). +// +// Ownership of privateKey is transfered. +TestKeyPair* CreateTestKeyPair(const ByteString& spki, + const ByteString& spk, + SECKEYPrivateKey* privateKey) +{ + return new (std::nothrow) NSSTestKeyPair(spki, spk, privateKey); +} + +TestKeyPair* +GenerateKeyPair() +{ + ScopedPtr slot(PK11_GetInternalSlot()); + if (!slot) { + return nullptr; + } + + // Bug 1012786: PK11_GenerateKeyPair can fail if there is insufficient + // entropy to generate a random key. Attempting to add some entropy and + // retrying appears to solve this issue. + for (uint32_t retries = 0; retries < 10; retries++) { + PK11RSAGenParams params; + params.keySizeInBits = 2048; + params.pe = 3; + SECKEYPublicKey* publicKeyTemp = nullptr; + ScopedSECKEYPrivateKey + privateKey(PK11_GenerateKeyPair(slot.get(), CKM_RSA_PKCS_KEY_PAIR_GEN, + ¶ms, &publicKeyTemp, false, true, + nullptr)); + ScopedSECKEYPublicKey publicKey(publicKeyTemp); + if (privateKey) { + ScopedSECItem + spkiDER(SECKEY_EncodeDERSubjectPublicKeyInfo(publicKey.get())); + if (!spkiDER) { + return nullptr; + } + ScopedPtr + spki(SECKEY_CreateSubjectPublicKeyInfo(publicKey.get())); + if (!spki) { + return nullptr; + } + SECItem spkDER = spki->subjectPublicKey; + DER_ConvertBitString(&spkDER); // bits to bytes + return CreateTestKeyPair(ByteString(spkiDER->data, spkiDER->len), + ByteString(spkDER.data, spkDER.len), + privateKey.release()); + } + + assert(!publicKeyTemp); + + if (PR_GetError() != SEC_ERROR_PKCS11_FUNCTION_FAILED) { + break; + } + + // Since these keys are only for testing, we don't need them to be good, + // random keys. + // https://xkcd.com/221/ + static const uint8_t RANDOM_NUMBER[] = { 4, 4, 4, 4, 4, 4, 4, 4 }; + if (PK11_RandomUpdate((void*) &RANDOM_NUMBER, + sizeof(RANDOM_NUMBER)) != SECSuccess) { + break; + } + } + + return nullptr; +} + +} } } // namespace mozilla::pkix::test diff --git a/security/pkix/test/lib/pkixtestutil.cpp b/security/pkix/test/lib/pkixtestutil.cpp index e375aa38e0a5..904e4cfe5e7a 100644 --- a/security/pkix/test/lib/pkixtestutil.cpp +++ b/security/pkix/test/lib/pkixtestutil.cpp @@ -30,15 +30,10 @@ #include #include -#include "cert.h" -#include "cryptohi.h" -#include "hasht.h" -#include "pk11pub.h" #include "pkix/pkixnss.h" #include "pkixder.h" #include "pkixutil.h" -#include "prinit.h" -#include "secerr.h" +#include "prprf.h" using namespace std; @@ -153,17 +148,17 @@ static ByteString ResponseBytes(OCSPResponseContext& context); static ByteString BasicOCSPResponse(OCSPResponseContext& context); static ByteString ResponseData(OCSPResponseContext& context); static ByteString ResponderID(OCSPResponseContext& context); -static ByteString KeyHash(OCSPResponseContext& context); +static ByteString KeyHash(const ByteString& subjectPublicKeyInfo); static ByteString SingleResponse(OCSPResponseContext& context); static ByteString CertID(OCSPResponseContext& context); static ByteString CertStatus(OCSPResponseContext& context); static ByteString -HashedOctetString(const SECItem& bytes) +HashedOctetString(const ByteString& bytes) { uint8_t hashBuf[TrustDomain::DIGEST_LENGTH]; Input input; - if (input.Init(bytes.data, bytes.len) != Success) { + if (input.Init(bytes.data(), bytes.length()) != Success) { return ENCODING_FAILED; } if (DigestBuf(input, hashBuf, sizeof(hashBuf)) != Success) { @@ -172,15 +167,6 @@ HashedOctetString(const SECItem& bytes) return TLV(der::OCTET_STRING, ByteString(hashBuf, sizeof(hashBuf))); } -static ByteString -KeyHashHelper(const CERTSubjectPublicKeyInfo* spki) -{ - // We only need a shallow copy here. - SECItem spk = spki->subjectPublicKey; - DER_ConvertBitString(&spk); // bits to bytes - return HashedOctetString(spk); -} - static ByteString BitString(const ByteString& rawBytes, bool corrupt) { @@ -361,20 +347,18 @@ YMDHMS(int16_t year, int16_t month, int16_t day, static ByteString SignedData(const ByteString& tbsData, - SECKEYPrivateKey* privKey, + TestKeyPair& keyPair, SignatureAlgorithm signatureAlgorithm, bool corrupt, /*optional*/ const ByteString* certs) { - assert(privKey); - if (!privKey) { - return ENCODING_FAILED; - } + ByteString signature; + if (keyPair.SignData(tbsData, signatureAlgorithm, signature) != Success) { + return ENCODING_FAILED; + } - SECOidTag signatureAlgorithmOidTag; ByteString signatureAlgorithmDER; switch (signatureAlgorithm) { case SignatureAlgorithm::rsa_pkcs1_with_sha256: - signatureAlgorithmOidTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; signatureAlgorithmDER.assign(alg_sha256WithRSAEncryption, sizeof(alg_sha256WithRSAEncryption)); break; @@ -382,17 +366,9 @@ SignedData(const ByteString& tbsData, return ENCODING_FAILED; } - SECItem signature; - if (SEC_SignData(&signature, tbsData.data(), tbsData.length(), privKey, - signatureAlgorithmOidTag) != SECSuccess) - { - return ENCODING_FAILED; - } // TODO: add ability to have signatures of bit length not divisible by 8, // resulting in unused bits in the bitstring encoding - ByteString signatureNested(BitString(ByteString(signature.data, signature.len), - corrupt)); - SECITEM_FreeItem(&signature, false); + ByteString signatureNested(BitString(signature, corrupt)); if (signatureNested == ENCODING_FAILED) { return ENCODING_FAILED; } @@ -487,55 +463,6 @@ MaybeLogOutput(const ByteString& result, const char* suffix) } } -/////////////////////////////////////////////////////////////////////////////// -// Key Pairs - -Result -GenerateKeyPair(/*out*/ ScopedSECKEYPublicKey& publicKey, - /*out*/ ScopedSECKEYPrivateKey& privateKey) -{ - ScopedPtr slot(PK11_GetInternalSlot()); - if (!slot) { - return MapPRErrorCodeToResult(PR_GetError()); - } - - // Bug 1012786: PK11_GenerateKeyPair can fail if there is insufficient - // entropy to generate a random key. Attempting to add some entropy and - // retrying appears to solve this issue. - for (uint32_t retries = 0; retries < 10; retries++) { - PK11RSAGenParams params; - params.keySizeInBits = 2048; - params.pe = 3; - SECKEYPublicKey* publicKeyTemp = nullptr; - privateKey = PK11_GenerateKeyPair(slot.get(), CKM_RSA_PKCS_KEY_PAIR_GEN, - ¶ms, &publicKeyTemp, false, true, - nullptr); - if (privateKey) { - publicKey = publicKeyTemp; - assert(publicKey); - return Success; - } - - assert(!publicKeyTemp); - - if (PR_GetError() != SEC_ERROR_PKCS11_FUNCTION_FAILED) { - break; - } - - // Since these keys are only for testing, we don't need them to be good, - // random keys. - // https://xkcd.com/221/ - static const uint8_t RANDOM_NUMBER[] = { 4, 4, 4, 4, 4, 4, 4, 4 }; - if (PK11_RandomUpdate((void*) &RANDOM_NUMBER, - sizeof(RANDOM_NUMBER)) != SECSuccess) { - break; - } - } - - return MapPRErrorCodeToResult(PR_GetError()); -} - - /////////////////////////////////////////////////////////////////////////////// // Certificates @@ -543,7 +470,7 @@ static ByteString TBSCertificate(long version, const ByteString& serialNumber, Input signature, const ByteString& issuer, time_t notBefore, time_t notAfter, const ByteString& subject, - const SECKEYPublicKey* subjectPublicKey, + const ByteString& subjectPublicKeyInfo, /*optional*/ const ByteString* extensions); // Certificate ::= SEQUENCE { @@ -557,30 +484,30 @@ CreateEncodedCertificate(long version, Input signature, time_t notBefore, time_t notAfter, const ByteString& subjectNameDER, /*optional*/ const ByteString* extensions, - /*optional*/ SECKEYPrivateKey* issuerPrivateKey, + /*optional*/ TestKeyPair* issuerKeyPair, SignatureAlgorithm signatureAlgorithm, - /*out*/ ScopedSECKEYPrivateKey& privateKeyResult) + /*out*/ ScopedTestKeyPair& keyPairResult) { - // It may be the case that privateKeyResult refers to the - // ScopedSECKEYPrivateKey that owns issuerPrivateKey; thus, we can't set - // privateKeyResult until after we're done with issuerPrivateKey. - ScopedSECKEYPublicKey publicKey; - ScopedSECKEYPrivateKey privateKeyTemp; - if (GenerateKeyPair(publicKey, privateKeyTemp) != Success) { + // It may be the case that privateKeyResult references the same TestKeyPair + // as issuerKeyPair. Thus, we can't set keyPairResult until after we're done + // with issuerKeyPair. + ScopedTestKeyPair subjectKeyPair(GenerateKeyPair()); + if (!subjectKeyPair) { return ENCODING_FAILED; } ByteString tbsCertificate(TBSCertificate(version, serialNumber, signature, issuerNameDER, notBefore, notAfter, subjectNameDER, - publicKey.get(), extensions)); + subjectKeyPair->subjectPublicKeyInfo, + extensions)); if (tbsCertificate == ENCODING_FAILED) { return ENCODING_FAILED; } ByteString result(SignedData(tbsCertificate, - issuerPrivateKey ? issuerPrivateKey - : privateKeyTemp.get(), + issuerKeyPair ? *issuerKeyPair + : *subjectKeyPair, signatureAlgorithm, false, nullptr)); if (result == ENCODING_FAILED) { return ENCODING_FAILED; @@ -588,7 +515,7 @@ CreateEncodedCertificate(long version, Input signature, MaybeLogOutput(result, "cert"); - privateKeyResult = privateKeyTemp.release(); + keyPairResult = subjectKeyPair.release(); return result; } @@ -612,14 +539,9 @@ TBSCertificate(long versionValue, const ByteString& serialNumber, Input signature, const ByteString& issuer, time_t notBeforeTime, time_t notAfterTime, const ByteString& subject, - const SECKEYPublicKey* subjectPublicKey, + const ByteString& subjectPublicKeyInfo, /*optional*/ const ByteString* extensions) { - assert(subjectPublicKey); - if (!subjectPublicKey) { - return ENCODING_FAILED; - } - ByteString value; if (versionValue != static_cast(der::Version::v1)) { @@ -664,15 +586,7 @@ TBSCertificate(long versionValue, value.append(subject); - // SubjectPublicKeyInfo ::= SEQUENCE { - // algorithm AlgorithmIdentifier, - // subjectPublicKey BIT STRING } - ScopedSECItem subjectPublicKeyInfo( - SECKEY_EncodeDERSubjectPublicKeyInfo(subjectPublicKey)); - if (!subjectPublicKeyInfo) { - return ENCODING_FAILED; - } - value.append(subjectPublicKeyInfo->data, subjectPublicKeyInfo->len); + value.append(subjectPublicKeyInfo); if (extensions) { ByteString extensionsValue; @@ -809,7 +723,7 @@ ByteString CreateEncodedOCSPResponse(OCSPResponseContext& context) { if (!context.skipResponseBytes) { - if (!context.signerPrivateKey) { + if (!context.signerKeyPair) { return ENCODING_FAILED; } } @@ -901,8 +815,7 @@ BasicOCSPResponse(OCSPResponseContext& context) } // TODO(bug 980538): certs - return SignedData(tbsResponseData, - context.signerPrivateKey.get(), + return SignedData(tbsResponseData, *context.signerKeyPair, SignatureAlgorithm::rsa_pkcs1_with_sha256, context.badSignature, context.certs); } @@ -1005,7 +918,7 @@ ResponderID(OCSPResponseContext& context) contents = context.signerNameDER; responderIDType = 1; // byName } else { - contents = KeyHash(context); + contents = KeyHash(context.signerKeyPair->subjectPublicKey); if (contents == ENCODING_FAILED) { return ENCODING_FAILED; } @@ -1022,19 +935,9 @@ ResponderID(OCSPResponseContext& context) // -- the tag, length, and number of unused // -- bits] in the responder's certificate) ByteString -KeyHash(OCSPResponseContext& context) +KeyHash(const ByteString& subjectPublicKey) { - ScopedSECKEYPublicKey - signerPublicKey(SECKEY_ConvertToPublicKey(context.signerPrivateKey.get())); - if (!signerPublicKey) { - return nullptr; - } - ScopedPtr - signerSPKI(SECKEY_CreateSubjectPublicKeyInfo(signerPublicKey.get())); - if (!signerSPKI) { - return nullptr; - } - return KeyHashHelper(signerSPKI.get()); + return HashedOctetString(subjectPublicKey); } // SingleResponse ::= SEQUENCE { @@ -1087,23 +990,37 @@ SingleResponse(OCSPResponseContext& context) ByteString CertID(OCSPResponseContext& context) { - SECItem issuerSECItem = UnsafeMapInputToSECItem(context.certID.issuer); - ByteString issuerNameHash(HashedOctetString(issuerSECItem)); + ByteString issuerName(context.certID.issuer.UnsafeGetData(), + context.certID.issuer.GetLength()); + ByteString issuerNameHash(HashedOctetString(issuerName)); if (issuerNameHash == ENCODING_FAILED) { return ENCODING_FAILED; } - SECItem issuerSubjectPublicKeyInfoSECItem = - UnsafeMapInputToSECItem(context.certID.issuerSubjectPublicKeyInfo); - ScopedPtr - spki(SECKEY_DecodeDERSubjectPublicKeyInfo( - &issuerSubjectPublicKeyInfoSECItem)); - if (!spki) { - return ENCODING_FAILED; - } - ByteString issuerKeyHash(KeyHashHelper(spki.get())); - if (issuerKeyHash == ENCODING_FAILED) { - return ENCODING_FAILED; + ByteString issuerKeyHash; + { + // context.certID.issuerSubjectPublicKeyInfo is the entire + // SubjectPublicKeyInfo structure, but we need just the subjectPublicKey + // part. + Reader input(context.certID.issuerSubjectPublicKeyInfo); + Reader contents; + if (der::ExpectTagAndGetValue(input, der::SEQUENCE, contents) != Success) { + return ENCODING_FAILED; + } + // Skip AlgorithmIdentifier + if (der::ExpectTagAndSkipValue(contents, der::SEQUENCE) != Success) { + return ENCODING_FAILED; + } + Input subjectPublicKey; + if (der::BitStringWithNoUnusedBits(contents, subjectPublicKey) + != Success) { + return ENCODING_FAILED; + } + issuerKeyHash = KeyHash(ByteString(subjectPublicKey.UnsafeGetData(), + subjectPublicKey.GetLength())); + if (issuerKeyHash == ENCODING_FAILED) { + return ENCODING_FAILED; + } } ByteString serialNumberValue(context.certID.serialNumber.UnsafeGetData(), diff --git a/security/pkix/test/lib/pkixtestutil.h b/security/pkix/test/lib/pkixtestutil.h index 1869da0dd4e7..0516e5a04052 100644 --- a/security/pkix/test/lib/pkixtestutil.h +++ b/security/pkix/test/lib/pkixtestutil.h @@ -29,11 +29,10 @@ #include // Some Mozilla-supported compilers lack #include -#include "keyhi.h" #include "pkix/enumclass.h" #include "pkix/pkixtypes.h" #include "pkix/ScopedPtr.h" -#include "seccomon.h" +#include "secitem.h" namespace mozilla { namespace pkix { namespace test { @@ -76,10 +75,6 @@ SECITEM_FreeItem_true(SECItem* item) } // unnamed namespace typedef mozilla::pkix::ScopedPtr ScopedSECItem; -typedef mozilla::pkix::ScopedPtr - ScopedSECKEYPublicKey; -typedef mozilla::pkix::ScopedPtr - ScopedSECKEYPrivateKey; // python DottedOIDToCode.py --tlv id-kp-OCSPSigning 1.3.6.1.5.5.7.3.9 static const uint8_t tlv_id_kp_OCSPSigning[] = { @@ -97,11 +92,42 @@ extern const Input sha256WithRSAEncryption; mozilla::pkix::Time YMDHMS(int16_t year, int16_t month, int16_t day, int16_t hour, int16_t minutes, int16_t seconds); -Result GenerateKeyPair(/*out*/ ScopedSECKEYPublicKey& publicKey, - /*out*/ ScopedSECKEYPrivateKey& privateKey); ByteString CNToDERName(const char* cn); +class TestKeyPair +{ +public: + virtual ~TestKeyPair() { } + + // The DER encoding of the entire SubjectPublicKeyInfo structure. This is + // what is encoded in certificates. + const ByteString subjectPublicKeyInfo; + + // The DER encoding of subjectPublicKeyInfo.subjectPublicKey. This is what is + // hashed to create CertIDs for OCSP. + const ByteString subjectPublicKey; + + virtual Result SignData(const ByteString& tbs, + SignatureAlgorithm signatureAlgorithm, + /*out*/ ByteString& signature) const = 0; + + virtual TestKeyPair* Clone() const = 0; +protected: + TestKeyPair(const ByteString& spki, const ByteString& spk) + : subjectPublicKeyInfo(spki) + , subjectPublicKey(spk) + { + } + + TestKeyPair(const TestKeyPair&) /*= delete*/; + void operator=(const TestKeyPair&) /*= delete*/; +}; + +TestKeyPair* GenerateKeyPair(); +inline void DeleteTestKeyPair(TestKeyPair* keyPair) { delete keyPair; } +typedef ScopedPtr ScopedTestKeyPair; + // Replace one substring in item with another of the same length, but only if // the substring was found exactly once. The "same length" restriction is // useful for avoiding invalidating lengths encoded within the item. The @@ -128,16 +154,15 @@ enum Version { v1 = 0, v2 = 1, v3 = 2 }; // If issuerPrivateKey is null, then the certificate will be self-signed. // Parameter order is based on the order of the attributes of the certificate // in RFC 5280. -ByteString CreateEncodedCertificate(long version, - Input signature, +ByteString CreateEncodedCertificate(long version, Input signature, const ByteString& serialNumber, const ByteString& issuerNameDER, - std::time_t notBefore, std::time_t notAfter, + time_t notBefore, time_t notAfter, const ByteString& subjectNameDER, - /*optional*/ const ByteString* extensions, - /*optional*/ SECKEYPrivateKey* issuerPrivateKey, + /*optional*/ const ByteString* extensions, + /*optional*/ TestKeyPair* issuerKeyPair, SignatureAlgorithm signatureAlgorithm, - /*out*/ ScopedSECKEYPrivateKey& privateKey); + /*out*/ ScopedTestKeyPair& keyPairResult); ByteString CreateEncodedSerialNumber(long value); @@ -196,7 +221,7 @@ public: bool includeEmptyExtensions; // If true, include the extension wrapper // regardless of if there are any actual // extensions. - ScopedSECKEYPrivateKey signerPrivateKey; + ScopedTestKeyPair signerKeyPair; bool badSignature; // If true, alter the signature to fail verification const ByteString* certs; // optional; array terminated by an empty string