Bug 1939208 - Localize messages according to application context. r=android-reviewers...
[gecko.git] / security / manager / ssl / tests / unit / tlsserver / lib / OCSPCommon.cpp
blobed51a0c8ea76bfe84d64cb5bee9af71f0afdfb13
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "OCSPCommon.h"
7 #include <stdio.h>
9 #include "TLSServer.h"
10 #include "mozpkix/pkixder.h"
11 #include "mozpkix/test/pkixtestnss.h"
12 #include "mozpkix/test/pkixtestutil.h"
13 #include "nss.h"
14 #include "secder.h"
15 #include "secerr.h"
17 using namespace mozilla;
18 using namespace mozilla::pkix;
19 using namespace mozilla::pkix::test;
20 using namespace mozilla::test;
22 static TestKeyPair* CreateTestKeyPairFromCert(
23 const UniqueCERTCertificate& cert) {
24 ScopedSECKEYPrivateKey privateKey(PK11_FindKeyByAnyCert(cert.get(), nullptr));
25 if (!privateKey) {
26 return nullptr;
28 ScopedSECKEYPublicKey publicKey(CERT_ExtractPublicKey(cert.get()));
29 if (!publicKey) {
30 return nullptr;
32 return CreateTestKeyPair(RSA_PKCS1(), publicKey, privateKey);
35 SECItemArray* GetOCSPResponseForType(OCSPResponseType aORT,
36 const UniqueCERTCertificate& aCert,
37 const UniquePLArenaPool& aArena,
38 const char* aAdditionalCertName,
39 time_t aThisUpdateSkew,
40 ByteString* aSCTList) {
41 MOZ_ASSERT(aArena);
42 MOZ_ASSERT(aCert);
43 // Note: |aAdditionalCertName| may or may not need to be non-null depending
44 // on the |aORT| value given.
46 // Ensure NSS can sign responses using small RSA keys.
47 NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, 512);
49 if (aORT == ORTNone) {
50 if (gDebugLevel >= DEBUG_WARNINGS) {
51 fprintf(stderr,
52 "GetOCSPResponseForType called with type ORTNone, "
53 "which makes no sense.\n");
55 return nullptr;
58 if (aORT == ORTEmpty) {
59 SECItemArray* arr = SECITEM_AllocArray(aArena.get(), nullptr, 1);
60 arr->items[0].data = nullptr;
61 arr->items[0].len = 0;
62 return arr;
65 time_t now = time(nullptr) + aThisUpdateSkew;
66 time_t oldNow = now - (8 * Time::ONE_DAY_IN_SECONDS);
68 mozilla::UniqueCERTCertificate cert(CERT_DupCertificate(aCert.get()));
70 if (aORT == ORTGoodOtherCert) {
71 cert.reset(PK11_FindCertFromNickname(aAdditionalCertName, nullptr));
72 if (!cert) {
73 PrintPRError("PK11_FindCertFromNickname failed");
74 return nullptr;
77 // XXX CERT_FindCertIssuer uses the old, deprecated path-building logic
78 mozilla::UniqueCERTCertificate issuerCert(
79 CERT_FindCertIssuer(aCert.get(), PR_Now(), certUsageSSLCA));
80 if (!issuerCert) {
81 PrintPRError("CERT_FindCertIssuer failed");
82 return nullptr;
84 Input issuer;
85 if (issuer.Init(cert->derIssuer.data, cert->derIssuer.len) != Success) {
86 return nullptr;
88 Input issuerPublicKey;
89 if (issuerPublicKey.Init(issuerCert->derPublicKey.data,
90 issuerCert->derPublicKey.len) != Success) {
91 return nullptr;
93 Input serialNumber;
94 if (serialNumber.Init(cert->serialNumber.data, cert->serialNumber.len) !=
95 Success) {
96 return nullptr;
98 CertID certID(issuer, issuerPublicKey, serialNumber);
99 OCSPResponseContext context(certID, now);
101 mozilla::UniqueCERTCertificate signerCert;
102 if (aORT == ORTGoodOtherCA || aORT == ORTDelegatedIncluded ||
103 aORT == ORTDelegatedIncludedLast || aORT == ORTDelegatedMissing ||
104 aORT == ORTDelegatedMissingMultiple) {
105 signerCert.reset(PK11_FindCertFromNickname(aAdditionalCertName, nullptr));
106 if (!signerCert) {
107 PrintPRError("PK11_FindCertFromNickname failed");
108 return nullptr;
112 ByteString certs[5];
114 if (aORT == ORTDelegatedIncluded) {
115 certs[0].assign(signerCert->derCert.data, signerCert->derCert.len);
116 context.certs = certs;
118 if (aORT == ORTDelegatedIncludedLast || aORT == ORTDelegatedMissingMultiple) {
119 certs[0].assign(issuerCert->derCert.data, issuerCert->derCert.len);
120 certs[1].assign(cert->derCert.data, cert->derCert.len);
121 certs[2].assign(issuerCert->derCert.data, issuerCert->derCert.len);
122 if (aORT != ORTDelegatedMissingMultiple) {
123 certs[3].assign(signerCert->derCert.data, signerCert->derCert.len);
125 context.certs = certs;
128 switch (aORT) {
129 case ORTMalformed:
130 context.responseStatus = 1;
131 break;
132 case ORTSrverr:
133 context.responseStatus = 2;
134 break;
135 case ORTTryLater:
136 context.responseStatus = 3;
137 break;
138 case ORTNeedsSig:
139 context.responseStatus = 5;
140 break;
141 case ORTUnauthorized:
142 context.responseStatus = 6;
143 break;
144 default:
145 // context.responseStatus is 0 in all other cases, and it has
146 // already been initialized in the constructor.
147 break;
149 if (aORT == ORTSkipResponseBytes) {
150 context.skipResponseBytes = true;
152 if (aORT == ORTExpired || aORT == ORTExpiredFreshCA ||
153 aORT == ORTRevokedOld || aORT == ORTUnknownOld) {
154 context.thisUpdate = oldNow;
155 context.nextUpdate = oldNow + Time::ONE_DAY_IN_SECONDS;
157 if (aORT == ORTLongValidityAlmostExpired) {
158 context.thisUpdate = now - (320 * Time::ONE_DAY_IN_SECONDS);
160 if (aORT == ORTAncientAlmostExpired) {
161 context.thisUpdate = now - (640 * Time::ONE_DAY_IN_SECONDS);
163 if (aORT == ORTRevoked || aORT == ORTRevokedOld) {
164 context.certStatus = 1;
166 if (aORT == ORTUnknown || aORT == ORTUnknownOld) {
167 context.certStatus = 2;
169 if (aORT == ORTBadSignature) {
170 context.badSignature = true;
172 OCSPResponseExtension extension;
173 if (aORT == ORTCriticalExtension || aORT == ORTNoncriticalExtension) {
174 // python DottedOIDToCode.py --tlv
175 // some-Mozilla-OID 1.3.6.1.4.1.13769.666.666.666.1.500.9.2
176 static const uint8_t tlv_some_Mozilla_OID[] = {
177 0x06, 0x12, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xeb, 0x49, 0x85,
178 0x1a, 0x85, 0x1a, 0x85, 0x1a, 0x01, 0x83, 0x74, 0x09, 0x02};
180 extension.id.assign(tlv_some_Mozilla_OID, sizeof(tlv_some_Mozilla_OID));
181 extension.critical = (aORT == ORTCriticalExtension);
182 extension.value.push_back(0x05); // tag: NULL
183 extension.value.push_back(0x00); // length: 0
184 extension.next = nullptr;
185 context.responseExtensions = &extension;
187 if (aORT == ORTEmptyExtensions) {
188 context.includeEmptyExtensions = true;
191 if (!signerCert) {
192 signerCert.reset(CERT_DupCertificate(issuerCert.get()));
194 context.signerKeyPair.reset(CreateTestKeyPairFromCert(signerCert));
195 if (!context.signerKeyPair) {
196 PrintPRError("PK11_FindKeyByAnyCert failed");
197 return nullptr;
200 OCSPResponseExtension singleExtension;
201 if (aSCTList) {
202 // SingleExtension for Signed Certificate Timestamp List.
203 // See Section 3.3 of RFC 6962.
204 // python DottedOIDToCode.py --tlv
205 // id_ocsp_singleExtensionSctList 1.3.6.1.4.1.11129.2.4.5
206 static const uint8_t tlv_id_ocsp_singleExtensionSctList[] = {
207 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x04, 0x05};
208 singleExtension.id.assign(tlv_id_ocsp_singleExtensionSctList,
209 sizeof(tlv_id_ocsp_singleExtensionSctList));
210 singleExtension.critical = true;
211 singleExtension.value = TLV(der::OCTET_STRING, *aSCTList);
212 singleExtension.next = nullptr;
213 context.singleExtensions = &singleExtension;
216 ByteString response(CreateEncodedOCSPResponse(context));
217 if (ENCODING_FAILED(response)) {
218 PrintPRError("CreateEncodedOCSPResponse failed");
219 return nullptr;
222 SECItem item = {siBuffer, const_cast<uint8_t*>(response.data()),
223 static_cast<unsigned int>(response.length())};
224 SECItemArray arr = {&item, 1};
225 return SECITEM_DupArray(aArena.get(), &arr);