diff -r 000000000000 -r 6474c204b198 security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,177 @@ +/* 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/. */ + +#include "OCSPCommon.h" + +#include + +#include "ScopedNSSTypes.h" +#include "TLSServer.h" +#include "pkixtestutil.h" +#include "secder.h" +#include "secerr.h" + +using namespace mozilla; +using namespace mozilla::test; +using namespace mozilla::pkix::test; + + +SECItemArray * +GetOCSPResponseForType(OCSPResponseType aORT, CERTCertificate *aCert, + PLArenaPool *aArena, const char *aAdditionalCertName) +{ + if (aORT == ORTNone) { + if (gDebugLevel >= DEBUG_WARNINGS) { + fprintf(stderr, "GetOCSPResponseForType called with type ORTNone, " + "which makes no sense.\n"); + } + return nullptr; + } + + if (aORT == ORTEmpty) { + SECItemArray* arr = SECITEM_AllocArray(aArena, nullptr, 1); + arr->items[0].data = nullptr; + arr->items[0].len = 0; + return arr; + } + + PRTime now = PR_Now(); + PRTime oneDay = 60*60*24 * (PRTime)PR_USEC_PER_SEC; + PRTime oldNow = now - (8 * oneDay); + + OCSPResponseContext context(aArena, aCert, now); + + if (aORT == ORTGoodOtherCert) { + context.cert = PK11_FindCertFromNickname(aAdditionalCertName, nullptr); + if (!context.cert) { + PrintPRError("PK11_FindCertFromNickname failed"); + return nullptr; + } + } + // XXX CERT_FindCertIssuer uses the old, deprecated path-building logic + context.issuerCert = CERT_FindCertIssuer(aCert, now, certUsageSSLCA); + if (!context.issuerCert) { + PrintPRError("CERT_FindCertIssuer failed"); + return nullptr; + } + if (aORT == ORTGoodOtherCA || aORT == ORTDelegatedIncluded || + aORT == ORTDelegatedIncludedLast || aORT == ORTDelegatedMissing || + aORT == ORTDelegatedMissingMultiple) { + context.signerCert = PK11_FindCertFromNickname(aAdditionalCertName, + nullptr); + if (!context.signerCert) { + PrintPRError("PK11_FindCertFromNickname failed"); + return nullptr; + } + } + if (aORT == ORTDelegatedIncluded) { + context.includedCertificates[0] = + CERT_DupCertificate(context.signerCert.get()); + } + if (aORT == ORTDelegatedIncludedLast || aORT == ORTDelegatedMissingMultiple) { + context.includedCertificates[0] = + CERT_DupCertificate(context.issuerCert.get()); + context.includedCertificates[1] = CERT_DupCertificate(context.cert.get()); + context.includedCertificates[2] = + CERT_DupCertificate(context.issuerCert.get()); + if (aORT != ORTDelegatedMissingMultiple) { + context.includedCertificates[3] = + CERT_DupCertificate(context.signerCert.get()); + } + } + switch (aORT) { + case ORTMalformed: + context.responseStatus = 1; + break; + case ORTSrverr: + context.responseStatus = 2; + break; + case ORTTryLater: + context.responseStatus = 3; + break; + case ORTNeedsSig: + context.responseStatus = 5; + break; + case ORTUnauthorized: + context.responseStatus = 6; + break; + default: + // context.responseStatus is 0 in all other cases, and it has + // already been initialized in the constructor. + break; + } + if (aORT == ORTSkipResponseBytes) { + context.skipResponseBytes = true; + } + if (aORT == ORTExpired || aORT == ORTExpiredFreshCA || + aORT == ORTRevokedOld || aORT == ORTUnknownOld) { + context.thisUpdate = oldNow; + context.nextUpdate = oldNow + 10 * PR_USEC_PER_SEC; + } + if (aORT == ORTLongValidityAlmostExpired) { + context.thisUpdate = now - (320 * oneDay); + } + if (aORT == ORTAncientAlmostExpired) { + context.thisUpdate = now - (640 * oneDay); + } + if (aORT == ORTRevoked || aORT == ORTRevokedOld) { + context.certStatus = 1; + } + if (aORT == ORTUnknown || aORT == ORTUnknownOld) { + context.certStatus = 2; + } + if (aORT == ORTBadSignature) { + context.badSignature = true; + } + OCSPResponseExtension extension; + if (aORT == ORTCriticalExtension || aORT == ORTNoncriticalExtension) { + SECItem oidItem = { + siBuffer, + nullptr, + 0 + }; + // 1.3.6.1.4.1.13769.666.666.666 is the root of Mozilla's testing OID space + static const char* testExtensionOID = "1.3.6.1.4.1.13769.666.666.666.1.500.9.2"; + if (SEC_StringToOID(aArena, &oidItem, testExtensionOID, + PL_strlen(testExtensionOID)) != SECSuccess) { + return nullptr; + } + DERTemplate oidTemplate[2] = { { DER_OBJECT_ID, 0 }, { 0 } }; + extension.id.data = nullptr; + extension.id.len = 0; + if (DER_Encode(aArena, &extension.id, oidTemplate, &oidItem) + != SECSuccess) { + return nullptr; + } + extension.critical = (aORT == ORTCriticalExtension); + static const uint8_t value[2] = { 0x05, 0x00 }; + extension.value.data = const_cast(value); + extension.value.len = PR_ARRAY_SIZE(value); + extension.next = nullptr; + context.extensions = &extension; + } + if (aORT == ORTEmptyExtensions) { + context.includeEmptyExtensions = true; + } + + if (!context.signerCert) { + context.signerCert = CERT_DupCertificate(context.issuerCert.get()); + } + + SECItem* response = CreateEncodedOCSPResponse(context); + if (!response) { + PrintPRError("CreateEncodedOCSPResponse failed"); + return nullptr; + } + + SECItemArray* arr = SECITEM_AllocArray(aArena, nullptr, 1); + if (!arr) { + PrintPRError("SECITEM_AllocArray failed"); + return nullptr; + } + arr->items[0].data = response->data; + arr->items[0].len = response->len; + + return arr; +}