asn1_util.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. // Copyright (c) 2012 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/asn1_util.h"
  5. #include "net/cert/pki/parse_certificate.h"
  6. #include "net/der/input.h"
  7. #include "net/der/parser.h"
  8. #include "third_party/abseil-cpp/absl/types/optional.h"
  9. namespace net::asn1 {
  10. namespace {
  11. // Parses input |in| which should point to the beginning of a Certificate, and
  12. // sets |*tbs_certificate| ready to parse the Subject. If parsing
  13. // fails, this function returns false and |*tbs_certificate| is left in an
  14. // undefined state.
  15. bool SeekToSubject(der::Input in, der::Parser* tbs_certificate) {
  16. // From RFC 5280, section 4.1
  17. // Certificate ::= SEQUENCE {
  18. // tbsCertificate TBSCertificate,
  19. // signatureAlgorithm AlgorithmIdentifier,
  20. // signatureValue BIT STRING }
  21. // TBSCertificate ::= SEQUENCE {
  22. // version [0] EXPLICIT Version DEFAULT v1,
  23. // serialNumber CertificateSerialNumber,
  24. // signature AlgorithmIdentifier,
  25. // issuer Name,
  26. // validity Validity,
  27. // subject Name,
  28. // subjectPublicKeyInfo SubjectPublicKeyInfo,
  29. // ... }
  30. der::Parser parser(in);
  31. der::Parser certificate;
  32. if (!parser.ReadSequence(&certificate))
  33. return false;
  34. // We don't allow junk after the certificate.
  35. if (parser.HasMore())
  36. return false;
  37. if (!certificate.ReadSequence(tbs_certificate))
  38. return false;
  39. bool unused;
  40. if (!tbs_certificate->SkipOptionalTag(
  41. der::kTagConstructed | der::kTagContextSpecific | 0, &unused)) {
  42. return false;
  43. }
  44. // serialNumber
  45. if (!tbs_certificate->SkipTag(der::kInteger))
  46. return false;
  47. // signature
  48. if (!tbs_certificate->SkipTag(der::kSequence))
  49. return false;
  50. // issuer
  51. if (!tbs_certificate->SkipTag(der::kSequence))
  52. return false;
  53. // validity
  54. if (!tbs_certificate->SkipTag(der::kSequence))
  55. return false;
  56. return true;
  57. }
  58. // Parses input |in| which should point to the beginning of a Certificate, and
  59. // sets |*tbs_certificate| ready to parse the SubjectPublicKeyInfo. If parsing
  60. // fails, this function returns false and |*tbs_certificate| is left in an
  61. // undefined state.
  62. bool SeekToSPKI(der::Input in, der::Parser* tbs_certificate) {
  63. return SeekToSubject(in, tbs_certificate) &&
  64. // Skip over Subject.
  65. tbs_certificate->SkipTag(der::kSequence);
  66. }
  67. // Parses input |in| which should point to the beginning of a
  68. // Certificate. If parsing fails, this function returns false, with
  69. // |*extensions_present| and |*extensions_parser| left in an undefined
  70. // state. If parsing succeeds and extensions are present, this function
  71. // sets |*extensions_present| to true and sets |*extensions_parser|
  72. // ready to parse the Extensions. If extensions are not present, it sets
  73. // |*extensions_present| to false and |*extensions_parser| is left in an
  74. // undefined state.
  75. bool SeekToExtensions(der::Input in,
  76. bool* extensions_present,
  77. der::Parser* extensions_parser) {
  78. bool present;
  79. der::Parser tbs_cert_parser;
  80. if (!SeekToSPKI(in, &tbs_cert_parser))
  81. return false;
  82. // From RFC 5280, section 4.1
  83. // TBSCertificate ::= SEQUENCE {
  84. // ...
  85. // subjectPublicKeyInfo SubjectPublicKeyInfo,
  86. // issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL,
  87. // subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL,
  88. // extensions [3] EXPLICIT Extensions OPTIONAL }
  89. // subjectPublicKeyInfo
  90. if (!tbs_cert_parser.SkipTag(der::kSequence))
  91. return false;
  92. // issuerUniqueID
  93. if (!tbs_cert_parser.SkipOptionalTag(der::kTagContextSpecific | 1,
  94. &present)) {
  95. return false;
  96. }
  97. // subjectUniqueID
  98. if (!tbs_cert_parser.SkipOptionalTag(der::kTagContextSpecific | 2,
  99. &present)) {
  100. return false;
  101. }
  102. absl::optional<der::Input> extensions;
  103. if (!tbs_cert_parser.ReadOptionalTag(
  104. der::kTagConstructed | der::kTagContextSpecific | 3, &extensions)) {
  105. return false;
  106. }
  107. if (!extensions) {
  108. *extensions_present = false;
  109. return true;
  110. }
  111. // Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
  112. // Extension ::= SEQUENCE {
  113. // extnID OBJECT IDENTIFIER,
  114. // critical BOOLEAN DEFAULT FALSE,
  115. // extnValue OCTET STRING }
  116. // |extensions| was EXPLICITly tagged, so we still need to remove the
  117. // ASN.1 SEQUENCE header.
  118. der::Parser explicit_extensions_parser(extensions.value());
  119. if (!explicit_extensions_parser.ReadSequence(extensions_parser))
  120. return false;
  121. if (explicit_extensions_parser.HasMore())
  122. return false;
  123. *extensions_present = true;
  124. return true;
  125. }
  126. // Parse a DER-encoded, X.509 certificate in |cert| and find an extension with
  127. // the given OID. Returns false on parse error or true if the parse was
  128. // successful. |*out_extension_present| will be true iff the extension was
  129. // found. In the case where it was found, |*out_extension| will describe the
  130. // extension, or is undefined on parse error or if the extension is missing.
  131. bool ExtractExtensionWithOID(base::StringPiece cert,
  132. der::Input extension_oid,
  133. bool* out_extension_present,
  134. ParsedExtension* out_extension) {
  135. der::Parser extensions;
  136. bool extensions_present;
  137. if (!SeekToExtensions(der::Input(cert), &extensions_present, &extensions))
  138. return false;
  139. if (!extensions_present) {
  140. *out_extension_present = false;
  141. return true;
  142. }
  143. while (extensions.HasMore()) {
  144. der::Input extension_tlv;
  145. if (!extensions.ReadRawTLV(&extension_tlv) ||
  146. !ParseExtension(extension_tlv, out_extension)) {
  147. return false;
  148. }
  149. if (out_extension->oid == extension_oid) {
  150. *out_extension_present = true;
  151. return true;
  152. }
  153. }
  154. *out_extension_present = false;
  155. return true;
  156. }
  157. } // namespace
  158. bool ExtractSubjectFromDERCert(base::StringPiece cert,
  159. base::StringPiece* subject_out) {
  160. der::Parser parser;
  161. if (!SeekToSubject(der::Input(cert), &parser))
  162. return false;
  163. der::Input subject;
  164. if (!parser.ReadRawTLV(&subject))
  165. return false;
  166. *subject_out = subject.AsStringPiece();
  167. return true;
  168. }
  169. bool ExtractSPKIFromDERCert(base::StringPiece cert,
  170. base::StringPiece* spki_out) {
  171. der::Parser parser;
  172. if (!SeekToSPKI(der::Input(cert), &parser))
  173. return false;
  174. der::Input spki;
  175. if (!parser.ReadRawTLV(&spki))
  176. return false;
  177. *spki_out = spki.AsStringPiece();
  178. return true;
  179. }
  180. bool ExtractSubjectPublicKeyFromSPKI(base::StringPiece spki,
  181. base::StringPiece* spk_out) {
  182. // From RFC 5280, Section 4.1
  183. // SubjectPublicKeyInfo ::= SEQUENCE {
  184. // algorithm AlgorithmIdentifier,
  185. // subjectPublicKey BIT STRING }
  186. //
  187. // AlgorithmIdentifier ::= SEQUENCE {
  188. // algorithm OBJECT IDENTIFIER,
  189. // parameters ANY DEFINED BY algorithm OPTIONAL }
  190. // Step into SubjectPublicKeyInfo sequence.
  191. der::Parser parser((der::Input(spki)));
  192. der::Parser spki_parser;
  193. if (!parser.ReadSequence(&spki_parser))
  194. return false;
  195. // Step over algorithm field (a SEQUENCE).
  196. if (!spki_parser.SkipTag(der::kSequence))
  197. return false;
  198. // Extract the subjectPublicKey field.
  199. der::Input spk;
  200. if (!spki_parser.ReadTag(der::kBitString, &spk))
  201. return false;
  202. *spk_out = spk.AsStringPiece();
  203. return true;
  204. }
  205. bool HasCanSignHttpExchangesDraftExtension(base::StringPiece cert) {
  206. // kCanSignHttpExchangesDraftOid is the DER encoding of the OID for
  207. // canSignHttpExchangesDraft defined in:
  208. // https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html
  209. static const uint8_t kCanSignHttpExchangesDraftOid[] = {
  210. 0x2B, 0x06, 0x01, 0x04, 0x01, 0xd6, 0x79, 0x02, 0x01, 0x16};
  211. bool extension_present;
  212. ParsedExtension extension;
  213. if (!ExtractExtensionWithOID(cert, der::Input(kCanSignHttpExchangesDraftOid),
  214. &extension_present, &extension) ||
  215. !extension_present) {
  216. return false;
  217. }
  218. // The extension should have contents NULL.
  219. static const uint8_t kNull[] = {0x05, 0x00};
  220. return extension.value == der::Input(kNull);
  221. }
  222. bool ExtractSignatureAlgorithmsFromDERCert(
  223. base::StringPiece cert,
  224. base::StringPiece* cert_signature_algorithm_sequence,
  225. base::StringPiece* tbs_signature_algorithm_sequence) {
  226. // From RFC 5280, section 4.1
  227. // Certificate ::= SEQUENCE {
  228. // tbsCertificate TBSCertificate,
  229. // signatureAlgorithm AlgorithmIdentifier,
  230. // signatureValue BIT STRING }
  231. // TBSCertificate ::= SEQUENCE {
  232. // version [0] EXPLICIT Version DEFAULT v1,
  233. // serialNumber CertificateSerialNumber,
  234. // signature AlgorithmIdentifier,
  235. // issuer Name,
  236. // validity Validity,
  237. // subject Name,
  238. // subjectPublicKeyInfo SubjectPublicKeyInfo,
  239. // ... }
  240. der::Parser parser((der::Input(cert)));
  241. der::Parser certificate;
  242. if (!parser.ReadSequence(&certificate))
  243. return false;
  244. der::Parser tbs_certificate;
  245. if (!certificate.ReadSequence(&tbs_certificate))
  246. return false;
  247. bool unused;
  248. if (!tbs_certificate.SkipOptionalTag(
  249. der::kTagConstructed | der::kTagContextSpecific | 0, &unused)) {
  250. return false;
  251. }
  252. // serialNumber
  253. if (!tbs_certificate.SkipTag(der::kInteger))
  254. return false;
  255. // signature
  256. der::Input tbs_algorithm;
  257. if (!tbs_certificate.ReadRawTLV(&tbs_algorithm))
  258. return false;
  259. der::Input cert_algorithm;
  260. if (!certificate.ReadRawTLV(&cert_algorithm))
  261. return false;
  262. *cert_signature_algorithm_sequence = cert_algorithm.AsStringPiece();
  263. *tbs_signature_algorithm_sequence = tbs_algorithm.AsStringPiece();
  264. return true;
  265. }
  266. bool ExtractExtensionFromDERCert(base::StringPiece cert,
  267. base::StringPiece extension_oid,
  268. bool* out_extension_present,
  269. bool* out_extension_critical,
  270. base::StringPiece* out_contents) {
  271. *out_extension_present = false;
  272. *out_extension_critical = false;
  273. *out_contents = base::StringPiece();
  274. ParsedExtension extension;
  275. if (!ExtractExtensionWithOID(cert, der::Input(extension_oid),
  276. out_extension_present, &extension))
  277. return false;
  278. if (!*out_extension_present)
  279. return true;
  280. *out_extension_critical = extension.critical;
  281. *out_contents = extension.value.AsStringPiece();
  282. return true;
  283. }
  284. } // namespace net::asn1