security/pkix/lib/pkixocsp.cpp

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:40f8d9c9459b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* Copyright 2013 Mozilla Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include <limits>
19
20 #include "pkix/bind.h"
21 #include "pkix/pkix.h"
22 #include "pkixcheck.h"
23 #include "pkixder.h"
24
25 #include "hasht.h"
26 #include "pk11pub.h"
27 #include "secder.h"
28
29 #ifdef _MSC_VER
30 // C4480: nonstandard extension used: specifying underlying type for enum
31 #define ENUM_CLASS __pragma(warning(disable: 4480)) enum
32 #else
33 #define ENUM_CLASS enum class
34 #endif
35
36 // TODO: use typed/qualified typedefs everywhere?
37 // TODO: When should we return SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE?
38
39 namespace mozilla { namespace pkix {
40
41 static const PRTime ONE_DAY
42 = INT64_C(24) * INT64_C(60) * INT64_C(60) * PR_USEC_PER_SEC;
43 static const PRTime SLOP = ONE_DAY;
44
45 // These values correspond to the tag values in the ASN.1 CertStatus
46 ENUM_CLASS CertStatus : uint8_t {
47 Good = der::CONTEXT_SPECIFIC | 0,
48 Revoked = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
49 Unknown = der::CONTEXT_SPECIFIC | 2
50 };
51
52 class Context
53 {
54 public:
55 Context(TrustDomain& trustDomain,
56 const CERTCertificate& cert,
57 CERTCertificate& issuerCert,
58 PRTime time,
59 uint16_t maxLifetimeInDays,
60 PRTime* thisUpdate,
61 PRTime* validThrough)
62 : trustDomain(trustDomain)
63 , cert(cert)
64 , issuerCert(issuerCert)
65 , time(time)
66 , maxLifetimeInDays(maxLifetimeInDays)
67 , certStatus(CertStatus::Unknown)
68 , thisUpdate(thisUpdate)
69 , validThrough(validThrough)
70 , expired(false)
71 {
72 if (thisUpdate) {
73 *thisUpdate = 0;
74 }
75 if (validThrough) {
76 *validThrough = 0;
77 }
78 }
79
80 TrustDomain& trustDomain;
81 const CERTCertificate& cert;
82 CERTCertificate& issuerCert;
83 const PRTime time;
84 const uint16_t maxLifetimeInDays;
85 CertStatus certStatus;
86 PRTime* thisUpdate;
87 PRTime* validThrough;
88 bool expired;
89
90 private:
91 Context(const Context&); // delete
92 void operator=(const Context&); // delete
93 };
94
95 // Verify that potentialSigner is a valid delegated OCSP response signing cert
96 // according to RFC 6960 section 4.2.2.2.
97 static Result
98 CheckOCSPResponseSignerCert(TrustDomain& trustDomain,
99 CERTCertificate& potentialSigner,
100 const CERTCertificate& issuerCert, PRTime time)
101 {
102 Result rv;
103
104 BackCert cert(&potentialSigner, nullptr, BackCert::ExcludeCN);
105 rv = cert.Init();
106 if (rv != Success) {
107 return rv;
108 }
109
110 // We don't need to do a complete verification of the signer (i.e. we don't
111 // have to call BuildCertChain to verify the entire chain) because we
112 // already know that the issuerCert is valid, since revocation checking is
113 // done from the root to the parent after we've built a complete chain that
114 // we know is otherwise valid. Rather, we just need to do a one-step
115 // validation from potentialSigner to issuerCert.
116 //
117 // It seems reasonable to require the KU_DIGITAL_SIGNATURE key usage on the
118 // OCSP responder certificate if the OCSP responder certificate has a
119 // key usage extension. However, according to bug 240456, some OCSP responder
120 // certificates may have only the nonRepudiation bit set. Also, the OCSP
121 // specification (RFC 6960) does not mandate any particular key usage to be
122 // asserted for OCSP responde signers. Oddly, the CABForum Baseline
123 // Requirements v.1.1.5 do say "If the Root CA Private Key is used for
124 // signing OCSP responses, then the digitalSignature bit MUST be set."
125 //
126 // Note that CheckIssuerIndependentProperties processes
127 // SEC_OID_OCSP_RESPONDER in the way that the OCSP specification requires us
128 // to--in particular, it doesn't allow SEC_OID_OCSP_RESPONDER to be implied
129 // by a missing EKU extension, unlike other EKUs.
130 //
131 // TODO(bug 926261): If we're validating for a policy then the policy OID we
132 // are validating for should be passed to CheckIssuerIndependentProperties.
133 rv = CheckIssuerIndependentProperties(trustDomain, cert, time,
134 MustBeEndEntity,
135 KeyUsage::noParticularKeyUsageRequired,
136 SEC_OID_OCSP_RESPONDER,
137 SEC_OID_X509_ANY_POLICY, 0);
138 if (rv != Success) {
139 return rv;
140 }
141
142 // It is possible that there exists a certificate with the same key as the
143 // issuer but with a different name, so we need to compare names
144 // TODO: needs test
145 if (!SECITEM_ItemsAreEqual(&cert.GetNSSCert()->derIssuer,
146 &issuerCert.derSubject) &&
147 CERT_CompareName(&cert.GetNSSCert()->issuer,
148 &issuerCert.subject) != SECEqual) {
149 return Fail(RecoverableError, SEC_ERROR_OCSP_RESPONDER_CERT_INVALID);
150 }
151
152 // TODO(bug 926260): check name constraints
153
154 if (trustDomain.VerifySignedData(&potentialSigner.signatureWrap,
155 &issuerCert) != SECSuccess) {
156 return MapSECStatus(SECFailure);
157 }
158
159 // TODO: check for revocation of the OCSP responder certificate unless no-check
160 // or the caller forcing no-check. To properly support the no-check policy, we'd
161 // need to enforce policy constraints from the issuerChain.
162
163 return Success;
164 }
165
166 //typedef enum {
167 // ocspResponderID_byName = 1,
168 // ocspResponderID_byKey = 2
169 //} ResponderIDType;
170
171 ENUM_CLASS ResponderIDType : uint8_t
172 {
173 byName = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
174 byKey = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 2
175 };
176
177 static inline der::Result OCSPResponse(der::Input&, Context&);
178 static inline der::Result ResponseBytes(der::Input&, Context&);
179 static inline der::Result BasicResponse(der::Input&, Context&);
180 static inline der::Result ResponseData(
181 der::Input& tbsResponseData, Context& context,
182 const CERTSignedData& signedResponseData,
183 /*const*/ SECItem* certs, size_t numCerts);
184 static inline der::Result SingleResponse(der::Input& input,
185 Context& context);
186 static inline der::Result CheckExtensionsForCriticality(der::Input&);
187 static inline der::Result CertID(der::Input& input,
188 const Context& context,
189 /*out*/ bool& match);
190 static der::Result MatchIssuerKey(const SECItem& issuerKeyHash,
191 const CERTCertificate& issuer,
192 /*out*/ bool& match);
193
194 // RFC 6960 section 4.2.2.2: The OCSP responder must either be the issuer of
195 // the cert or it must be a delegated OCSP response signing cert directly
196 // issued by the issuer. If the OCSP responder is a delegated OCSP response
197 // signer, then its certificate is (probably) embedded within the OCSP
198 // response and we'll need to verify that it is a valid certificate that chains
199 // *directly* to issuerCert.
200 static CERTCertificate*
201 GetOCSPSignerCertificate(TrustDomain& trustDomain,
202 ResponderIDType responderIDType,
203 const SECItem& responderIDItem,
204 const SECItem* certs, size_t numCerts,
205 CERTCertificate& issuerCert, PRTime time)
206 {
207 bool isIssuer = true;
208 size_t i = 0;
209 for (;;) {
210 ScopedCERTCertificate potentialSigner;
211 if (isIssuer) {
212 potentialSigner = CERT_DupCertificate(&issuerCert);
213 } else if (i < numCerts) {
214 potentialSigner = CERT_NewTempCertificate(
215 CERT_GetDefaultCertDB(),
216 /*TODO*/const_cast<SECItem*>(&certs[i]), nullptr,
217 false, false);
218 if (!potentialSigner) {
219 return nullptr;
220 }
221 ++i;
222 } else {
223 PR_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, 0);
224 return nullptr;
225 }
226
227 bool match;
228 switch (responderIDType) {
229 case ResponderIDType::byName:
230 // The CA is very likely to have encoded the name in the OCSP response
231 // exactly the same as the name is encoded in the signing certificate.
232 // Consequently, most of the time we will avoid parsing the name
233 // completely. We're assuming here that the signer's subject name is
234 // correctly formatted.
235 // TODO: need test for exact name
236 // TODO: need test for non-exact name match
237 match = SECITEM_ItemsAreEqual(&responderIDItem,
238 &potentialSigner->derSubject);
239 if (!match) {
240 ScopedPLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
241 if (!arena) {
242 return nullptr;
243 }
244 CERTName name;
245 if (SEC_QuickDERDecodeItem(arena.get(), &name,
246 SEC_ASN1_GET(CERT_NameTemplate),
247 &responderIDItem) != SECSuccess) {
248 return nullptr;
249 }
250 match = CERT_CompareName(&name, &potentialSigner->subject) == SECEqual;
251 }
252 break;
253
254 case ResponderIDType::byKey:
255 {
256 der::Input responderID;
257 if (responderID.Init(responderIDItem.data, responderIDItem.len)
258 != der::Success) {
259 return nullptr;
260 }
261 SECItem issuerKeyHash;
262 if (der::Skip(responderID, der::OCTET_STRING, issuerKeyHash) != der::Success) {
263 return nullptr;
264 }
265 if (MatchIssuerKey(issuerKeyHash, *potentialSigner.get(), match)
266 != der::Success) {
267 return nullptr;
268 }
269 break;
270 }
271
272 default:
273 PR_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE, 0);
274 return nullptr;
275 }
276
277 if (match && !isIssuer) {
278 Result rv = CheckOCSPResponseSignerCert(trustDomain,
279 *potentialSigner.get(),
280 issuerCert, time);
281 if (rv == RecoverableError) {
282 match = false;
283 } else if (rv != Success) {
284 return nullptr;
285 }
286 }
287
288 if (match) {
289 return potentialSigner.release();
290 }
291
292 isIssuer = false;
293 }
294 }
295
296 static SECStatus
297 VerifySignature(Context& context, ResponderIDType responderIDType,
298 const SECItem& responderID, const SECItem* certs,
299 size_t numCerts, const CERTSignedData& signedResponseData)
300 {
301 ScopedCERTCertificate signer(
302 GetOCSPSignerCertificate(context.trustDomain, responderIDType, responderID,
303 certs, numCerts, context.issuerCert,
304 context.time));
305 if (!signer) {
306 return SECFailure;
307 }
308
309 if (context.trustDomain.VerifySignedData(&signedResponseData, signer.get())
310 != SECSuccess) {
311 if (PR_GetError() == SEC_ERROR_BAD_SIGNATURE) {
312 PR_SetError(SEC_ERROR_OCSP_BAD_SIGNATURE, 0);
313 }
314 return SECFailure;
315 }
316
317 return SECSuccess;
318 }
319
320 static inline void
321 SetErrorToMalformedResponseOnBadDERError()
322 {
323 if (PR_GetError() == SEC_ERROR_BAD_DER) {
324 PR_SetError(SEC_ERROR_OCSP_MALFORMED_RESPONSE, 0);
325 }
326 }
327
328 SECStatus
329 VerifyEncodedOCSPResponse(TrustDomain& trustDomain,
330 const CERTCertificate* cert,
331 CERTCertificate* issuerCert, PRTime time,
332 uint16_t maxOCSPLifetimeInDays,
333 const SECItem* encodedResponse,
334 bool& expired,
335 PRTime* thisUpdate,
336 PRTime* validThrough)
337 {
338 PR_ASSERT(cert);
339 PR_ASSERT(issuerCert);
340 // TODO: PR_Assert(pinArg)
341 PR_ASSERT(encodedResponse);
342 if (!cert || !issuerCert || !encodedResponse || !encodedResponse->data) {
343 PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
344 return SECFailure;
345 }
346
347 // Always initialize this to something reasonable.
348 expired = false;
349
350 der::Input input;
351 if (input.Init(encodedResponse->data, encodedResponse->len) != der::Success) {
352 SetErrorToMalformedResponseOnBadDERError();
353 return SECFailure;
354 }
355 Context context(trustDomain, *cert, *issuerCert, time, maxOCSPLifetimeInDays,
356 thisUpdate, validThrough);
357
358 if (der::Nested(input, der::SEQUENCE,
359 bind(OCSPResponse, _1, ref(context))) != der::Success) {
360 SetErrorToMalformedResponseOnBadDERError();
361 return SECFailure;
362 }
363
364 if (der::End(input) != der::Success) {
365 SetErrorToMalformedResponseOnBadDERError();
366 return SECFailure;
367 }
368
369 expired = context.expired;
370
371 switch (context.certStatus) {
372 case CertStatus::Good:
373 if (expired) {
374 PR_SetError(SEC_ERROR_OCSP_OLD_RESPONSE, 0);
375 return SECFailure;
376 }
377 return SECSuccess;
378 case CertStatus::Revoked:
379 PR_SetError(SEC_ERROR_REVOKED_CERTIFICATE, 0);
380 return SECFailure;
381 case CertStatus::Unknown:
382 PR_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT, 0);
383 return SECFailure;
384 }
385
386 PR_NOT_REACHED("unknown CertStatus");
387 PR_SetError(SEC_ERROR_OCSP_UNKNOWN_CERT, 0);
388 return SECFailure;
389 }
390
391 // OCSPResponse ::= SEQUENCE {
392 // responseStatus OCSPResponseStatus,
393 // responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
394 //
395 static inline der::Result
396 OCSPResponse(der::Input& input, Context& context)
397 {
398 // OCSPResponseStatus ::= ENUMERATED {
399 // successful (0), -- Response has valid confirmations
400 // malformedRequest (1), -- Illegal confirmation request
401 // internalError (2), -- Internal error in issuer
402 // tryLater (3), -- Try again later
403 // -- (4) is not used
404 // sigRequired (5), -- Must sign the request
405 // unauthorized (6) -- Request unauthorized
406 // }
407 uint8_t responseStatus;
408
409 if (der::Enumerated(input, responseStatus) != der::Success) {
410 return der::Failure;
411 }
412 switch (responseStatus) {
413 case 0: break; // successful
414 case 1: return der::Fail(SEC_ERROR_OCSP_MALFORMED_REQUEST);
415 case 2: return der::Fail(SEC_ERROR_OCSP_SERVER_ERROR);
416 case 3: return der::Fail(SEC_ERROR_OCSP_TRY_SERVER_LATER);
417 case 5: return der::Fail(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG);
418 case 6: return der::Fail(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST);
419 default: return der::Fail(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS);
420 }
421
422 return der::Nested(input, der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
423 der::SEQUENCE, bind(ResponseBytes, _1, ref(context)));
424 }
425
426 // ResponseBytes ::= SEQUENCE {
427 // responseType OBJECT IDENTIFIER,
428 // response OCTET STRING }
429 static inline der::Result
430 ResponseBytes(der::Input& input, Context& context)
431 {
432 static const uint8_t id_pkix_ocsp_basic[] = {
433 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
434 };
435
436 if (der::OID(input, id_pkix_ocsp_basic) != der::Success) {
437 return der::Failure;
438 }
439
440 return der::Nested(input, der::OCTET_STRING, der::SEQUENCE,
441 bind(BasicResponse, _1, ref(context)));
442 }
443
444 // BasicOCSPResponse ::= SEQUENCE {
445 // tbsResponseData ResponseData,
446 // signatureAlgorithm AlgorithmIdentifier,
447 // signature BIT STRING,
448 // certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
449 der::Result
450 BasicResponse(der::Input& input, Context& context)
451 {
452 der::Input::Mark mark(input.GetMark());
453
454 uint16_t length;
455 if (der::ExpectTagAndGetLength(input, der::SEQUENCE, length)
456 != der::Success) {
457 return der::Failure;
458 }
459
460 // The signature covers the entire DER encoding of tbsResponseData, including
461 // the beginning tag and length. However, when we're parsing tbsResponseData,
462 // we want to strip off the tag and length because we don't need it after
463 // we've confirmed it's there and figured out what length it is.
464
465 der::Input tbsResponseData;
466
467 if (input.Skip(length, tbsResponseData) != der::Success) {
468 return der::Failure;
469 }
470
471 CERTSignedData signedData;
472
473 input.GetSECItem(siBuffer, mark, signedData.data);
474
475 if (der::Nested(input, der::SEQUENCE,
476 bind(der::AlgorithmIdentifier, _1,
477 ref(signedData.signatureAlgorithm))) != der::Success) {
478 return der::Failure;
479 }
480
481 if (der::Skip(input, der::BIT_STRING, signedData.signature) != der::Success) {
482 return der::Failure;
483 }
484 if (signedData.signature.len == 0) {
485 return der::Fail(SEC_ERROR_OCSP_BAD_SIGNATURE);
486 }
487 unsigned int unusedBitsAtEnd = signedData.signature.data[0];
488 // XXX: Really the constraint should be that unusedBitsAtEnd must be less
489 // than 7. But, we suspect there are no valid OCSP response signatures with
490 // non-zero unused bits. It seems like NSS assumes this in various places, so
491 // we enforce it. If we find compatibility issues, we'll know we're wrong.
492 if (unusedBitsAtEnd != 0) {
493 return der::Fail(SEC_ERROR_OCSP_BAD_SIGNATURE);
494 }
495 ++signedData.signature.data;
496 --signedData.signature.len;
497 signedData.signature.len = (signedData.signature.len << 3); // Bytes to bits
498
499 // Parse certificates, if any
500
501 SECItem certs[8];
502 size_t numCerts = 0;
503
504 if (!input.AtEnd()) {
505 // We ignore the lengths of the wrappers because we'll detect bad lengths
506 // during parsing--too short and we'll run out of input for parsing a cert,
507 // and too long and we'll have leftover data that won't parse as a cert.
508
509 // [0] wrapper
510 if (der::ExpectTagAndIgnoreLength(
511 input, der::CONSTRUCTED | der::CONTEXT_SPECIFIC | 0)
512 != der::Success) {
513 return der::Failure;
514 }
515
516 // SEQUENCE wrapper
517 if (der::ExpectTagAndIgnoreLength(input, der::SEQUENCE) != der::Success) {
518 return der::Failure;
519 }
520
521 // sequence of certificates
522 while (!input.AtEnd()) {
523 if (numCerts == PR_ARRAY_SIZE(certs)) {
524 return der::Fail(SEC_ERROR_BAD_DER);
525 }
526
527 // Unwrap the SEQUENCE that contains the certificate, which is itself a
528 // SEQUENCE.
529 der::Input::Mark mark(input.GetMark());
530 if (der::Skip(input, der::SEQUENCE) != der::Success) {
531 return der::Failure;
532 }
533
534 input.GetSECItem(siBuffer, mark, certs[numCerts]);
535 ++numCerts;
536 }
537 }
538
539 return ResponseData(tbsResponseData, context, signedData, certs, numCerts);
540 }
541
542 // ResponseData ::= SEQUENCE {
543 // version [0] EXPLICIT Version DEFAULT v1,
544 // responderID ResponderID,
545 // producedAt GeneralizedTime,
546 // responses SEQUENCE OF SingleResponse,
547 // responseExtensions [1] EXPLICIT Extensions OPTIONAL }
548 static inline der::Result
549 ResponseData(der::Input& input, Context& context,
550 const CERTSignedData& signedResponseData,
551 /*const*/ SECItem* certs, size_t numCerts)
552 {
553 uint8_t version;
554 if (der::OptionalVersion(input, version) != der::Success) {
555 return der::Failure;
556 }
557 if (version != der::v1) {
558 // TODO: more specific error code for bad version?
559 return der::Fail(SEC_ERROR_BAD_DER);
560 }
561
562 // ResponderID ::= CHOICE {
563 // byName [1] Name,
564 // byKey [2] KeyHash }
565 SECItem responderID;
566 uint16_t responderIDLength;
567 ResponderIDType responderIDType
568 = input.Peek(static_cast<uint8_t>(ResponderIDType::byName))
569 ? ResponderIDType::byName
570 : ResponderIDType::byKey;
571 if (ExpectTagAndGetLength(input, static_cast<uint8_t>(responderIDType),
572 responderIDLength) != der::Success) {
573 return der::Failure;
574 }
575 // TODO: responderID probably needs to have another level of ASN1 tag/length
576 // checked and stripped.
577 if (input.Skip(responderIDLength, responderID) != der::Success) {
578 return der::Failure;
579 }
580
581 // This is the soonest we can verify the signature. We verify the signature
582 // right away to follow the principal of minimizing the processing of data
583 // before verifying its signature.
584 if (VerifySignature(context, responderIDType, responderID, certs, numCerts,
585 signedResponseData) != SECSuccess) {
586 return der::Failure;
587 }
588
589 // TODO: Do we even need to parse this? Should we just skip it?
590 PRTime producedAt;
591 if (der::GeneralizedTime(input, producedAt) != der::Success) {
592 return der::Failure;
593 }
594
595 // We don't accept an empty sequence of responses. In practice, a legit OCSP
596 // responder will never return an empty response, and handling the case of an
597 // empty response makes things unnecessarily complicated.
598 if (der::NestedOf(input, der::SEQUENCE, der::SEQUENCE,
599 der::MustNotBeEmpty,
600 bind(SingleResponse, _1, ref(context))) != der::Success) {
601 return der::Failure;
602 }
603
604 if (!input.AtEnd()) {
605 if (der::Nested(input, der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
606 CheckExtensionsForCriticality) != der::Success) {
607 return der::Failure;
608 }
609 }
610
611 return der::Success;
612 }
613
614 // SingleResponse ::= SEQUENCE {
615 // certID CertID,
616 // certStatus CertStatus,
617 // thisUpdate GeneralizedTime,
618 // nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
619 // singleExtensions [1] EXPLICIT Extensions{{re-ocsp-crl |
620 // re-ocsp-archive-cutoff |
621 // CrlEntryExtensions, ...}
622 // } OPTIONAL }
623 static inline der::Result
624 SingleResponse(der::Input& input, Context& context)
625 {
626 bool match = false;
627 if (der::Nested(input, der::SEQUENCE,
628 bind(CertID, _1, cref(context), ref(match)))
629 != der::Success) {
630 return der::Failure;
631 }
632
633 if (!match) {
634 // This response does not reference the certificate we're interested in.
635 // By consuming the rest of our input and returning successfully, we can
636 // continue processing and examine another response that might have what
637 // we want.
638 input.SkipToEnd();
639 return der::Success;
640 }
641
642 // CertStatus ::= CHOICE {
643 // good [0] IMPLICIT NULL,
644 // revoked [1] IMPLICIT RevokedInfo,
645 // unknown [2] IMPLICIT UnknownInfo }
646 //
647 // In the event of multiple SingleResponses for a cert that have conflicting
648 // statuses, we use the following precedence rules:
649 //
650 // * revoked overrides good and unknown
651 // * good overrides unknown
652 if (input.Peek(static_cast<uint8_t>(CertStatus::Good))) {
653 if (ExpectTagAndLength(input, static_cast<uint8_t>(CertStatus::Good), 0)
654 != der::Success) {
655 return der::Failure;
656 }
657 if (context.certStatus != CertStatus::Revoked) {
658 context.certStatus = CertStatus::Good;
659 }
660 } else if (input.Peek(static_cast<uint8_t>(CertStatus::Revoked))) {
661 // We don't need any info from the RevokedInfo structure, so we don't even
662 // parse it. TODO: We should mention issues like this in the explanation of
663 // why we treat invalid OCSP responses equivalently to revoked for OCSP
664 // stapling.
665 if (der::Skip(input, static_cast<uint8_t>(CertStatus::Revoked))
666 != der::Success) {
667 return der::Failure;
668 }
669 context.certStatus = CertStatus::Revoked;
670 } else if (ExpectTagAndLength(input,
671 static_cast<uint8_t>(CertStatus::Unknown),
672 0) != der::Success) {
673 return der::Failure;
674 }
675
676 // http://tools.ietf.org/html/rfc6960#section-3.2
677 // 5. The time at which the status being indicated is known to be
678 // correct (thisUpdate) is sufficiently recent;
679 // 6. When available, the time at or before which newer information will
680 // be available about the status of the certificate (nextUpdate) is
681 // greater than the current time.
682
683 const PRTime maxLifetime =
684 context.maxLifetimeInDays * ONE_DAY;
685
686 PRTime thisUpdate;
687 if (der::GeneralizedTime(input, thisUpdate) != der::Success) {
688 return der::Failure;
689 }
690
691 if (thisUpdate > context.time + SLOP) {
692 return der::Fail(SEC_ERROR_OCSP_FUTURE_RESPONSE);
693 }
694
695 PRTime notAfter;
696 static const uint8_t NEXT_UPDATE_TAG =
697 der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0;
698 if (input.Peek(NEXT_UPDATE_TAG)) {
699 PRTime nextUpdate;
700 if (der::Nested(input, NEXT_UPDATE_TAG,
701 bind(der::GeneralizedTime, _1, ref(nextUpdate)))
702 != der::Success) {
703 return der::Failure;
704 }
705
706 if (nextUpdate < thisUpdate) {
707 return der::Fail(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
708 }
709 if (nextUpdate - thisUpdate <= maxLifetime) {
710 notAfter = nextUpdate;
711 } else {
712 notAfter = thisUpdate + maxLifetime;
713 }
714 } else {
715 // NSS requires all OCSP responses without a nextUpdate to be recent.
716 // Match that stricter behavior.
717 notAfter = thisUpdate + ONE_DAY;
718 }
719
720 if (context.time < SLOP) { // prevent underflow
721 return der::Fail(SEC_ERROR_INVALID_ARGS);
722 }
723
724 if (context.time - SLOP > notAfter) {
725 context.expired = true;
726 }
727
728 if (!input.AtEnd()) {
729 if (der::Nested(input, der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
730 CheckExtensionsForCriticality) != der::Success) {
731 return der::Failure;
732 }
733 }
734
735 if (context.thisUpdate) {
736 *context.thisUpdate = thisUpdate;
737 }
738 if (context.validThrough) {
739 *context.validThrough = notAfter;
740 }
741
742 return der::Success;
743 }
744
745 // CertID ::= SEQUENCE {
746 // hashAlgorithm AlgorithmIdentifier,
747 // issuerNameHash OCTET STRING, -- Hash of issuer's DN
748 // issuerKeyHash OCTET STRING, -- Hash of issuer's public key
749 // serialNumber CertificateSerialNumber }
750 static inline der::Result
751 CertID(der::Input& input, const Context& context, /*out*/ bool& match)
752 {
753 match = false;
754
755 SECAlgorithmID hashAlgorithm;
756 if (der::Nested(input, der::SEQUENCE,
757 bind(der::AlgorithmIdentifier, _1, ref(hashAlgorithm)))
758 != der::Success) {
759 return der::Failure;
760 }
761
762 SECItem issuerNameHash;
763 if (der::Skip(input, der::OCTET_STRING, issuerNameHash) != der::Success) {
764 return der::Failure;
765 }
766
767 SECItem issuerKeyHash;
768 if (der::Skip(input, der::OCTET_STRING, issuerKeyHash) != der::Success) {
769 return der::Failure;
770 }
771
772 SECItem serialNumber;
773 if (der::CertificateSerialNumber(input, serialNumber) != der::Success) {
774 return der::Failure;
775 }
776
777 const CERTCertificate& cert = context.cert;
778 const CERTCertificate& issuerCert = context.issuerCert;
779
780 if (!SECITEM_ItemsAreEqual(&serialNumber, &cert.serialNumber)) {
781 // This does not reference the certificate we're interested in.
782 // Consume the rest of the input and return successfully to
783 // potentially continue processing other responses.
784 input.SkipToEnd();
785 return der::Success;
786 }
787
788 // TODO: support SHA-2 hashes.
789
790 SECOidTag hashAlg = SECOID_GetAlgorithmTag(&hashAlgorithm);
791 if (hashAlg != SEC_OID_SHA1) {
792 // Again, not interested in this response. Consume input, return success.
793 input.SkipToEnd();
794 return der::Success;
795 }
796
797 if (issuerNameHash.len != SHA1_LENGTH) {
798 return der::Fail(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
799 }
800
801 // From http://tools.ietf.org/html/rfc6960#section-4.1.1:
802 // "The hash shall be calculated over the DER encoding of the
803 // issuer's name field in the certificate being checked."
804 uint8_t hashBuf[SHA1_LENGTH];
805 if (PK11_HashBuf(SEC_OID_SHA1, hashBuf, cert.derIssuer.data,
806 cert.derIssuer.len) != SECSuccess) {
807 return der::Failure;
808 }
809 if (memcmp(hashBuf, issuerNameHash.data, issuerNameHash.len)) {
810 // Again, not interested in this response. Consume input, return success.
811 input.SkipToEnd();
812 return der::Success;
813 }
814
815 return MatchIssuerKey(issuerKeyHash, issuerCert, match);
816 }
817
818 // From http://tools.ietf.org/html/rfc6960#section-4.1.1:
819 // "The hash shall be calculated over the value (excluding tag and length) of
820 // the subject public key field in the issuer's certificate."
821 static der::Result
822 MatchIssuerKey(const SECItem& issuerKeyHash, const CERTCertificate& issuer,
823 /*out*/ bool& match)
824 {
825 if (issuerKeyHash.len != SHA1_LENGTH) {
826 return der::Fail(SEC_ERROR_OCSP_MALFORMED_RESPONSE);
827 }
828
829 // TODO(bug 966856): support SHA-2 hashes
830
831 // Copy just the length and data pointer (nothing needs to be freed) of the
832 // subject public key so we can convert the length from bits to bytes, which
833 // is what the digest function expects.
834 SECItem spk = issuer.subjectPublicKeyInfo.subjectPublicKey;
835 DER_ConvertBitString(&spk);
836
837 static uint8_t hashBuf[SHA1_LENGTH];
838 if (PK11_HashBuf(SEC_OID_SHA1, hashBuf, spk.data, spk.len) != SECSuccess) {
839 return der::Failure;
840 }
841
842 match = !memcmp(hashBuf, issuerKeyHash.data, issuerKeyHash.len);
843 return der::Success;
844 }
845
846 // Extension ::= SEQUENCE {
847 // extnID OBJECT IDENTIFIER,
848 // critical BOOLEAN DEFAULT FALSE,
849 // extnValue OCTET STRING
850 // }
851 static der::Result
852 CheckExtensionForCriticality(der::Input& input)
853 {
854 uint16_t toSkip;
855 if (ExpectTagAndGetLength(input, der::OIDTag, toSkip) != der::Success) {
856 return der::Failure;
857 }
858
859 // TODO: maybe we should check the syntax of the OID value
860 if (input.Skip(toSkip) != der::Success) {
861 return der::Failure;
862 }
863
864 // The only valid explicit encoding of the value is TRUE, so don't even
865 // bother parsing it, since we're going to fail either way.
866 if (input.Peek(der::BOOLEAN)) {
867 return der::Fail(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION);
868 }
869
870 if (ExpectTagAndGetLength(input, der::OCTET_STRING, toSkip)
871 != der::Success) {
872 return der::Failure;
873 }
874 return input.Skip(toSkip);
875 }
876
877 // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
878 static der::Result
879 CheckExtensionsForCriticality(der::Input& input)
880 {
881 // TODO(bug 997994): some responders include an empty SEQUENCE OF
882 // Extension, which is invalid (der::MayBeEmpty should really be
883 // der::MustNotBeEmpty).
884 return der::NestedOf(input, der::SEQUENCE, der::SEQUENCE,
885 der::MayBeEmpty, CheckExtensionForCriticality);
886 }
887
888 // 1. The certificate identified in a received response corresponds to
889 // the certificate that was identified in the corresponding request;
890 // 2. The signature on the response is valid;
891 // 3. The identity of the signer matches the intended recipient of the
892 // request;
893 // 4. The signer is currently authorized to provide a response for the
894 // certificate in question;
895 // 5. The time at which the status being indicated is known to be
896 // correct (thisUpdate) is sufficiently recent;
897 // 6. When available, the time at or before which newer information will
898 // be available about the status of the certificate (nextUpdate) is
899 // greater than the current time.
900 //
901 // Responses whose nextUpdate value is earlier than
902 // the local system time value SHOULD be considered unreliable.
903 // Responses whose thisUpdate time is later than the local system time
904 // SHOULD be considered unreliable.
905 //
906 // If nextUpdate is not set, the responder is indicating that newer
907 // revocation information is available all the time.
908 //
909 // http://tools.ietf.org/html/rfc5019#section-4
910
911 SECItem*
912 CreateEncodedOCSPRequest(PLArenaPool* arena,
913 const CERTCertificate* cert,
914 const CERTCertificate* issuerCert)
915 {
916 if (!arena || !cert || !issuerCert) {
917 PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
918 return nullptr;
919 }
920
921 // We do not add any extensions to the request.
922
923 // RFC 6960 says "An OCSP client MAY wish to specify the kinds of response
924 // types it understands. To do so, it SHOULD use an extension with the OID
925 // id-pkix-ocsp-response." This use of MAY and SHOULD is unclear. MSIE11
926 // on Windows 8.1 does not include any extensions, whereas NSS has always
927 // included the id-pkix-ocsp-response extension. Avoiding the sending the
928 // extension is better for OCSP GET because it makes the request smaller,
929 // and thus more likely to fit within the 255 byte limit for OCSP GET that
930 // is specified in RFC 5019 Section 5.
931
932 // Bug 966856: Add the id-pkix-ocsp-pref-sig-algs extension.
933
934 // Since we don't know whether the OCSP responder supports anything other
935 // than SHA-1, we have no choice but to use SHA-1 for issuerNameHash and
936 // issuerKeyHash.
937 static const uint8_t hashAlgorithm[11] = {
938 0x30, 0x09, // SEQUENCE
939 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, // OBJECT IDENTIFIER id-sha1
940 0x05, 0x00, // NULL
941 };
942 static const uint8_t hashLen = SHA1_LENGTH;
943
944 static const unsigned int totalLenWithoutSerialNumberData
945 = 2 // OCSPRequest
946 + 2 // tbsRequest
947 + 2 // requestList
948 + 2 // Request
949 + 2 // reqCert (CertID)
950 + PR_ARRAY_SIZE(hashAlgorithm) // hashAlgorithm
951 + 2 + hashLen // issuerNameHash
952 + 2 + hashLen // issuerKeyHash
953 + 2; // serialNumber (header)
954
955 // The only way we could have a request this large is if the serialNumber was
956 // ridiculously and unreasonably large. RFC 5280 says "Conforming CAs MUST
957 // NOT use serialNumber values longer than 20 octets." With this restriction,
958 // we allow for some amount of non-conformance with that requirement while
959 // still ensuring we can encode the length values in the ASN.1 TLV structures
960 // in a single byte.
961 if (issuerCert->serialNumber.len > 127u - totalLenWithoutSerialNumberData) {
962 PR_SetError(SEC_ERROR_BAD_DATA, 0);
963 return nullptr;
964 }
965
966 uint8_t totalLen = static_cast<uint8_t>(totalLenWithoutSerialNumberData +
967 cert->serialNumber.len);
968
969 SECItem* encodedRequest = SECITEM_AllocItem(arena, nullptr, totalLen);
970 if (!encodedRequest) {
971 return nullptr;
972 }
973
974 uint8_t* d = encodedRequest->data;
975 *d++ = 0x30; *d++ = totalLen - 2; // OCSPRequest (SEQUENCE)
976 *d++ = 0x30; *d++ = totalLen - 4; // tbsRequest (SEQUENCE)
977 *d++ = 0x30; *d++ = totalLen - 6; // requestList (SEQUENCE OF)
978 *d++ = 0x30; *d++ = totalLen - 8; // Request (SEQUENCE)
979 *d++ = 0x30; *d++ = totalLen - 10; // reqCert (CertID SEQUENCE)
980
981 // reqCert.hashAlgorithm
982 for (size_t i = 0; i < PR_ARRAY_SIZE(hashAlgorithm); ++i) {
983 *d++ = hashAlgorithm[i];
984 }
985
986 // reqCert.issuerNameHash (OCTET STRING)
987 *d++ = 0x04;
988 *d++ = hashLen;
989 if (PK11_HashBuf(SEC_OID_SHA1, d, issuerCert->derSubject.data,
990 issuerCert->derSubject.len) != SECSuccess) {
991 return nullptr;
992 }
993 d += hashLen;
994
995 // reqCert.issuerKeyHash (OCTET STRING)
996 *d++ = 0x04;
997 *d++ = hashLen;
998 SECItem key = issuerCert->subjectPublicKeyInfo.subjectPublicKey;
999 DER_ConvertBitString(&key);
1000 if (PK11_HashBuf(SEC_OID_SHA1, d, key.data, key.len) != SECSuccess) {
1001 return nullptr;
1002 }
1003 d += hashLen;
1004
1005 // reqCert.serialNumber (INTEGER)
1006 *d++ = 0x02; // INTEGER
1007 *d++ = static_cast<uint8_t>(cert->serialNumber.len);
1008 for (size_t i = 0; i < cert->serialNumber.len; ++i) {
1009 *d++ = cert->serialNumber.data[i];
1010 }
1011
1012 PR_ASSERT(d == encodedRequest->data + totalLen);
1013
1014 return encodedRequest;
1015 }
1016
1017 } } // namespace mozilla::pkix

mercurial