pkixocsp.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
  5. */
  6. #include <limits>
  7. #include "pkix/pkix.h"
  8. #include "pkix/pkixcheck.h"
  9. #include "pkix/pkixutil.h"
  10. namespace {
  11. const size_t SHA1_DIGEST_LENGTH = 160 / 8;
  12. } // namespace
  13. namespace mozilla { namespace pkix {
  14. // These values correspond to the tag values in the ASN.1 CertStatus
  15. enum class CertStatus : uint8_t {
  16. Good = der::CONTEXT_SPECIFIC | 0,
  17. Revoked = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
  18. Unknown = der::CONTEXT_SPECIFIC | 2
  19. };
  20. class Context final
  21. {
  22. public:
  23. Context(TrustDomain& aTrustDomain, const CertID& aCertID, Time aTime,
  24. uint16_t aMaxLifetimeInDays, /*optional out*/ Time* aThisUpdate,
  25. /*optional out*/ Time* aValidThrough)
  26. : trustDomain(aTrustDomain)
  27. , certID(aCertID)
  28. , time(aTime)
  29. , maxLifetimeInDays(aMaxLifetimeInDays)
  30. , certStatus(CertStatus::Unknown)
  31. , thisUpdate(aThisUpdate)
  32. , validThrough(aValidThrough)
  33. , expired(false)
  34. , matchFound(false)
  35. {
  36. if (thisUpdate) {
  37. *thisUpdate = TimeFromElapsedSecondsAD(0);
  38. }
  39. if (validThrough) {
  40. *validThrough = TimeFromElapsedSecondsAD(0);
  41. }
  42. }
  43. TrustDomain& trustDomain;
  44. const CertID& certID;
  45. const Time time;
  46. const uint16_t maxLifetimeInDays;
  47. CertStatus certStatus;
  48. Time* thisUpdate;
  49. Time* validThrough;
  50. bool expired;
  51. Input signedCertificateTimestamps;
  52. // Keep track of whether the OCSP response contains the status of the
  53. // certificate we're interested in. Responders might reply without
  54. // including the status of any of the requested certs, we should
  55. // indicate a server failure in those cases.
  56. bool matchFound;
  57. Context(const Context&) = delete;
  58. void operator=(const Context&) = delete;
  59. };
  60. // Verify that potentialSigner is a valid delegated OCSP response signing cert
  61. // according to RFC 6960 section 4.2.2.2.
  62. static Result
  63. CheckOCSPResponseSignerCert(TrustDomain& trustDomain,
  64. BackCert& potentialSigner,
  65. Input issuerSubject,
  66. Input issuerSubjectPublicKeyInfo,
  67. Time time)
  68. {
  69. Result rv;
  70. // We don't need to do a complete verification of the signer (i.e. we don't
  71. // have to call BuildCertChain to verify the entire chain) because we
  72. // already know that the issuer is valid, since revocation checking is done
  73. // from the root to the parent after we've built a complete chain that we
  74. // know is otherwise valid. Rather, we just need to do a one-step validation
  75. // from potentialSigner to the issuer.
  76. //
  77. // It seems reasonable to require the KU_DIGITAL_SIGNATURE key usage on the
  78. // OCSP responder certificate if the OCSP responder certificate has a
  79. // key usage extension. However, according to bug 240456, some OCSP responder
  80. // certificates may have only the nonRepudiation bit set. Also, the OCSP
  81. // specification (RFC 6960) does not mandate any particular key usage to be
  82. // asserted for OCSP responde signers. Oddly, the CABForum Baseline
  83. // Requirements v.1.1.5 do say "If the Root CA Private Key is used for
  84. // signing OCSP responses, then the digitalSignature bit MUST be set."
  85. //
  86. // Note that CheckIssuerIndependentProperties processes
  87. // SEC_OID_OCSP_RESPONDER in the way that the OCSP specification requires us
  88. // to--in particular, it doesn't allow SEC_OID_OCSP_RESPONDER to be implied
  89. // by a missing EKU extension, unlike other EKUs.
  90. //
  91. // TODO(bug 926261): If we're validating for a policy then the policy OID we
  92. // are validating for should be passed to CheckIssuerIndependentProperties.
  93. TrustLevel unusedTrustLevel;
  94. rv = CheckIssuerIndependentProperties(trustDomain, potentialSigner, time,
  95. KeyUsage::noParticularKeyUsageRequired,
  96. KeyPurposeId::id_kp_OCSPSigning,
  97. CertPolicyId::anyPolicy, 0,
  98. unusedTrustLevel);
  99. if (rv != Success) {
  100. return rv;
  101. }
  102. // It is possible that there exists a certificate with the same key as the
  103. // issuer but with a different name, so we need to compare names
  104. // XXX(bug 926270) XXX(bug 1008133) XXX(bug 980163): Improve name
  105. // comparison.
  106. // TODO: needs test
  107. if (!InputsAreEqual(potentialSigner.GetIssuer(), issuerSubject)) {
  108. return Result::ERROR_OCSP_RESPONDER_CERT_INVALID;
  109. }
  110. // TODO(bug 926260): check name constraints
  111. rv = VerifySignedData(trustDomain, potentialSigner.GetSignedData(),
  112. issuerSubjectPublicKeyInfo);
  113. // TODO: check for revocation of the OCSP responder certificate unless no-check
  114. // or the caller forcing no-check. To properly support the no-check policy, we'd
  115. // need to enforce policy constraints from the issuerChain.
  116. return rv;
  117. }
  118. enum class ResponderIDType : uint8_t
  119. {
  120. byName = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
  121. byKey = der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 2
  122. };
  123. static inline Result OCSPResponse(Reader&, Context&);
  124. static inline Result ResponseBytes(Reader&, Context&);
  125. static inline Result BasicResponse(Reader&, Context&);
  126. static inline Result ResponseData(
  127. Reader& tbsResponseData,
  128. Context& context,
  129. const der::SignedDataWithSignature& signedResponseData,
  130. const DERArray& certs);
  131. static inline Result SingleResponse(Reader& input, Context& context);
  132. static Result ExtensionNotUnderstood(Reader& extnID, Input extnValue,
  133. bool critical, /*out*/ bool& understood);
  134. static Result RememberSingleExtension(Context& context, Reader& extnID,
  135. Input extnValue, bool critical,
  136. /*out*/ bool& understood);
  137. // It is convention to name the function after the part of the data structure
  138. // we're parsing from the RFC (e.g. OCSPResponse, ResponseBytes).
  139. // But since we also have a C++ type called CertID, this function doesn't
  140. // follow the convention to prevent shadowing.
  141. static inline Result MatchCertID(Reader& input,
  142. const Context& context,
  143. /*out*/ bool& match);
  144. static Result MatchKeyHash(TrustDomain& trustDomain,
  145. Input issuerKeyHash,
  146. Input issuerSubjectPublicKeyInfo,
  147. /*out*/ bool& match);
  148. static Result KeyHash(TrustDomain& trustDomain,
  149. Input subjectPublicKeyInfo,
  150. /*out*/ uint8_t* hashBuf, size_t hashBufSize);
  151. static Result
  152. MatchResponderID(TrustDomain& trustDomain,
  153. ResponderIDType responderIDType,
  154. Input responderID,
  155. Input potentialSignerSubject,
  156. Input potentialSignerSubjectPublicKeyInfo,
  157. /*out*/ bool& match)
  158. {
  159. match = false;
  160. switch (responderIDType) {
  161. case ResponderIDType::byName:
  162. // XXX(bug 926270) XXX(bug 1008133) XXX(bug 980163): Improve name
  163. // comparison.
  164. match = InputsAreEqual(responderID, potentialSignerSubject);
  165. return Success;
  166. case ResponderIDType::byKey:
  167. {
  168. Reader input(responderID);
  169. Input keyHash;
  170. Result rv = der::ExpectTagAndGetValue(input, der::OCTET_STRING, keyHash);
  171. if (rv != Success) {
  172. return rv;
  173. }
  174. return MatchKeyHash(trustDomain, keyHash,
  175. potentialSignerSubjectPublicKeyInfo, match);
  176. }
  177. MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
  178. }
  179. }
  180. static Result
  181. VerifyOCSPSignedData(TrustDomain& trustDomain,
  182. const der::SignedDataWithSignature& signedResponseData,
  183. Input spki)
  184. {
  185. Result rv = VerifySignedData(trustDomain, signedResponseData, spki);
  186. if (rv == Result::ERROR_BAD_SIGNATURE) {
  187. rv = Result::ERROR_OCSP_BAD_SIGNATURE;
  188. }
  189. return rv;
  190. }
  191. // RFC 6960 section 4.2.2.2: The OCSP responder must either be the issuer of
  192. // the cert or it must be a delegated OCSP response signing cert directly
  193. // issued by the issuer. If the OCSP responder is a delegated OCSP response
  194. // signer, then its certificate is (probably) embedded within the OCSP
  195. // response and we'll need to verify that it is a valid certificate that chains
  196. // *directly* to issuerCert.
  197. static Result
  198. VerifySignature(Context& context, ResponderIDType responderIDType,
  199. Input responderID, const DERArray& certs,
  200. const der::SignedDataWithSignature& signedResponseData)
  201. {
  202. bool match;
  203. Result rv = MatchResponderID(context.trustDomain, responderIDType,
  204. responderID, context.certID.issuer,
  205. context.certID.issuerSubjectPublicKeyInfo,
  206. match);
  207. if (rv != Success) {
  208. return rv;
  209. }
  210. if (match) {
  211. return VerifyOCSPSignedData(context.trustDomain, signedResponseData,
  212. context.certID.issuerSubjectPublicKeyInfo);
  213. }
  214. size_t numCerts = certs.GetLength();
  215. for (size_t i = 0; i < numCerts; ++i) {
  216. BackCert cert(*certs.GetDER(i), EndEntityOrCA::MustBeEndEntity, nullptr);
  217. rv = cert.Init();
  218. if (rv != Success) {
  219. return rv;
  220. }
  221. rv = MatchResponderID(context.trustDomain, responderIDType, responderID,
  222. cert.GetSubject(), cert.GetSubjectPublicKeyInfo(),
  223. match);
  224. if (rv != Success) {
  225. if (IsFatalError(rv)) {
  226. return rv;
  227. }
  228. continue;
  229. }
  230. if (match) {
  231. rv = CheckOCSPResponseSignerCert(context.trustDomain, cert,
  232. context.certID.issuer,
  233. context.certID.issuerSubjectPublicKeyInfo,
  234. context.time);
  235. if (rv != Success) {
  236. if (IsFatalError(rv)) {
  237. return rv;
  238. }
  239. continue;
  240. }
  241. return VerifyOCSPSignedData(context.trustDomain, signedResponseData,
  242. cert.GetSubjectPublicKeyInfo());
  243. }
  244. }
  245. return Result::ERROR_OCSP_INVALID_SIGNING_CERT;
  246. }
  247. static inline Result
  248. MapBadDERToMalformedOCSPResponse(Result rv)
  249. {
  250. if (rv == Result::ERROR_BAD_DER) {
  251. return Result::ERROR_OCSP_MALFORMED_RESPONSE;
  252. }
  253. return rv;
  254. }
  255. Result
  256. VerifyEncodedOCSPResponse(TrustDomain& trustDomain, const struct CertID& certID,
  257. Time time, uint16_t maxOCSPLifetimeInDays,
  258. Input encodedResponse,
  259. /*out*/ bool& expired,
  260. /*optional out*/ Time* thisUpdate,
  261. /*optional out*/ Time* validThrough)
  262. {
  263. // Always initialize this to something reasonable.
  264. expired = false;
  265. Context context(trustDomain, certID, time, maxOCSPLifetimeInDays,
  266. thisUpdate, validThrough);
  267. Reader input(encodedResponse);
  268. Result rv = der::Nested(input, der::SEQUENCE, [&context](Reader& r) {
  269. return OCSPResponse(r, context);
  270. });
  271. if (rv != Success) {
  272. return MapBadDERToMalformedOCSPResponse(rv);
  273. }
  274. rv = der::End(input);
  275. if (rv != Success) {
  276. return MapBadDERToMalformedOCSPResponse(rv);
  277. }
  278. if (!context.matchFound) {
  279. return Result::ERROR_OCSP_RESPONSE_FOR_CERT_MISSING;
  280. }
  281. expired = context.expired;
  282. switch (context.certStatus) {
  283. case CertStatus::Good:
  284. if (expired) {
  285. return Result::ERROR_OCSP_OLD_RESPONSE;
  286. }
  287. if (context.signedCertificateTimestamps.GetLength()) {
  288. Input sctList;
  289. rv = ExtractSignedCertificateTimestampListFromExtension(
  290. context.signedCertificateTimestamps, sctList);
  291. if (rv != Success) {
  292. return MapBadDERToMalformedOCSPResponse(rv);
  293. }
  294. context.trustDomain.NoteAuxiliaryExtension(
  295. AuxiliaryExtension::SCTListFromOCSPResponse, sctList);
  296. }
  297. return Success;
  298. case CertStatus::Revoked:
  299. return Result::ERROR_REVOKED_CERTIFICATE;
  300. case CertStatus::Unknown:
  301. return Result::ERROR_OCSP_UNKNOWN_CERT;
  302. MOZILLA_PKIX_UNREACHABLE_DEFAULT_ENUM
  303. }
  304. }
  305. // OCSPResponse ::= SEQUENCE {
  306. // responseStatus OCSPResponseStatus,
  307. // responseBytes [0] EXPLICIT ResponseBytes OPTIONAL }
  308. //
  309. static inline Result
  310. OCSPResponse(Reader& input, Context& context)
  311. {
  312. // OCSPResponseStatus ::= ENUMERATED {
  313. // successful (0), -- Response has valid confirmations
  314. // malformedRequest (1), -- Illegal confirmation request
  315. // internalError (2), -- Internal error in issuer
  316. // tryLater (3), -- Try again later
  317. // -- (4) is not used
  318. // sigRequired (5), -- Must sign the request
  319. // unauthorized (6) -- Request unauthorized
  320. // }
  321. uint8_t responseStatus;
  322. Result rv = der::Enumerated(input, responseStatus);
  323. if (rv != Success) {
  324. return rv;
  325. }
  326. switch (responseStatus) {
  327. case 0: break; // successful
  328. case 1: return Result::ERROR_OCSP_MALFORMED_REQUEST;
  329. case 2: return Result::ERROR_OCSP_SERVER_ERROR;
  330. case 3: return Result::ERROR_OCSP_TRY_SERVER_LATER;
  331. case 5: return Result::ERROR_OCSP_REQUEST_NEEDS_SIG;
  332. case 6: return Result::ERROR_OCSP_UNAUTHORIZED_REQUEST;
  333. default: return Result::ERROR_OCSP_UNKNOWN_RESPONSE_STATUS;
  334. }
  335. return der::Nested(input, der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
  336. der::SEQUENCE, [&context](Reader& r) {
  337. return ResponseBytes(r, context);
  338. });
  339. }
  340. // ResponseBytes ::= SEQUENCE {
  341. // responseType OBJECT IDENTIFIER,
  342. // response OCTET STRING }
  343. static inline Result
  344. ResponseBytes(Reader& input, Context& context)
  345. {
  346. static const uint8_t id_pkix_ocsp_basic[] = {
  347. 0x2B, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
  348. };
  349. Result rv = der::OID(input, id_pkix_ocsp_basic);
  350. if (rv != Success) {
  351. return rv;
  352. }
  353. return der::Nested(input, der::OCTET_STRING, der::SEQUENCE,
  354. [&context](Reader& r) {
  355. return BasicResponse(r, context);
  356. });
  357. }
  358. // BasicOCSPResponse ::= SEQUENCE {
  359. // tbsResponseData ResponseData,
  360. // signatureAlgorithm AlgorithmIdentifier,
  361. // signature BIT STRING,
  362. // certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL }
  363. Result
  364. BasicResponse(Reader& input, Context& context)
  365. {
  366. Reader tbsResponseData;
  367. der::SignedDataWithSignature signedData;
  368. Result rv = der::SignedData(input, tbsResponseData, signedData);
  369. if (rv != Success) {
  370. if (rv == Result::ERROR_BAD_SIGNATURE) {
  371. return Result::ERROR_OCSP_BAD_SIGNATURE;
  372. }
  373. return rv;
  374. }
  375. // Parse certificates, if any
  376. NonOwningDERArray certs;
  377. if (!input.AtEnd()) {
  378. rv = der::Nested(input, der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0,
  379. der::SEQUENCE, [&certs](Reader& certsDER) -> Result {
  380. while (!certsDER.AtEnd()) {
  381. Input cert;
  382. Result nestedRv =
  383. der::ExpectTagAndGetTLV(certsDER, der::SEQUENCE, cert);
  384. if (nestedRv != Success) {
  385. return nestedRv;
  386. }
  387. nestedRv = certs.Append(cert);
  388. if (nestedRv != Success) {
  389. return Result::ERROR_BAD_DER; // Too many certs
  390. }
  391. }
  392. return Success;
  393. });
  394. if (rv != Success) {
  395. return rv;
  396. }
  397. }
  398. return ResponseData(tbsResponseData, context, signedData, certs);
  399. }
  400. // ResponseData ::= SEQUENCE {
  401. // version [0] EXPLICIT Version DEFAULT v1,
  402. // responderID ResponderID,
  403. // producedAt GeneralizedTime,
  404. // responses SEQUENCE OF SingleResponse,
  405. // responseExtensions [1] EXPLICIT Extensions OPTIONAL }
  406. static inline Result
  407. ResponseData(Reader& input, Context& context,
  408. const der::SignedDataWithSignature& signedResponseData,
  409. const DERArray& certs)
  410. {
  411. der::Version version;
  412. Result rv = der::OptionalVersion(input, version);
  413. if (rv != Success) {
  414. return rv;
  415. }
  416. if (version != der::Version::v1) {
  417. // TODO: more specific error code for bad version?
  418. return Result::ERROR_BAD_DER;
  419. }
  420. // ResponderID ::= CHOICE {
  421. // byName [1] Name,
  422. // byKey [2] KeyHash }
  423. Input responderID;
  424. ResponderIDType responderIDType
  425. = input.Peek(static_cast<uint8_t>(ResponderIDType::byName))
  426. ? ResponderIDType::byName
  427. : ResponderIDType::byKey;
  428. rv = der::ExpectTagAndGetValue(input, static_cast<uint8_t>(responderIDType),
  429. responderID);
  430. if (rv != Success) {
  431. return rv;
  432. }
  433. // This is the soonest we can verify the signature. We verify the signature
  434. // right away to follow the principal of minimizing the processing of data
  435. // before verifying its signature.
  436. rv = VerifySignature(context, responderIDType, responderID, certs,
  437. signedResponseData);
  438. if (rv != Success) {
  439. return rv;
  440. }
  441. // TODO: Do we even need to parse this? Should we just skip it?
  442. Time producedAt(Time::uninitialized);
  443. rv = der::GeneralizedTime(input, producedAt);
  444. if (rv != Success) {
  445. return rv;
  446. }
  447. // We don't accept an empty sequence of responses. In practice, a legit OCSP
  448. // responder will never return an empty response, and handling the case of an
  449. // empty response makes things unnecessarily complicated.
  450. rv = der::NestedOf(input, der::SEQUENCE, der::SEQUENCE,
  451. der::EmptyAllowed::No, [&context](Reader& r) {
  452. return SingleResponse(r, context);
  453. });
  454. if (rv != Success) {
  455. return rv;
  456. }
  457. return der::OptionalExtensions(input,
  458. der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
  459. ExtensionNotUnderstood);
  460. }
  461. // SingleResponse ::= SEQUENCE {
  462. // certID CertID,
  463. // certStatus CertStatus,
  464. // thisUpdate GeneralizedTime,
  465. // nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL,
  466. // singleExtensions [1] EXPLICIT Extensions{{re-ocsp-crl |
  467. // re-ocsp-archive-cutoff |
  468. // CrlEntryExtensions, ...}
  469. // } OPTIONAL }
  470. static inline Result
  471. SingleResponse(Reader& input, Context& context)
  472. {
  473. bool match = false;
  474. Result rv = der::Nested(input, der::SEQUENCE, [&context, &match](Reader& r) {
  475. return MatchCertID(r, context, match);
  476. });
  477. if (rv != Success) {
  478. return rv;
  479. }
  480. if (!match) {
  481. // This response does not reference the certificate we're interested in.
  482. // By consuming the rest of our input and returning successfully, we can
  483. // continue processing and examine another response that might have what
  484. // we want.
  485. input.SkipToEnd();
  486. return Success;
  487. }
  488. // We found a response for the cert we're interested in.
  489. context.matchFound = true;
  490. // CertStatus ::= CHOICE {
  491. // good [0] IMPLICIT NULL,
  492. // revoked [1] IMPLICIT RevokedInfo,
  493. // unknown [2] IMPLICIT UnknownInfo }
  494. //
  495. // In the event of multiple SingleResponses for a cert that have conflicting
  496. // statuses, we use the following precedence rules:
  497. //
  498. // * revoked overrides good and unknown
  499. // * good overrides unknown
  500. if (input.Peek(static_cast<uint8_t>(CertStatus::Good))) {
  501. rv = der::ExpectTagAndEmptyValue(input,
  502. static_cast<uint8_t>(CertStatus::Good));
  503. if (rv != Success) {
  504. return rv;
  505. }
  506. if (context.certStatus != CertStatus::Revoked) {
  507. context.certStatus = CertStatus::Good;
  508. }
  509. } else if (input.Peek(static_cast<uint8_t>(CertStatus::Revoked))) {
  510. // We don't need any info from the RevokedInfo structure, so we don't even
  511. // parse it. TODO: We should mention issues like this in the explanation of
  512. // why we treat invalid OCSP responses equivalently to revoked for OCSP
  513. // stapling.
  514. rv = der::ExpectTagAndSkipValue(input,
  515. static_cast<uint8_t>(CertStatus::Revoked));
  516. if (rv != Success) {
  517. return rv;
  518. }
  519. context.certStatus = CertStatus::Revoked;
  520. } else {
  521. rv = der::ExpectTagAndEmptyValue(input,
  522. static_cast<uint8_t>(CertStatus::Unknown));
  523. if (rv != Success) {
  524. return rv;
  525. }
  526. }
  527. // http://tools.ietf.org/html/rfc6960#section-3.2
  528. // 5. The time at which the status being indicated is known to be
  529. // correct (thisUpdate) is sufficiently recent;
  530. // 6. When available, the time at or before which newer information will
  531. // be available about the status of the certificate (nextUpdate) is
  532. // greater than the current time.
  533. Time thisUpdate(Time::uninitialized);
  534. rv = der::GeneralizedTime(input, thisUpdate);
  535. if (rv != Success) {
  536. return rv;
  537. }
  538. static const uint64_t SLOP_SECONDS = Time::ONE_DAY_IN_SECONDS;
  539. Time timePlusSlop(context.time);
  540. rv = timePlusSlop.AddSeconds(SLOP_SECONDS);
  541. if (rv != Success) {
  542. return rv;
  543. }
  544. if (thisUpdate > timePlusSlop) {
  545. return Result::ERROR_OCSP_FUTURE_RESPONSE;
  546. }
  547. Time notAfter(Time::uninitialized);
  548. static const uint8_t NEXT_UPDATE_TAG =
  549. der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 0;
  550. if (input.Peek(NEXT_UPDATE_TAG)) {
  551. Time nextUpdate(Time::uninitialized);
  552. rv = der::Nested(input, NEXT_UPDATE_TAG, [&nextUpdate](Reader& r) {
  553. return der::GeneralizedTime(r, nextUpdate);
  554. });
  555. if (rv != Success) {
  556. return rv;
  557. }
  558. if (nextUpdate < thisUpdate) {
  559. return Result::ERROR_OCSP_MALFORMED_RESPONSE;
  560. }
  561. notAfter = thisUpdate;
  562. if (notAfter.AddSeconds(context.maxLifetimeInDays *
  563. Time::ONE_DAY_IN_SECONDS) != Success) {
  564. // This could only happen if we're dealing with times beyond the year
  565. // 10,000AD.
  566. return Result::ERROR_OCSP_FUTURE_RESPONSE;
  567. }
  568. if (nextUpdate <= notAfter) {
  569. notAfter = nextUpdate;
  570. }
  571. } else {
  572. // NSS requires all OCSP responses without a nextUpdate to be recent.
  573. // Match that stricter behavior.
  574. notAfter = thisUpdate;
  575. if (notAfter.AddSeconds(Time::ONE_DAY_IN_SECONDS) != Success) {
  576. // This could only happen if we're dealing with times beyond the year
  577. // 10,000AD.
  578. return Result::ERROR_OCSP_FUTURE_RESPONSE;
  579. }
  580. }
  581. // Add some slop to hopefully handle clock-skew.
  582. Time notAfterPlusSlop(notAfter);
  583. rv = notAfterPlusSlop.AddSeconds(SLOP_SECONDS);
  584. if (rv != Success) {
  585. // This could only happen if we're dealing with times beyond the year
  586. // 10,000AD.
  587. return Result::ERROR_OCSP_FUTURE_RESPONSE;
  588. }
  589. if (context.time > notAfterPlusSlop) {
  590. context.expired = true;
  591. }
  592. rv = der::OptionalExtensions(
  593. input,
  594. der::CONTEXT_SPECIFIC | der::CONSTRUCTED | 1,
  595. [&context](Reader& extnID, const Input& extnValue, bool critical,
  596. /*out*/ bool& understood) {
  597. return RememberSingleExtension(context, extnID, extnValue, critical,
  598. understood);
  599. });
  600. if (rv != Success) {
  601. return rv;
  602. }
  603. if (context.thisUpdate) {
  604. *context.thisUpdate = thisUpdate;
  605. }
  606. if (context.validThrough) {
  607. *context.validThrough = notAfterPlusSlop;
  608. }
  609. return Success;
  610. }
  611. // CertID ::= SEQUENCE {
  612. // hashAlgorithm AlgorithmIdentifier,
  613. // issuerNameHash OCTET STRING, -- Hash of issuer's DN
  614. // issuerKeyHash OCTET STRING, -- Hash of issuer's public key
  615. // serialNumber CertificateSerialNumber }
  616. static inline Result
  617. MatchCertID(Reader& input, const Context& context, /*out*/ bool& match)
  618. {
  619. match = false;
  620. DigestAlgorithm hashAlgorithm;
  621. Result rv = der::DigestAlgorithmIdentifier(input, hashAlgorithm);
  622. if (rv != Success) {
  623. if (rv == Result::ERROR_INVALID_ALGORITHM) {
  624. // Skip entries that are hashed with algorithms we don't support.
  625. input.SkipToEnd();
  626. return Success;
  627. }
  628. return rv;
  629. }
  630. Input issuerNameHash;
  631. rv = der::ExpectTagAndGetValue(input, der::OCTET_STRING, issuerNameHash);
  632. if (rv != Success) {
  633. return rv;
  634. }
  635. Input issuerKeyHash;
  636. rv = der::ExpectTagAndGetValue(input, der::OCTET_STRING, issuerKeyHash);
  637. if (rv != Success) {
  638. return rv;
  639. }
  640. Input serialNumber;
  641. rv = der::CertificateSerialNumber(input, serialNumber);
  642. if (rv != Success) {
  643. return rv;
  644. }
  645. if (!InputsAreEqual(serialNumber, context.certID.serialNumber)) {
  646. // This does not reference the certificate we're interested in.
  647. // Consume the rest of the input and return successfully to
  648. // potentially continue processing other responses.
  649. input.SkipToEnd();
  650. return Success;
  651. }
  652. // TODO: support SHA-2 hashes.
  653. if (hashAlgorithm != DigestAlgorithm::sha1) {
  654. // Again, not interested in this response. Consume input, return success.
  655. input.SkipToEnd();
  656. return Success;
  657. }
  658. if (issuerNameHash.GetLength() != SHA1_DIGEST_LENGTH) {
  659. return Result::ERROR_OCSP_MALFORMED_RESPONSE;
  660. }
  661. // From http://tools.ietf.org/html/rfc6960#section-4.1.1:
  662. // "The hash shall be calculated over the DER encoding of the
  663. // issuer's name field in the certificate being checked."
  664. uint8_t hashBuf[SHA1_DIGEST_LENGTH];
  665. rv = context.trustDomain.DigestBuf(context.certID.issuer,
  666. DigestAlgorithm::sha1, hashBuf,
  667. sizeof(hashBuf));
  668. if (rv != Success) {
  669. return rv;
  670. }
  671. Input computed(hashBuf);
  672. if (!InputsAreEqual(computed, issuerNameHash)) {
  673. // Again, not interested in this response. Consume input, return success.
  674. input.SkipToEnd();
  675. return Success;
  676. }
  677. return MatchKeyHash(context.trustDomain, issuerKeyHash,
  678. context.certID.issuerSubjectPublicKeyInfo, match);
  679. }
  680. // From http://tools.ietf.org/html/rfc6960#section-4.1.1:
  681. // "The hash shall be calculated over the value (excluding tag and length) of
  682. // the subject public key field in the issuer's certificate."
  683. //
  684. // From http://tools.ietf.org/html/rfc6960#appendix-B.1:
  685. // KeyHash ::= OCTET STRING -- SHA-1 hash of responder's public key
  686. // -- (i.e., the SHA-1 hash of the value of the
  687. // -- BIT STRING subjectPublicKey [excluding
  688. // -- the tag, length, and number of unused
  689. // -- bits] in the responder's certificate)
  690. static Result
  691. MatchKeyHash(TrustDomain& trustDomain, Input keyHash,
  692. const Input subjectPublicKeyInfo, /*out*/ bool& match)
  693. {
  694. if (keyHash.GetLength() != SHA1_DIGEST_LENGTH) {
  695. return Result::ERROR_OCSP_MALFORMED_RESPONSE;
  696. }
  697. uint8_t hashBuf[SHA1_DIGEST_LENGTH];
  698. Result rv = KeyHash(trustDomain, subjectPublicKeyInfo, hashBuf,
  699. sizeof hashBuf);
  700. if (rv != Success) {
  701. return rv;
  702. }
  703. Input computed(hashBuf);
  704. match = InputsAreEqual(computed, keyHash);
  705. return Success;
  706. }
  707. // TODO(bug 966856): support SHA-2 hashes
  708. Result
  709. KeyHash(TrustDomain& trustDomain, const Input subjectPublicKeyInfo,
  710. /*out*/ uint8_t* hashBuf, size_t hashBufSize)
  711. {
  712. if (!hashBuf || hashBufSize != SHA1_DIGEST_LENGTH) {
  713. return Result::FATAL_ERROR_LIBRARY_FAILURE;
  714. }
  715. // RFC 5280 Section 4.1
  716. //
  717. // SubjectPublicKeyInfo ::= SEQUENCE {
  718. // algorithm AlgorithmIdentifier,
  719. // subjectPublicKey BIT STRING }
  720. Reader spki;
  721. Result rv = der::ExpectTagAndGetValueAtEnd(subjectPublicKeyInfo,
  722. der::SEQUENCE, spki);
  723. if (rv != Success) {
  724. return rv;
  725. }
  726. // Skip AlgorithmIdentifier
  727. rv = der::ExpectTagAndSkipValue(spki, der::SEQUENCE);
  728. if (rv != Success) {
  729. return rv;
  730. }
  731. Input subjectPublicKey;
  732. rv = der::BitStringWithNoUnusedBits(spki, subjectPublicKey);
  733. if (rv != Success) {
  734. return rv;
  735. }
  736. rv = der::End(spki);
  737. if (rv != Success) {
  738. return rv;
  739. }
  740. return trustDomain.DigestBuf(subjectPublicKey, DigestAlgorithm::sha1,
  741. hashBuf, hashBufSize);
  742. }
  743. Result
  744. ExtensionNotUnderstood(Reader& /*extnID*/, Input /*extnValue*/,
  745. bool /*critical*/, /*out*/ bool& understood)
  746. {
  747. understood = false;
  748. return Success;
  749. }
  750. Result
  751. RememberSingleExtension(Context& context, Reader& extnID, Input extnValue,
  752. bool /*critical*/, /*out*/ bool& understood)
  753. {
  754. understood = false;
  755. // SingleExtension for Signed Certificate Timestamp List.
  756. // See Section 3.3 of RFC 6962.
  757. // python DottedOIDToCode.py
  758. // id_ocsp_singleExtensionSctList 1.3.6.1.4.1.11129.2.4.5
  759. static const uint8_t id_ocsp_singleExtensionSctList[] = {
  760. 0x2b, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x04, 0x05
  761. };
  762. if (extnID.MatchRest(id_ocsp_singleExtensionSctList)) {
  763. // Empty values are not allowed for this extension. Note that
  764. // we assume this later, when checking if the extension was present.
  765. if (extnValue.GetLength() == 0) {
  766. return Result::ERROR_EXTENSION_VALUE_INVALID;
  767. }
  768. if (context.signedCertificateTimestamps.Init(extnValue) != Success) {
  769. // Duplicate extension.
  770. return Result::ERROR_EXTENSION_VALUE_INVALID;
  771. }
  772. understood = true;
  773. }
  774. return Success;
  775. }
  776. // 1. The certificate identified in a received response corresponds to
  777. // the certificate that was identified in the corresponding request;
  778. // 2. The signature on the response is valid;
  779. // 3. The identity of the signer matches the intended recipient of the
  780. // request;
  781. // 4. The signer is currently authorized to provide a response for the
  782. // certificate in question;
  783. // 5. The time at which the status being indicated is known to be
  784. // correct (thisUpdate) is sufficiently recent;
  785. // 6. When available, the time at or before which newer information will
  786. // be available about the status of the certificate (nextUpdate) is
  787. // greater than the current time.
  788. //
  789. // Responses whose nextUpdate value is earlier than
  790. // the local system time value SHOULD be considered unreliable.
  791. // Responses whose thisUpdate time is later than the local system time
  792. // SHOULD be considered unreliable.
  793. //
  794. // If nextUpdate is not set, the responder is indicating that newer
  795. // revocation information is available all the time.
  796. //
  797. // http://tools.ietf.org/html/rfc5019#section-4
  798. Result
  799. CreateEncodedOCSPRequest(TrustDomain& trustDomain, const struct CertID& certID,
  800. /*out*/ uint8_t (&out)[OCSP_REQUEST_MAX_LENGTH],
  801. /*out*/ size_t& outLen)
  802. {
  803. // We do not add any extensions to the request.
  804. // RFC 6960 says "An OCSP client MAY wish to specify the kinds of response
  805. // types it understands. To do so, it SHOULD use an extension with the OID
  806. // id-pkix-ocsp-response." This use of MAY and SHOULD is unclear. MSIE11
  807. // on Windows 8.1 does not include any extensions, whereas NSS has always
  808. // included the id-pkix-ocsp-response extension. Avoiding the sending the
  809. // extension is better for OCSP GET because it makes the request smaller,
  810. // and thus more likely to fit within the 255 byte limit for OCSP GET that
  811. // is specified in RFC 5019 Section 5.
  812. // Bug 966856: Add the id-pkix-ocsp-pref-sig-algs extension.
  813. // Since we don't know whether the OCSP responder supports anything other
  814. // than SHA-1, we have no choice but to use SHA-1 for issuerNameHash and
  815. // issuerKeyHash.
  816. static const uint8_t hashAlgorithm[11] = {
  817. 0x30, 0x09, // SEQUENCE
  818. 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, // OBJECT IDENTIFIER id-sha1
  819. 0x05, 0x00, // NULL
  820. };
  821. static const uint8_t hashLen = 160 / 8;
  822. static const unsigned int totalLenWithoutSerialNumberData
  823. = 2 // OCSPRequest
  824. + 2 // tbsRequest
  825. + 2 // requestList
  826. + 2 // Request
  827. + 2 // reqCert (CertID)
  828. + sizeof(hashAlgorithm) // hashAlgorithm
  829. + 2 + hashLen // issuerNameHash
  830. + 2 + hashLen // issuerKeyHash
  831. + 2; // serialNumber (header)
  832. // The only way we could have a request this large is if the serialNumber was
  833. // ridiculously and unreasonably large. RFC 5280 says "Conforming CAs MUST
  834. // NOT use serialNumber values longer than 20 octets." With this restriction,
  835. // we allow for some amount of non-conformance with that requirement while
  836. // still ensuring we can encode the length values in the ASN.1 TLV structures
  837. // in a single byte.
  838. static_assert(totalLenWithoutSerialNumberData < OCSP_REQUEST_MAX_LENGTH,
  839. "totalLenWithoutSerialNumberData too big");
  840. if (certID.serialNumber.GetLength() >
  841. OCSP_REQUEST_MAX_LENGTH - totalLenWithoutSerialNumberData) {
  842. return Result::ERROR_BAD_DER;
  843. }
  844. outLen = totalLenWithoutSerialNumberData + certID.serialNumber.GetLength();
  845. uint8_t totalLen = static_cast<uint8_t>(outLen);
  846. uint8_t* d = out;
  847. *d++ = 0x30; *d++ = totalLen - 2u; // OCSPRequest (SEQUENCE)
  848. *d++ = 0x30; *d++ = totalLen - 4u; // tbsRequest (SEQUENCE)
  849. *d++ = 0x30; *d++ = totalLen - 6u; // requestList (SEQUENCE OF)
  850. *d++ = 0x30; *d++ = totalLen - 8u; // Request (SEQUENCE)
  851. *d++ = 0x30; *d++ = totalLen - 10u; // reqCert (CertID SEQUENCE)
  852. // reqCert.hashAlgorithm
  853. for (const uint8_t hashAlgorithmByte : hashAlgorithm) {
  854. *d++ = hashAlgorithmByte;
  855. }
  856. // reqCert.issuerNameHash (OCTET STRING)
  857. *d++ = 0x04;
  858. *d++ = hashLen;
  859. Result rv = trustDomain.DigestBuf(certID.issuer, DigestAlgorithm::sha1, d,
  860. hashLen);
  861. if (rv != Success) {
  862. return rv;
  863. }
  864. d += hashLen;
  865. // reqCert.issuerKeyHash (OCTET STRING)
  866. *d++ = 0x04;
  867. *d++ = hashLen;
  868. rv = KeyHash(trustDomain, certID.issuerSubjectPublicKeyInfo, d, hashLen);
  869. if (rv != Success) {
  870. return rv;
  871. }
  872. d += hashLen;
  873. // reqCert.serialNumber (INTEGER)
  874. *d++ = 0x02; // INTEGER
  875. *d++ = static_cast<uint8_t>(certID.serialNumber.GetLength());
  876. Reader serialNumber(certID.serialNumber);
  877. do {
  878. rv = serialNumber.Read(*d);
  879. if (rv != Success) {
  880. return rv;
  881. }
  882. ++d;
  883. } while (!serialNumber.AtEnd());
  884. assert(d == out + totalLen);
  885. return Success;
  886. }
  887. } } // namespace mozilla::pkix