Certificate.cpp 31 KB

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