Bug 1063006: Centralize direct use of NSS for crypto in the mozilla::pkix test suite, r=keeler

--HG--
rename : security/pkix/test/lib/pkixtestutil.cpp => security/pkix/test/lib/pkixtestnss.cpp
extra : rebase_source : 93515d39abf91168fa86268f9b26f8c62d0d411e
This commit is contained in:
Brian Smith 2014-08-31 17:47:09 -07:00
Родитель ba3ad3aa0e
Коммит 8dbcf66d66
9 изменённых файлов: 372 добавлений и 266 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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()));

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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<CertID, deleteCertID> 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,

Просмотреть файл

@ -21,6 +21,7 @@
# limitations under the License.
SOURCES += [
'pkixtestnss.cpp',
'pkixtestutil.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<SECKEYPublicKey, SECKEY_DestroyPublicKey>
ScopedSECKEYPublicKey;
typedef ScopedPtr<SECKEYPrivateKey, SECKEY_DestroyPrivateKey>
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<PK11SlotInfo, PK11_FreeSlot> 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,
&params, &publicKeyTemp, false, true,
nullptr));
ScopedSECKEYPublicKey publicKey(publicKeyTemp);
if (privateKey) {
ScopedSECItem
spkiDER(SECKEY_EncodeDERSubjectPublicKeyInfo(publicKey.get()));
if (!spkiDER) {
return nullptr;
}
ScopedPtr<CERTSubjectPublicKeyInfo, SECKEY_DestroySubjectPublicKeyInfo>
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

Просмотреть файл

@ -30,15 +30,10 @@
#include <new>
#include <sstream>
#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) {
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<PK11SlotInfo, PK11_FreeSlot> 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,
&params, &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<long>(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<CERTSubjectPublicKeyInfo, SECKEY_DestroySubjectPublicKeyInfo>
signerSPKI(SECKEY_CreateSubjectPublicKeyInfo(signerPublicKey.get()));
if (!signerSPKI) {
return nullptr;
}
return KeyHashHelper(signerSPKI.get());
return HashedOctetString(subjectPublicKey);
}
// SingleResponse ::= SEQUENCE {
@ -1087,24 +990,38 @@ 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<CERTSubjectPublicKeyInfo, SECKEY_DestroySubjectPublicKeyInfo>
spki(SECKEY_DecodeDERSubjectPublicKeyInfo(
&issuerSubjectPublicKeyInfoSECItem));
if (!spki) {
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;
}
ByteString issuerKeyHash(KeyHashHelper(spki.get()));
// 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(),
context.certID.serialNumber.GetLength());

Просмотреть файл

@ -29,11 +29,10 @@
#include <stdint.h> // Some Mozilla-supported compilers lack <cstdint>
#include <string>
#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<SECItem, SECITEM_FreeItem_true> ScopedSECItem;
typedef mozilla::pkix::ScopedPtr<SECKEYPublicKey, SECKEY_DestroyPublicKey>
ScopedSECKEYPublicKey;
typedef mozilla::pkix::ScopedPtr<SECKEYPrivateKey, SECKEY_DestroyPrivateKey>
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<TestKeyPair, DeleteTestKeyPair> 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*/ 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