ct_objects_extractor.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. // Copyright 2013 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/cert/ct_objects_extractor.h"
  5. #include <string.h>
  6. #include "base/hash/sha1.h"
  7. #include "base/logging.h"
  8. #include "base/strings/string_piece.h"
  9. #include "base/strings/string_util.h"
  10. #include "crypto/sha2.h"
  11. #include "net/cert/asn1_util.h"
  12. #include "net/cert/signed_certificate_timestamp.h"
  13. #include "net/cert/x509_util.h"
  14. #include "third_party/boringssl/src/include/openssl/bytestring.h"
  15. #include "third_party/boringssl/src/include/openssl/mem.h"
  16. namespace net::ct {
  17. namespace {
  18. // The wire form of the OID 1.3.6.1.4.1.11129.2.4.2. See Section 3.3 of
  19. // RFC6962.
  20. const uint8_t kEmbeddedSCTOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01,
  21. 0xD6, 0x79, 0x02, 0x04, 0x02};
  22. // The wire form of the OID 1.3.6.1.4.1.11129.2.4.5 - OCSP SingleExtension for
  23. // X.509v3 Certificate Transparency Signed Certificate Timestamp List, see
  24. // Section 3.3 of RFC6962.
  25. const uint8_t kOCSPExtensionOid[] = {0x2B, 0x06, 0x01, 0x04, 0x01,
  26. 0xD6, 0x79, 0x02, 0x04, 0x05};
  27. // The wire form of the OID 1.3.6.1.5.5.7.48.1.1. See RFC 6960.
  28. const uint8_t kOCSPBasicResponseOid[] = {0x2b, 0x06, 0x01, 0x05, 0x05,
  29. 0x07, 0x30, 0x01, 0x01};
  30. // The wire form of the OID 1.3.14.3.2.26.
  31. const uint8_t kSHA1Oid[] = {0x2b, 0x0e, 0x03, 0x02, 0x1a};
  32. // The wire form of the OID 2.16.840.1.101.3.4.2.1.
  33. const uint8_t kSHA256Oid[] = {0x60, 0x86, 0x48, 0x01, 0x65,
  34. 0x03, 0x04, 0x02, 0x01};
  35. bool StringEqualToCBS(const std::string& value1, const CBS* value2) {
  36. if (CBS_len(value2) != value1.size())
  37. return false;
  38. return memcmp(value1.data(), CBS_data(value2), CBS_len(value2)) == 0;
  39. }
  40. bool SkipElements(CBS* cbs, int count) {
  41. for (int i = 0; i < count; i++) {
  42. if (!CBS_get_any_asn1_element(cbs, nullptr, nullptr, nullptr))
  43. return false;
  44. }
  45. return true;
  46. }
  47. bool SkipOptionalElement(CBS* cbs, unsigned tag) {
  48. CBS unused;
  49. return !CBS_peek_asn1_tag(cbs, tag) || CBS_get_asn1(cbs, &unused, tag);
  50. }
  51. // Copies all the bytes in |outer| which are before |inner| to |out|. |inner|
  52. // must be a subset of |outer|.
  53. bool CopyBefore(const CBS& outer, const CBS& inner, CBB* out) {
  54. CHECK_LE(CBS_data(&outer), CBS_data(&inner));
  55. CHECK_LE(CBS_data(&inner) + CBS_len(&inner),
  56. CBS_data(&outer) + CBS_len(&outer));
  57. return !!CBB_add_bytes(out, CBS_data(&outer),
  58. CBS_data(&inner) - CBS_data(&outer));
  59. }
  60. // Copies all the bytes in |outer| which are after |inner| to |out|. |inner|
  61. // must be a subset of |outer|.
  62. bool CopyAfter(const CBS& outer, const CBS& inner, CBB* out) {
  63. CHECK_LE(CBS_data(&outer), CBS_data(&inner));
  64. CHECK_LE(CBS_data(&inner) + CBS_len(&inner),
  65. CBS_data(&outer) + CBS_len(&outer));
  66. return !!CBB_add_bytes(
  67. out, CBS_data(&inner) + CBS_len(&inner),
  68. CBS_data(&outer) + CBS_len(&outer) - CBS_data(&inner) - CBS_len(&inner));
  69. }
  70. // Skips |tbs_cert|, which must be a TBSCertificate body, to just before the
  71. // extensions element.
  72. bool SkipTBSCertificateToExtensions(CBS* tbs_cert) {
  73. constexpr unsigned kVersionTag =
  74. CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0;
  75. constexpr unsigned kIssuerUniqueIDTag = CBS_ASN1_CONTEXT_SPECIFIC | 1;
  76. constexpr unsigned kSubjectUniqueIDTag = CBS_ASN1_CONTEXT_SPECIFIC | 2;
  77. return SkipOptionalElement(tbs_cert, kVersionTag) &&
  78. SkipElements(tbs_cert,
  79. 6 /* serialNumber through subjectPublicKeyInfo */) &&
  80. SkipOptionalElement(tbs_cert, kIssuerUniqueIDTag) &&
  81. SkipOptionalElement(tbs_cert, kSubjectUniqueIDTag);
  82. }
  83. // Looks for the extension with the specified OID in |extensions|, which must
  84. // contain the contents of a SEQUENCE of X.509 extension structures. If found,
  85. // returns true and sets |*out| to the full extension element.
  86. bool FindExtensionElement(const CBS& extensions,
  87. const uint8_t* oid,
  88. size_t oid_len,
  89. CBS* out) {
  90. CBS extensions_copy = extensions;
  91. CBS result;
  92. CBS_init(&result, nullptr, 0);
  93. bool found = false;
  94. while (CBS_len(&extensions_copy) > 0) {
  95. CBS extension_element;
  96. if (!CBS_get_asn1_element(&extensions_copy, &extension_element,
  97. CBS_ASN1_SEQUENCE)) {
  98. return false;
  99. }
  100. CBS copy = extension_element;
  101. CBS extension, extension_oid;
  102. if (!CBS_get_asn1(&copy, &extension, CBS_ASN1_SEQUENCE) ||
  103. !CBS_get_asn1(&extension, &extension_oid, CBS_ASN1_OBJECT)) {
  104. return false;
  105. }
  106. if (CBS_mem_equal(&extension_oid, oid, oid_len)) {
  107. if (found)
  108. return false;
  109. found = true;
  110. result = extension_element;
  111. }
  112. }
  113. if (!found)
  114. return false;
  115. *out = result;
  116. return true;
  117. }
  118. // Finds the SignedCertificateTimestampList in an extension with OID |oid| in
  119. // |x509_exts|. If found, returns true and sets |*out_sct_list| to the encoded
  120. // SCT list.
  121. bool ParseSCTListFromExtensions(const CBS& extensions,
  122. const uint8_t* oid,
  123. size_t oid_len,
  124. std::string* out_sct_list) {
  125. CBS extension_element, extension, extension_oid, value, sct_list;
  126. if (!FindExtensionElement(extensions, oid, oid_len, &extension_element) ||
  127. !CBS_get_asn1(&extension_element, &extension, CBS_ASN1_SEQUENCE) ||
  128. !CBS_get_asn1(&extension, &extension_oid, CBS_ASN1_OBJECT) ||
  129. // Skip the optional critical element.
  130. !SkipOptionalElement(&extension, CBS_ASN1_BOOLEAN) ||
  131. // The extension value is stored in an OCTET STRING.
  132. !CBS_get_asn1(&extension, &value, CBS_ASN1_OCTETSTRING) ||
  133. CBS_len(&extension) != 0 ||
  134. // The extension value itself is an OCTET STRING containing the
  135. // serialized SCT list.
  136. !CBS_get_asn1(&value, &sct_list, CBS_ASN1_OCTETSTRING) ||
  137. CBS_len(&value) != 0) {
  138. return false;
  139. }
  140. DCHECK(CBS_mem_equal(&extension_oid, oid, oid_len));
  141. *out_sct_list = std::string(
  142. reinterpret_cast<const char*>(CBS_data(&sct_list)), CBS_len(&sct_list));
  143. return true;
  144. }
  145. // Finds the SingleResponse in |responses| which matches |issuer| and
  146. // |cert_serial_number|. On success, returns true and sets
  147. // |*out_single_response| to the body of the SingleResponse starting at the
  148. // |certStatus| field.
  149. bool FindMatchingSingleResponse(CBS* responses,
  150. const CRYPTO_BUFFER* issuer,
  151. const std::string& cert_serial_number,
  152. CBS* out_single_response) {
  153. base::StringPiece issuer_spki;
  154. if (!asn1::ExtractSPKIFromDERCert(
  155. x509_util::CryptoBufferAsStringPiece(issuer), &issuer_spki))
  156. return false;
  157. // In OCSP, only the key itself is under hash.
  158. base::StringPiece issuer_spk;
  159. if (!asn1::ExtractSubjectPublicKeyFromSPKI(issuer_spki, &issuer_spk))
  160. return false;
  161. // ExtractSubjectPublicKeyFromSPKI does not remove the initial octet encoding
  162. // the number of unused bits in the ASN.1 BIT STRING so we do it here. For
  163. // public keys, the bitstring is in practice always byte-aligned.
  164. if (issuer_spk.empty() || issuer_spk[0] != 0)
  165. return false;
  166. issuer_spk.remove_prefix(1);
  167. // TODO(ekasper): add SHA-384 to crypto/sha2.h and here if it proves
  168. // necessary.
  169. // TODO(ekasper): only compute the hashes on demand.
  170. std::string issuer_key_sha256_hash = crypto::SHA256HashString(issuer_spk);
  171. std::string issuer_key_sha1_hash =
  172. base::SHA1HashString(std::string(issuer_spk));
  173. while (CBS_len(responses) > 0) {
  174. CBS single_response, cert_id;
  175. if (!CBS_get_asn1(responses, &single_response, CBS_ASN1_SEQUENCE) ||
  176. !CBS_get_asn1(&single_response, &cert_id, CBS_ASN1_SEQUENCE)) {
  177. return false;
  178. }
  179. CBS hash_algorithm, hash, serial_number, issuer_name_hash, issuer_key_hash;
  180. if (!CBS_get_asn1(&cert_id, &hash_algorithm, CBS_ASN1_SEQUENCE) ||
  181. !CBS_get_asn1(&hash_algorithm, &hash, CBS_ASN1_OBJECT) ||
  182. !CBS_get_asn1(&cert_id, &issuer_name_hash, CBS_ASN1_OCTETSTRING) ||
  183. !CBS_get_asn1(&cert_id, &issuer_key_hash, CBS_ASN1_OCTETSTRING) ||
  184. !CBS_get_asn1(&cert_id, &serial_number, CBS_ASN1_INTEGER) ||
  185. CBS_len(&cert_id) != 0) {
  186. return false;
  187. }
  188. // Check the serial number matches.
  189. if (!StringEqualToCBS(cert_serial_number, &serial_number))
  190. continue;
  191. // Check if the issuer_key_hash matches.
  192. // TODO(ekasper): also use the issuer name hash in matching.
  193. if (CBS_mem_equal(&hash, kSHA1Oid, sizeof(kSHA1Oid))) {
  194. if (StringEqualToCBS(issuer_key_sha1_hash, &issuer_key_hash)) {
  195. *out_single_response = single_response;
  196. return true;
  197. }
  198. } else if (CBS_mem_equal(&hash, kSHA256Oid, sizeof(kSHA256Oid))) {
  199. if (StringEqualToCBS(issuer_key_sha256_hash, &issuer_key_hash)) {
  200. *out_single_response = single_response;
  201. return true;
  202. }
  203. }
  204. }
  205. return false;
  206. }
  207. } // namespace
  208. bool ExtractEmbeddedSCTList(const CRYPTO_BUFFER* cert, std::string* sct_list) {
  209. CBS cert_cbs;
  210. CBS_init(&cert_cbs, CRYPTO_BUFFER_data(cert), CRYPTO_BUFFER_len(cert));
  211. CBS cert_body, tbs_cert, extensions_wrap, extensions;
  212. if (!CBS_get_asn1(&cert_cbs, &cert_body, CBS_ASN1_SEQUENCE) ||
  213. CBS_len(&cert_cbs) != 0 ||
  214. !CBS_get_asn1(&cert_body, &tbs_cert, CBS_ASN1_SEQUENCE) ||
  215. !SkipTBSCertificateToExtensions(&tbs_cert) ||
  216. // Extract the extensions list.
  217. !CBS_get_asn1(&tbs_cert, &extensions_wrap,
  218. CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 3) ||
  219. !CBS_get_asn1(&extensions_wrap, &extensions, CBS_ASN1_SEQUENCE) ||
  220. CBS_len(&extensions_wrap) != 0 || CBS_len(&tbs_cert) != 0) {
  221. return false;
  222. }
  223. return ParseSCTListFromExtensions(extensions, kEmbeddedSCTOid,
  224. sizeof(kEmbeddedSCTOid), sct_list);
  225. }
  226. bool GetPrecertSignedEntry(const CRYPTO_BUFFER* leaf,
  227. const CRYPTO_BUFFER* issuer,
  228. SignedEntryData* result) {
  229. result->Reset();
  230. // Parse the TBSCertificate.
  231. CBS cert_cbs;
  232. CBS_init(&cert_cbs, CRYPTO_BUFFER_data(leaf), CRYPTO_BUFFER_len(leaf));
  233. CBS cert_body, tbs_cert;
  234. if (!CBS_get_asn1(&cert_cbs, &cert_body, CBS_ASN1_SEQUENCE) ||
  235. CBS_len(&cert_cbs) != 0 ||
  236. !CBS_get_asn1(&cert_body, &tbs_cert, CBS_ASN1_SEQUENCE)) {
  237. return false;
  238. }
  239. CBS tbs_cert_copy = tbs_cert;
  240. if (!SkipTBSCertificateToExtensions(&tbs_cert))
  241. return false;
  242. // Start filling in a new TBSCertificate. Copy everything parsed or skipped
  243. // so far to the |new_tbs_cert|.
  244. bssl::ScopedCBB cbb;
  245. CBB new_tbs_cert;
  246. if (!CBB_init(cbb.get(), CBS_len(&tbs_cert_copy)) ||
  247. !CBB_add_asn1(cbb.get(), &new_tbs_cert, CBS_ASN1_SEQUENCE) ||
  248. !CopyBefore(tbs_cert_copy, tbs_cert, &new_tbs_cert)) {
  249. return false;
  250. }
  251. // Parse the extensions list and find the SCT extension.
  252. //
  253. // XXX(rsleevi): We could generate precerts for certs without the extension
  254. // by leaving the TBSCertificate as-is. The reference implementation does not
  255. // do this.
  256. constexpr unsigned kExtensionsTag =
  257. CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 3;
  258. CBS extensions_wrap, extensions, sct_extension;
  259. if (!CBS_get_asn1(&tbs_cert, &extensions_wrap, kExtensionsTag) ||
  260. !CBS_get_asn1(&extensions_wrap, &extensions, CBS_ASN1_SEQUENCE) ||
  261. CBS_len(&extensions_wrap) != 0 || CBS_len(&tbs_cert) != 0 ||
  262. !FindExtensionElement(extensions, kEmbeddedSCTOid,
  263. sizeof(kEmbeddedSCTOid), &sct_extension)) {
  264. return false;
  265. }
  266. // Add extensions to the TBSCertificate. Copy all extensions except the
  267. // embedded SCT extension.
  268. CBB new_extensions_wrap, new_extensions;
  269. if (!CBB_add_asn1(&new_tbs_cert, &new_extensions_wrap, kExtensionsTag) ||
  270. !CBB_add_asn1(&new_extensions_wrap, &new_extensions, CBS_ASN1_SEQUENCE) ||
  271. !CopyBefore(extensions, sct_extension, &new_extensions) ||
  272. !CopyAfter(extensions, sct_extension, &new_extensions)) {
  273. return false;
  274. }
  275. uint8_t* new_tbs_cert_der;
  276. size_t new_tbs_cert_len;
  277. if (!CBB_finish(cbb.get(), &new_tbs_cert_der, &new_tbs_cert_len))
  278. return false;
  279. bssl::UniquePtr<uint8_t> scoped_new_tbs_cert_der(new_tbs_cert_der);
  280. // Extract the issuer's public key.
  281. base::StringPiece issuer_key;
  282. if (!asn1::ExtractSPKIFromDERCert(
  283. x509_util::CryptoBufferAsStringPiece(issuer), &issuer_key)) {
  284. return false;
  285. }
  286. // Fill in the SignedEntryData.
  287. result->type = ct::SignedEntryData::LOG_ENTRY_TYPE_PRECERT;
  288. result->tbs_certificate.assign(
  289. reinterpret_cast<const char*>(new_tbs_cert_der), new_tbs_cert_len);
  290. crypto::SHA256HashString(issuer_key, result->issuer_key_hash.data,
  291. sizeof(result->issuer_key_hash.data));
  292. return true;
  293. }
  294. bool GetX509SignedEntry(const CRYPTO_BUFFER* leaf, SignedEntryData* result) {
  295. DCHECK(leaf);
  296. result->Reset();
  297. result->type = ct::SignedEntryData::LOG_ENTRY_TYPE_X509;
  298. result->leaf_certificate =
  299. std::string(x509_util::CryptoBufferAsStringPiece(leaf));
  300. return true;
  301. }
  302. bool ExtractSCTListFromOCSPResponse(const CRYPTO_BUFFER* issuer,
  303. const std::string& cert_serial_number,
  304. base::StringPiece ocsp_response,
  305. std::string* sct_list) {
  306. // The input is an OCSPResponse. See RFC2560, section 4.2.1. The SCT list is
  307. // in the extensions field of the SingleResponse which matches the input
  308. // certificate.
  309. CBS cbs;
  310. CBS_init(&cbs, reinterpret_cast<const uint8_t*>(ocsp_response.data()),
  311. ocsp_response.size());
  312. // Parse down to the ResponseBytes. The ResponseBytes is optional, but if it's
  313. // missing, this can't include an SCT list.
  314. CBS sequence, tagged_response_bytes, response_bytes, response_type, response;
  315. if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE) || CBS_len(&cbs) != 0 ||
  316. !SkipElements(&sequence, 1 /* responseStatus */) ||
  317. !CBS_get_asn1(&sequence, &tagged_response_bytes,
  318. CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
  319. CBS_len(&sequence) != 0 ||
  320. !CBS_get_asn1(&tagged_response_bytes, &response_bytes,
  321. CBS_ASN1_SEQUENCE) ||
  322. CBS_len(&tagged_response_bytes) != 0 ||
  323. !CBS_get_asn1(&response_bytes, &response_type, CBS_ASN1_OBJECT) ||
  324. !CBS_get_asn1(&response_bytes, &response, CBS_ASN1_OCTETSTRING) ||
  325. CBS_len(&response_bytes) != 0) {
  326. return false;
  327. }
  328. // The only relevant ResponseType is id-pkix-ocsp-basic.
  329. if (!CBS_mem_equal(&response_type, kOCSPBasicResponseOid,
  330. sizeof(kOCSPBasicResponseOid))) {
  331. return false;
  332. }
  333. // Parse the ResponseData out of the BasicOCSPResponse. Ignore the rest.
  334. constexpr unsigned kVersionTag =
  335. CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0;
  336. CBS basic_response, response_data, responses;
  337. if (!CBS_get_asn1(&response, &basic_response, CBS_ASN1_SEQUENCE) ||
  338. CBS_len(&response) != 0 ||
  339. !CBS_get_asn1(&basic_response, &response_data, CBS_ASN1_SEQUENCE)) {
  340. return false;
  341. }
  342. // Extract the list of SingleResponses from the ResponseData.
  343. if (!SkipOptionalElement(&response_data, kVersionTag) ||
  344. !SkipElements(&response_data, 2 /* responderID, producedAt */) ||
  345. !CBS_get_asn1(&response_data, &responses, CBS_ASN1_SEQUENCE)) {
  346. return false;
  347. }
  348. CBS single_response;
  349. if (!FindMatchingSingleResponse(&responses, issuer, cert_serial_number,
  350. &single_response)) {
  351. return false;
  352. }
  353. // Parse the extensions out of the SingleResponse.
  354. constexpr unsigned kNextUpdateTag =
  355. CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0;
  356. constexpr unsigned kSingleExtensionsTag =
  357. CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1;
  358. CBS extensions_wrap, extensions;
  359. if (!SkipElements(&single_response, 2 /* certStatus, thisUpdate */) ||
  360. !SkipOptionalElement(&single_response, kNextUpdateTag) ||
  361. !CBS_get_asn1(&single_response, &extensions_wrap, kSingleExtensionsTag) ||
  362. !CBS_get_asn1(&extensions_wrap, &extensions, CBS_ASN1_SEQUENCE) ||
  363. CBS_len(&extensions_wrap) != 0) {
  364. return false;
  365. }
  366. return ParseSCTListFromExtensions(extensions, kOCSPExtensionOid,
  367. sizeof(kOCSPExtensionOid), sct_list);
  368. }
  369. } // namespace net::ct