Certificate.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. /*
  2. * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
  3. * Copyright (c) 2023, stelar7 <dudedbz@gmail.com>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include "Certificate.h"
  8. #include <AK/Debug.h>
  9. #include <AK/IPv4Address.h>
  10. #include <LibCrypto/ASN1/ASN1.h>
  11. #include <LibCrypto/ASN1/DER.h>
  12. #include <LibCrypto/ASN1/PEM.h>
  13. namespace TLS {
  14. #define ERROR_WITH_SCOPE(error) \
  15. do { \
  16. return Error::from_string_view(TRY(String::formatted("{}: {}", current_scope, error))); \
  17. } while (0)
  18. #define ENTER_TYPED_SCOPE(tag_kind_name, scope) \
  19. do { \
  20. if (auto tag = decoder.peek(); tag.is_error() || tag.value().kind != Crypto::ASN1::Kind::tag_kind_name) { \
  21. if (tag.is_error()) \
  22. ERROR_WITH_SCOPE(TRY(String::formatted(scope " data was invalid: {}", tag.error()))); \
  23. else \
  24. ERROR_WITH_SCOPE(TRY(String::formatted(scope " data was not of kind " #tag_kind_name " was {}", Crypto::ASN1::kind_name(tag.value().kind)))); \
  25. } \
  26. ENTER_SCOPE(scope); \
  27. } while (0)
  28. #define ENTER_SCOPE(scope) \
  29. do { \
  30. if (auto result = decoder.enter(); result.is_error()) { \
  31. ERROR_WITH_SCOPE(TRY(String::formatted("Failed to enter scope: {}", scope))); \
  32. } \
  33. PUSH_SCOPE(scope) \
  34. } while (0)
  35. #define PUSH_SCOPE(scope) current_scope.append(#scope##sv);
  36. #define EXIT_SCOPE() \
  37. do { \
  38. if (auto error = decoder.leave(); error.is_error()) { \
  39. ERROR_WITH_SCOPE(TRY(String::formatted("Failed to exit scope: {}", error.error()))); \
  40. } \
  41. POP_SCOPE(); \
  42. } while (0)
  43. #define POP_SCOPE() current_scope.remove(current_scope.size() - 1);
  44. #define READ_OBJECT(kind_name, type_name, value_name) \
  45. auto value_name##_result = decoder.read<type_name>(Crypto::ASN1::Class::Universal, Crypto::ASN1::Kind::kind_name); \
  46. if (value_name##_result.is_error()) { \
  47. ERROR_WITH_SCOPE(TRY(String::formatted("Read of kind " #kind_name " failed: {}", value_name##_result.error()))); \
  48. } \
  49. auto value_name = value_name##_result.release_value();
  50. #define REWRITE_TAG(kind_name) \
  51. auto value_name##_result = decoder.rewrite_tag(Crypto::ASN1::Kind::kind_name); \
  52. if (value_name##_result.is_error()) { \
  53. ERROR_WITH_SCOPE(TRY(String::formatted("Rewrite of kind " #kind_name " failed: {}", value_name##_result.error()))); \
  54. }
  55. #define DROP_OBJECT() \
  56. do { \
  57. if (auto error = decoder.drop(); error.is_error()) { \
  58. ERROR_WITH_SCOPE(TRY(String::formatted("Drop failed: {}", error.error()))); \
  59. } \
  60. } while (0)
  61. static ErrorOr<SupportedGroup> oid_to_curve(Vector<int> curve)
  62. {
  63. if (curve == curve_ansip384r1)
  64. return SupportedGroup::SECP384R1;
  65. else if (curve == curve_prime256)
  66. return SupportedGroup::SECP256R1;
  67. return Error::from_string_view(TRY(String::formatted("Unknown curve oid {}", curve)));
  68. }
  69. static ErrorOr<Crypto::UnsignedBigInteger> parse_version(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  70. {
  71. // Version ::= INTEGER {v1(0), v2(1), v3(2)}
  72. if (auto tag = decoder.peek(); !tag.is_error() && tag.value().type == Crypto::ASN1::Type::Constructed) {
  73. ENTER_SCOPE("Version"sv);
  74. READ_OBJECT(Integer, Crypto::UnsignedBigInteger, version);
  75. if (version > 3) {
  76. ERROR_WITH_SCOPE(TRY(String::formatted("Invalid version value at {}", current_scope)));
  77. }
  78. EXIT_SCOPE();
  79. return version;
  80. } else {
  81. return Crypto::UnsignedBigInteger { 0 };
  82. }
  83. }
  84. static ErrorOr<Crypto::UnsignedBigInteger> parse_serial_number(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  85. {
  86. // CertificateSerialNumber ::= INTEGER
  87. PUSH_SCOPE("CertificateSerialNumber"sv);
  88. READ_OBJECT(Integer, Crypto::UnsignedBigInteger, serial);
  89. POP_SCOPE();
  90. return serial;
  91. }
  92. static ErrorOr<SupportedGroup> parse_ec_parameters(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  93. {
  94. // ECParameters ::= CHOICE {
  95. // namedCurve OBJECT IDENTIFIER
  96. // }
  97. PUSH_SCOPE("ECParameters"sv);
  98. READ_OBJECT(ObjectIdentifier, Vector<int>, named_curve);
  99. // Note: namedCurve sometimes has 5 nodes, but we need 7 for the comparison below to work.
  100. while (named_curve.size() < 7) {
  101. named_curve.append(0);
  102. }
  103. POP_SCOPE();
  104. bool is_known_curve = false;
  105. for (auto const& curves : known_curve_identifiers) {
  106. if (curves.span() == named_curve.span()) {
  107. is_known_curve = true;
  108. break;
  109. }
  110. }
  111. if (!is_known_curve) {
  112. ERROR_WITH_SCOPE(TRY(String::formatted("Unknown named curve {}", named_curve)));
  113. }
  114. return oid_to_curve(named_curve);
  115. }
  116. static ErrorOr<AlgorithmIdentifier> parse_algorithm_identifier(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  117. {
  118. // AlgorithmIdentifier{ALGORITHM:SupportedAlgorithms} ::= SEQUENCE {
  119. // algorithm ALGORITHM.&id({SupportedAlgorithms}),
  120. // parameters ALGORITHM.&Type({SupportedAlgorithms}{@algorithm}) OPTIONAL,
  121. // ... }
  122. ENTER_TYPED_SCOPE(Sequence, "AlgorithmIdentifier"sv);
  123. PUSH_SCOPE("algorithm"sv);
  124. READ_OBJECT(ObjectIdentifier, Vector<int>, algorithm);
  125. // Note: ecPublicKey only has 6 nodes, but we need 7 for the comparison below to work.
  126. while (algorithm.size() < 7) {
  127. algorithm.append(0);
  128. }
  129. POP_SCOPE();
  130. bool is_known_algorithm = false;
  131. for (auto const& inner : known_algorithm_identifiers) {
  132. if (inner.span() == algorithm.span()) {
  133. is_known_algorithm = true;
  134. break;
  135. }
  136. }
  137. if (!is_known_algorithm) {
  138. ERROR_WITH_SCOPE(TRY(String::formatted("Unknown algorithm {}", algorithm)));
  139. }
  140. // -- When the following OIDs are used in an AlgorithmIdentifier, the
  141. // -- parameters MUST be present and MUST be NULL.
  142. // sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 1 }
  143. // sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
  144. // sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
  145. // sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
  146. // sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
  147. // sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
  148. // sha224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 14 }
  149. Array<Array<int, 7>, 8> rsa_null_algorithms = {
  150. rsa_encryption_oid,
  151. rsa_md5_encryption_oid,
  152. rsa_sha1_encryption_oid,
  153. rsa_sha256_encryption_oid,
  154. rsa_sha384_encryption_oid,
  155. rsa_sha512_encryption_oid,
  156. rsa_sha224_encryption_oid,
  157. };
  158. bool is_rsa_null_algorithm = false;
  159. for (auto const& inner : rsa_null_algorithms) {
  160. if (inner.span() == algorithm.span()) {
  161. is_rsa_null_algorithm = true;
  162. break;
  163. }
  164. }
  165. if (is_rsa_null_algorithm) {
  166. PUSH_SCOPE("RSA null parameter"sv);
  167. READ_OBJECT(Null, void*, forced_null);
  168. (void)forced_null;
  169. POP_SCOPE();
  170. EXIT_SCOPE();
  171. return AlgorithmIdentifier(algorithm);
  172. }
  173. // When the ecdsa-with-SHA224, ecdsa-with-SHA256, ecdsa-with-SHA384, or
  174. // ecdsa-with-SHA512 algorithm identifier appears in the algorithm field
  175. // as an AlgorithmIdentifier, the encoding MUST omit the parameters
  176. // field.
  177. Array<Array<int, 7>, 8> no_parameter_algorithms = {
  178. ecdsa_with_sha224_encryption_oid,
  179. ecdsa_with_sha256_encryption_oid,
  180. ecdsa_with_sha384_encryption_oid,
  181. ecdsa_with_sha512_encryption_oid,
  182. };
  183. bool is_no_parameter_algorithm = false;
  184. for (auto const& inner : no_parameter_algorithms) {
  185. if (inner.span() == algorithm.span()) {
  186. is_no_parameter_algorithm = true;
  187. }
  188. }
  189. if (is_no_parameter_algorithm) {
  190. EXIT_SCOPE();
  191. return AlgorithmIdentifier(algorithm);
  192. }
  193. if (algorithm.span() == ec_public_key_encryption_oid.span()) {
  194. // The parameters associated with id-ecPublicKey SHOULD be absent or ECParameters,
  195. // and NULL is allowed to support legacy implementations.
  196. if (decoder.eof()) {
  197. EXIT_SCOPE();
  198. return AlgorithmIdentifier(algorithm);
  199. }
  200. auto tag = TRY(decoder.peek());
  201. if (tag.kind == Crypto::ASN1::Kind::Null) {
  202. PUSH_SCOPE("ecPublicKey null parameter"sv);
  203. READ_OBJECT(Null, void*, forced_null);
  204. (void)forced_null;
  205. POP_SCOPE();
  206. EXIT_SCOPE();
  207. return AlgorithmIdentifier(algorithm);
  208. }
  209. auto algorithm_identifier = AlgorithmIdentifier(algorithm);
  210. algorithm_identifier.ec_parameters = TRY(parse_ec_parameters(decoder, current_scope));
  211. EXIT_SCOPE();
  212. return algorithm_identifier;
  213. }
  214. ERROR_WITH_SCOPE(TRY(String::formatted("Unhandled parameters for algorithm {}", algorithm)));
  215. }
  216. static ErrorOr<RelativeDistinguishedName> parse_name(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  217. {
  218. RelativeDistinguishedName rdn {};
  219. // Name ::= Choice {
  220. // rdn_sequence RDNSequence
  221. // } // NOTE: since this is the only alternative, there's no index
  222. // RDNSequence ::= Sequence OF RelativeDistinguishedName
  223. ENTER_TYPED_SCOPE(Sequence, "Name"sv);
  224. while (!decoder.eof()) {
  225. // RelativeDistinguishedName ::= Set OF AttributeTypeAndValue
  226. ENTER_TYPED_SCOPE(Set, "RDNSequence"sv);
  227. while (!decoder.eof()) {
  228. // AttributeTypeAndValue ::= Sequence {
  229. // type AttributeType,
  230. // value AttributeValue
  231. // }
  232. ENTER_TYPED_SCOPE(Sequence, "AttributeTypeAndValue"sv);
  233. // AttributeType ::= ObjectIdentifier
  234. PUSH_SCOPE("AttributeType"sv)
  235. READ_OBJECT(ObjectIdentifier, Vector<int>, attribute_type_oid);
  236. POP_SCOPE();
  237. // AttributeValue ::= Any
  238. PUSH_SCOPE("AttributeValue"sv)
  239. READ_OBJECT(PrintableString, StringView, attribute_value);
  240. POP_SCOPE();
  241. auto attribute_type_string = TRY(String::join("."sv, attribute_type_oid));
  242. auto attribute_value_string = TRY(String::from_utf8(attribute_value));
  243. TRY(rdn.set(attribute_type_string, attribute_value_string));
  244. EXIT_SCOPE();
  245. }
  246. EXIT_SCOPE();
  247. }
  248. EXIT_SCOPE();
  249. return rdn;
  250. }
  251. static ErrorOr<Core::DateTime> parse_time(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  252. {
  253. // Time ::= Choice {
  254. // utc_time UTCTime,
  255. // general_time GeneralizedTime
  256. // }
  257. auto tag = TRY(decoder.peek());
  258. if (tag.kind == Crypto::ASN1::Kind::UTCTime) {
  259. PUSH_SCOPE("UTCTime"sv);
  260. READ_OBJECT(UTCTime, StringView, utc_time);
  261. auto parse_result = Crypto::ASN1::parse_utc_time(utc_time);
  262. if (!parse_result.has_value()) {
  263. ERROR_WITH_SCOPE(TRY(String::formatted("Failed to parse UTCTime {}", utc_time)));
  264. }
  265. POP_SCOPE();
  266. return parse_result.release_value();
  267. }
  268. if (tag.kind == Crypto::ASN1::Kind::GeneralizedTime) {
  269. PUSH_SCOPE("GeneralizedTime"sv);
  270. READ_OBJECT(UTCTime, StringView, generalized_time);
  271. auto parse_result = Crypto::ASN1::parse_generalized_time(generalized_time);
  272. if (!parse_result.has_value()) {
  273. ERROR_WITH_SCOPE(TRY(String::formatted("Failed to parse GeneralizedTime {}", generalized_time)));
  274. }
  275. POP_SCOPE();
  276. return parse_result.release_value();
  277. }
  278. ERROR_WITH_SCOPE(TRY(String::formatted("Unrecognised Time format {}", kind_name(tag.kind))));
  279. }
  280. static ErrorOr<Validity> parse_validity(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  281. {
  282. Validity validity {};
  283. // Validity ::= SEQUENCE {
  284. // notBefore Time,
  285. // notAfter Time }
  286. ENTER_TYPED_SCOPE(Sequence, "Validity"sv);
  287. validity.not_before = TRY(parse_time(decoder, current_scope));
  288. validity.not_after = TRY(parse_time(decoder, current_scope));
  289. EXIT_SCOPE();
  290. return validity;
  291. }
  292. static ErrorOr<SubjectPublicKey> parse_subject_public_key_info(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  293. {
  294. // SubjectPublicKeyInfo ::= Sequence {
  295. // algorithm AlgorithmIdentifier,
  296. // subject_public_key BitString
  297. // }
  298. SubjectPublicKey public_key;
  299. ENTER_TYPED_SCOPE(Sequence, "SubjectPublicKeyInfo"sv);
  300. public_key.algorithm = TRY(parse_algorithm_identifier(decoder, current_scope));
  301. PUSH_SCOPE("subjectPublicKey"sv);
  302. READ_OBJECT(BitString, Crypto::ASN1::BitStringView, value);
  303. POP_SCOPE();
  304. public_key.raw_key = TRY(ByteBuffer::copy(value.raw_bytes()));
  305. if (public_key.algorithm.identifier.span() == rsa_encryption_oid.span()) {
  306. auto key = Crypto::PK::RSA::parse_rsa_key(value.raw_bytes());
  307. if (!key.public_key.length()) {
  308. return Error::from_string_literal("Invalid RSA key");
  309. }
  310. public_key.rsa = move(key.public_key);
  311. EXIT_SCOPE();
  312. return public_key;
  313. }
  314. if (public_key.algorithm.identifier.span() == ec_public_key_encryption_oid.span()) {
  315. // Note: Raw key is already stored, so we can just exit out at this point.
  316. EXIT_SCOPE();
  317. return public_key;
  318. }
  319. String algo_oid = TRY(String::join("."sv, public_key.algorithm.identifier));
  320. ERROR_WITH_SCOPE(TRY(String::formatted("Unhandled algorithm {}", algo_oid)));
  321. EXIT_SCOPE();
  322. return public_key;
  323. }
  324. static ErrorOr<Crypto::ASN1::BitStringView> parse_unique_identifier(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  325. {
  326. // UniqueIdentifier ::= BIT STRING
  327. PUSH_SCOPE("UniqueIdentifier"sv);
  328. READ_OBJECT(BitString, Crypto::ASN1::BitStringView, value);
  329. POP_SCOPE();
  330. return value;
  331. }
  332. static ErrorOr<String> parse_general_name(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  333. {
  334. // GeneralName ::= CHOICE {
  335. // otherName [0] INSTANCE OF OTHER-NAME,
  336. // rfc822Name [1] IA5String,
  337. // dNSName [2] IA5String,
  338. // x400Address [3] ORAddress,
  339. // directoryName [4] Name,
  340. // ediPartyName [5] EDIPartyName,
  341. // uniformResourceIdentifier [6] IA5String,
  342. // iPAddress [7] OCTET STRING,
  343. // registeredID [8] OBJECT IDENTIFIER,
  344. // }
  345. auto tag = TRY(decoder.peek());
  346. auto tag_value = static_cast<u8>(tag.kind);
  347. switch (tag_value) {
  348. case 0:
  349. // Note: We don't know how to use this.
  350. PUSH_SCOPE("otherName"sv)
  351. DROP_OBJECT();
  352. POP_SCOPE();
  353. break;
  354. case 1: {
  355. PUSH_SCOPE("rfc822Name"sv)
  356. READ_OBJECT(IA5String, StringView, name);
  357. POP_SCOPE();
  358. return String::from_utf8(name);
  359. }
  360. case 2: {
  361. PUSH_SCOPE("dNSName"sv)
  362. READ_OBJECT(IA5String, StringView, name);
  363. POP_SCOPE();
  364. return String::from_utf8(name);
  365. }
  366. case 3:
  367. // Note: We don't know how to use this.
  368. PUSH_SCOPE("x400Address"sv)
  369. DROP_OBJECT();
  370. POP_SCOPE();
  371. break;
  372. case 4: {
  373. PUSH_SCOPE("directoryName"sv);
  374. READ_OBJECT(OctetString, StringView, directory_name);
  375. Crypto::ASN1::Decoder decoder { directory_name.bytes() };
  376. auto names = TRY(parse_name(decoder, current_scope));
  377. POP_SCOPE();
  378. return names.to_string();
  379. }
  380. case 5:
  381. // Note: We don't know how to use this.
  382. PUSH_SCOPE("ediPartyName");
  383. DROP_OBJECT();
  384. POP_SCOPE();
  385. break;
  386. case 6: {
  387. PUSH_SCOPE("uniformResourceIdentifier"sv);
  388. READ_OBJECT(IA5String, StringView, name);
  389. POP_SCOPE();
  390. return String::from_utf8(name);
  391. }
  392. case 7: {
  393. PUSH_SCOPE("iPAddress"sv);
  394. READ_OBJECT(OctetString, StringView, ip_addr_sv);
  395. IPv4Address ip_addr { ip_addr_sv.bytes().data() };
  396. POP_SCOPE();
  397. return ip_addr.to_string();
  398. }
  399. case 8: {
  400. PUSH_SCOPE("registeredID"sv);
  401. READ_OBJECT(ObjectIdentifier, Vector<int>, identifier);
  402. POP_SCOPE();
  403. return String::join("."sv, identifier);
  404. }
  405. default:
  406. ERROR_WITH_SCOPE("Unknown tag in GeneralNames choice"sv);
  407. }
  408. ERROR_WITH_SCOPE("Unknown tag in GeneralNames choice"sv);
  409. }
  410. static ErrorOr<Vector<String>> parse_general_names(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  411. {
  412. // GeneralNames ::= Sequence OF GeneralName
  413. ENTER_TYPED_SCOPE(Sequence, "GeneralNames");
  414. Vector<String> names;
  415. while (!decoder.eof()) {
  416. names.append(TRY(parse_general_name(decoder, current_scope)));
  417. }
  418. EXIT_SCOPE();
  419. return names;
  420. }
  421. static ErrorOr<Vector<String>> parse_subject_alternative_names(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  422. {
  423. // SubjectAlternativeName ::= GeneralNames
  424. PUSH_SCOPE("SubjectAlternativeName"sv);
  425. auto values = TRY(parse_general_names(decoder, current_scope));
  426. POP_SCOPE();
  427. return values;
  428. }
  429. static ErrorOr<Vector<String>> parse_issuer_alternative_names(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  430. {
  431. // issuerAltName ::= GeneralNames
  432. PUSH_SCOPE("issuerAltName"sv);
  433. auto values = TRY(parse_general_names(decoder, current_scope));
  434. POP_SCOPE();
  435. return values;
  436. }
  437. static ErrorOr<Crypto::ASN1::BitStringView> parse_key_usage(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  438. {
  439. // KeyUsage ::= BIT STRING {
  440. // digitalSignature (0),
  441. // contentCommitment (1),
  442. // keyEncipherment (2),
  443. // dataEncipherment (3),
  444. // keyAgreement (4),
  445. // keyCertSign (5),
  446. // cRLSign (6),
  447. // encipherOnly (7),
  448. // decipherOnly (8)
  449. // }
  450. PUSH_SCOPE("KeyUsage"sv);
  451. READ_OBJECT(BitString, Crypto::ASN1::BitStringView, usage);
  452. POP_SCOPE();
  453. return usage;
  454. }
  455. static ErrorOr<BasicConstraints> parse_basic_constraints(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  456. {
  457. // BasicConstraints ::= SEQUENCE {
  458. // cA BOOLEAN DEFAULT FALSE,
  459. // pathLenConstraint INTEGER (0..MAX) OPTIONAL
  460. // }
  461. BasicConstraints constraints {};
  462. ENTER_TYPED_SCOPE(Sequence, "BasicConstraints"sv);
  463. if (decoder.eof()) {
  464. EXIT_SCOPE();
  465. return constraints;
  466. }
  467. auto ca_tag = TRY(decoder.peek());
  468. if (ca_tag.kind == Crypto::ASN1::Kind::Boolean) {
  469. PUSH_SCOPE("cA"sv);
  470. READ_OBJECT(Boolean, bool, is_certificate_authority);
  471. constraints.is_certificate_authority = is_certificate_authority;
  472. POP_SCOPE();
  473. }
  474. if (decoder.eof()) {
  475. EXIT_SCOPE();
  476. return constraints;
  477. }
  478. auto path_length_tag = TRY(decoder.peek());
  479. if (path_length_tag.kind == Crypto::ASN1::Kind::Integer) {
  480. PUSH_SCOPE("pathLenConstraint"sv);
  481. READ_OBJECT(Integer, Crypto::UnsignedBigInteger, path_length_constraint);
  482. constraints.path_length_constraint = path_length_constraint;
  483. POP_SCOPE();
  484. }
  485. EXIT_SCOPE();
  486. return constraints;
  487. }
  488. static ErrorOr<void> parse_extension(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope, Certificate& certificate)
  489. {
  490. // Extension ::= Sequence {
  491. // extension_id ObjectIdentifier,
  492. // critical Boolean DEFAULT false,
  493. // extension_value OctetString (DER-encoded)
  494. // }
  495. ENTER_TYPED_SCOPE(Sequence, "Extension"sv);
  496. PUSH_SCOPE("extension_id"sv);
  497. READ_OBJECT(ObjectIdentifier, Vector<int>, extension_id);
  498. POP_SCOPE();
  499. bool is_critical = false;
  500. auto peek = TRY(decoder.peek());
  501. if (peek.kind == Crypto::ASN1::Kind::Boolean) {
  502. PUSH_SCOPE("critical"sv);
  503. READ_OBJECT(Boolean, bool, extension_critical);
  504. is_critical = extension_critical;
  505. POP_SCOPE();
  506. }
  507. PUSH_SCOPE("extension_value"sv);
  508. READ_OBJECT(OctetString, StringView, extension_value);
  509. POP_SCOPE();
  510. bool is_known_extension = false;
  511. Crypto::ASN1::Decoder extension_decoder { extension_value.bytes() };
  512. Vector<StringView, 8> extension_scope {};
  513. if (extension_id == subject_alternative_name_oid) {
  514. is_known_extension = true;
  515. auto alternate_names = TRY(parse_subject_alternative_names(extension_decoder, extension_scope));
  516. certificate.SAN = alternate_names;
  517. }
  518. if (extension_id == key_usage_oid) {
  519. is_known_extension = true;
  520. auto usage = TRY(parse_key_usage(extension_decoder, extension_scope));
  521. certificate.is_allowed_to_sign_certificate = usage.get(5);
  522. }
  523. if (extension_id == basic_constraints_oid) {
  524. is_known_extension = true;
  525. auto constraints = TRY(parse_basic_constraints(extension_decoder, extension_scope));
  526. certificate.is_certificate_authority = constraints.is_certificate_authority;
  527. certificate.path_length_constraint = constraints.path_length_constraint.to_u64();
  528. }
  529. if (extension_id == issuer_alternative_name_oid) {
  530. is_known_extension = true;
  531. auto alternate_names = TRY(parse_issuer_alternative_names(extension_decoder, extension_scope));
  532. certificate.IAN = alternate_names;
  533. }
  534. EXIT_SCOPE();
  535. if (is_critical && !is_known_extension) {
  536. ERROR_WITH_SCOPE(TRY(String::formatted("Extension {} is critical, but we do not support it", extension_id)));
  537. }
  538. if (!is_known_extension) {
  539. dbgln_if(TLS_DEBUG, TRY(String::formatted("{}: Unhandled extension: {}", current_scope, extension_id)));
  540. }
  541. return {};
  542. }
  543. static ErrorOr<void> parse_extensions(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope, Certificate& certificate)
  544. {
  545. // Extensions ::= Sequence OF Extension
  546. ENTER_TYPED_SCOPE(Sequence, "Extensions"sv);
  547. while (!decoder.eof()) {
  548. TRY(parse_extension(decoder, current_scope, certificate));
  549. }
  550. EXIT_SCOPE();
  551. return {};
  552. }
  553. static ErrorOr<Certificate> parse_tbs_certificate(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  554. {
  555. // TBSCertificate ::= SEQUENCE {
  556. // version [0] Version DEFAULT v1,
  557. // serialNumber CertificateSerialNumber,
  558. // signature AlgorithmIdentifier{{SupportedAlgorithms}},
  559. // issuer Name,
  560. // validity Validity,
  561. // subject Name,
  562. // subjectPublicKeyInfo SubjectPublicKeyInfo,
  563. // issuerUniqueIdentifier [1] IMPLICIT UniqueIdentifier OPTIONAL,
  564. // ...,
  565. // [[2: -- if present, version shall be v2 or v3
  566. // subjectUniqueIdentifier [2] IMPLICIT UniqueIdentifier OPTIONAL]],
  567. // [[3: -- if present, version shall be v2 or v3
  568. // extensions [3] Extensions OPTIONAL]]
  569. // -- If present, version shall be v3]]
  570. // }
  571. ENTER_TYPED_SCOPE(Sequence, "TBSCertificate"sv);
  572. Certificate certificate;
  573. certificate.version = TRY(parse_version(decoder, current_scope)).to_u64();
  574. certificate.serial_number = TRY(parse_serial_number(decoder, current_scope));
  575. certificate.algorithm = TRY(parse_algorithm_identifier(decoder, current_scope));
  576. certificate.issuer = TRY(parse_name(decoder, current_scope));
  577. certificate.validity = TRY(parse_validity(decoder, current_scope));
  578. certificate.subject = TRY(parse_name(decoder, current_scope));
  579. certificate.public_key = TRY(parse_subject_public_key_info(decoder, current_scope));
  580. if (!decoder.eof()) {
  581. auto tag = TRY(decoder.peek());
  582. if (static_cast<u8>(tag.kind) == 1) {
  583. REWRITE_TAG(BitString)
  584. TRY(parse_unique_identifier(decoder, current_scope));
  585. }
  586. }
  587. if (!decoder.eof()) {
  588. auto tag = TRY(decoder.peek());
  589. if (static_cast<u8>(tag.kind) == 2) {
  590. REWRITE_TAG(BitString)
  591. TRY(parse_unique_identifier(decoder, current_scope));
  592. }
  593. }
  594. if (!decoder.eof()) {
  595. auto tag = TRY(decoder.peek());
  596. if (static_cast<u8>(tag.kind) == 3) {
  597. REWRITE_TAG(Sequence)
  598. ENTER_TYPED_SCOPE(Sequence, "extensions"sv);
  599. TRY(parse_extensions(decoder, current_scope, certificate));
  600. EXIT_SCOPE();
  601. }
  602. }
  603. if (!decoder.eof()) {
  604. ERROR_WITH_SCOPE("Reached end of TBS parse with more data left"sv);
  605. }
  606. certificate.is_self_issued = TRY(certificate.issuer.to_string()) == TRY(certificate.subject.to_string());
  607. EXIT_SCOPE();
  608. return certificate;
  609. }
  610. ErrorOr<Certificate> Certificate::parse_certificate(ReadonlyBytes buffer, bool)
  611. {
  612. Crypto::ASN1::Decoder decoder { buffer };
  613. Vector<StringView, 8> current_scope {};
  614. // Certificate ::= SIGNED{TBSCertificate}
  615. // SIGNED{ToBeSigned} ::= SEQUENCE {
  616. // toBeSigned ToBeSigned,
  617. // COMPONENTS OF SIGNATURE{ToBeSigned},
  618. // }
  619. // SIGNATURE{ToBeSigned} ::= SEQUENCE {
  620. // algorithmIdentifier AlgorithmIdentifier{{SupportedAlgorithms}},
  621. // encrypted ENCRYPTED-HASH{ToBeSigned},
  622. // }
  623. // ENCRYPTED-HASH{ToBeSigned} ::= BIT STRING (CONSTRAINED BY {
  624. // -- shall be the result of applying a hashing procedure to the DER-encoded (see 6.2)
  625. // -- octets of a value of -- ToBeSigned -- and then applying an encipherment procedure
  626. // -- to those octets -- } )
  627. ENTER_TYPED_SCOPE(Sequence, "Certificate"sv);
  628. Certificate certificate = TRY(parse_tbs_certificate(decoder, current_scope));
  629. certificate.original_asn1 = TRY(ByteBuffer::copy(buffer));
  630. certificate.signature_algorithm = TRY(parse_algorithm_identifier(decoder, current_scope));
  631. PUSH_SCOPE("signature"sv);
  632. READ_OBJECT(BitString, Crypto::ASN1::BitStringView, signature);
  633. certificate.signature_value = TRY(ByteBuffer::copy(signature.raw_bytes()));
  634. POP_SCOPE();
  635. if (!decoder.eof()) {
  636. ERROR_WITH_SCOPE("Reached end of Certificate parse with more data left"sv);
  637. }
  638. EXIT_SCOPE();
  639. return certificate;
  640. }
  641. #undef PUSH_SCOPE
  642. #undef ENTER_SCOPE
  643. #undef ENTER_TYPED_SCOPE
  644. #undef POP_SCOPE
  645. #undef EXIT_SCOPE
  646. #undef READ_OBJECT
  647. #undef DROP_OBJECT
  648. #undef REWRITE_TAG
  649. ErrorOr<String> RelativeDistinguishedName::to_string()
  650. {
  651. #define ADD_IF_RECOGNIZED(identifier, shorthand_code) \
  652. if (it->key == identifier) { \
  653. cert_name.appendff("\\{}={}", shorthand_code, it->value); \
  654. continue; \
  655. }
  656. StringBuilder cert_name;
  657. for (auto it = m_members.begin(); it != m_members.end(); ++it) {
  658. ADD_IF_RECOGNIZED(enum_value(AttributeType::SerialNumber), "SERIALNUMBER");
  659. ADD_IF_RECOGNIZED(enum_value(AttributeType::Email), "MAIL");
  660. ADD_IF_RECOGNIZED(enum_value(AttributeType::Title), "T");
  661. ADD_IF_RECOGNIZED(enum_value(AttributeType::PostalCode), "PC");
  662. ADD_IF_RECOGNIZED(enum_value(AttributeType::DnQualifier), "DNQ");
  663. ADD_IF_RECOGNIZED(enum_value(AttributeType::GivenName), "GIVENNAME");
  664. ADD_IF_RECOGNIZED(enum_value(AttributeType::Surname), "SN");
  665. ADD_IF_RECOGNIZED(enum_value(AttributeType::Cn), "CN");
  666. ADD_IF_RECOGNIZED(enum_value(AttributeType::L), "L");
  667. ADD_IF_RECOGNIZED(enum_value(AttributeType::St), "ST");
  668. ADD_IF_RECOGNIZED(enum_value(AttributeType::O), "O");
  669. ADD_IF_RECOGNIZED(enum_value(AttributeType::Ou), "OU");
  670. ADD_IF_RECOGNIZED(enum_value(AttributeType::C), "C");
  671. ADD_IF_RECOGNIZED(enum_value(AttributeType::Street), "STREET");
  672. ADD_IF_RECOGNIZED(enum_value(AttributeType::Dc), "DC");
  673. ADD_IF_RECOGNIZED(enum_value(AttributeType::Uid), "UID");
  674. cert_name.appendff("\\{}={}", it->key, it->value);
  675. }
  676. #undef ADD_IF_RECOGNIZED
  677. return cert_name.to_string();
  678. }
  679. }