Certificate.cpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  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_literal("Unknown curve oid");
  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(move(attribute_type_string), move(attribute_value_string)));
  248. EXIT_SCOPE();
  249. }
  250. EXIT_SCOPE();
  251. }
  252. EXIT_SCOPE();
  253. return rdn;
  254. }
  255. static ErrorOr<UnixDateTime> 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. 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. }
  326. // https://www.rfc-editor.org/rfc/rfc5208#section-5
  327. ErrorOr<PrivateKey> parse_private_key_info(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  328. {
  329. // PrivateKeyInfo ::= SEQUENCE {
  330. // version Version,
  331. // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
  332. // privateKey PrivateKey,
  333. // attributes [0] IMPLICIT Attributes OPTIONAL
  334. // }
  335. PrivateKey private_key;
  336. ENTER_TYPED_SCOPE(Sequence, "PrivateKeyInfo"sv);
  337. READ_OBJECT(Integer, Crypto::UnsignedBigInteger, version);
  338. if (version != 0) {
  339. ERROR_WITH_SCOPE(TRY(String::formatted("Invalid version value at {}", current_scope)));
  340. }
  341. private_key.algorithm = TRY(parse_algorithm_identifier(decoder, current_scope));
  342. PUSH_SCOPE("privateKey"sv);
  343. READ_OBJECT(OctetString, StringView, value);
  344. POP_SCOPE();
  345. private_key.raw_key = TRY(ByteBuffer::copy(value.bytes()));
  346. if (private_key.algorithm.identifier.span() == rsa_encryption_oid.span()) {
  347. auto key = Crypto::PK::RSA::parse_rsa_key(value.bytes());
  348. if (key.private_key.length() == 0) {
  349. ERROR_WITH_SCOPE(TRY(String::formatted("Invalid RSA key at {}", current_scope)));
  350. }
  351. private_key.rsa = move(key.private_key);
  352. EXIT_SCOPE();
  353. return private_key;
  354. }
  355. if (private_key.algorithm.identifier.span() == ec_public_key_encryption_oid.span()) {
  356. // Note: Raw key is already stored, so we can just exit out at this point.
  357. EXIT_SCOPE();
  358. return private_key;
  359. }
  360. String algo_oid = TRY(String::join("."sv, private_key.algorithm.identifier));
  361. ERROR_WITH_SCOPE(TRY(String::formatted("Unhandled algorithm {}", algo_oid)));
  362. }
  363. static ErrorOr<Crypto::ASN1::BitStringView> parse_unique_identifier(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  364. {
  365. // UniqueIdentifier ::= BIT STRING
  366. PUSH_SCOPE("UniqueIdentifier"sv);
  367. READ_OBJECT(BitString, Crypto::ASN1::BitStringView, value);
  368. POP_SCOPE();
  369. return value;
  370. }
  371. static ErrorOr<String> parse_general_name(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  372. {
  373. // GeneralName ::= CHOICE {
  374. // otherName [0] INSTANCE OF OTHER-NAME,
  375. // rfc822Name [1] IA5String,
  376. // dNSName [2] IA5String,
  377. // x400Address [3] ORAddress,
  378. // directoryName [4] Name,
  379. // ediPartyName [5] EDIPartyName,
  380. // uniformResourceIdentifier [6] IA5String,
  381. // iPAddress [7] OCTET STRING,
  382. // registeredID [8] OBJECT IDENTIFIER,
  383. // }
  384. auto tag = TRY(decoder.peek());
  385. auto tag_value = static_cast<u8>(tag.kind);
  386. switch (tag_value) {
  387. case 0:
  388. // Note: We don't know how to use this.
  389. PUSH_SCOPE("otherName"sv)
  390. DROP_OBJECT();
  391. POP_SCOPE();
  392. break;
  393. case 1: {
  394. PUSH_SCOPE("rfc822Name"sv)
  395. READ_OBJECT(IA5String, StringView, name);
  396. POP_SCOPE();
  397. return String::from_utf8(name);
  398. }
  399. case 2: {
  400. PUSH_SCOPE("dNSName"sv)
  401. READ_OBJECT(IA5String, StringView, name);
  402. POP_SCOPE();
  403. return String::from_utf8(name);
  404. }
  405. case 3:
  406. // Note: We don't know how to use this.
  407. PUSH_SCOPE("x400Address"sv)
  408. DROP_OBJECT();
  409. POP_SCOPE();
  410. break;
  411. case 4: {
  412. PUSH_SCOPE("directoryName"sv);
  413. READ_OBJECT(OctetString, StringView, directory_name);
  414. Crypto::ASN1::Decoder decoder { directory_name.bytes() };
  415. auto names = TRY(parse_name(decoder, current_scope));
  416. POP_SCOPE();
  417. return names.to_string();
  418. }
  419. case 5:
  420. // Note: We don't know how to use this.
  421. PUSH_SCOPE("ediPartyName");
  422. DROP_OBJECT();
  423. POP_SCOPE();
  424. break;
  425. case 6: {
  426. PUSH_SCOPE("uniformResourceIdentifier"sv);
  427. READ_OBJECT(IA5String, StringView, name);
  428. POP_SCOPE();
  429. return String::from_utf8(name);
  430. }
  431. case 7: {
  432. PUSH_SCOPE("iPAddress"sv);
  433. READ_OBJECT(OctetString, StringView, ip_addr_sv);
  434. IPv4Address ip_addr { ip_addr_sv.bytes().data() };
  435. POP_SCOPE();
  436. return ip_addr.to_string();
  437. }
  438. case 8: {
  439. PUSH_SCOPE("registeredID"sv);
  440. READ_OBJECT(ObjectIdentifier, Vector<int>, identifier);
  441. POP_SCOPE();
  442. return String::join("."sv, identifier);
  443. }
  444. default:
  445. ERROR_WITH_SCOPE("Unknown tag in GeneralNames choice"sv);
  446. }
  447. ERROR_WITH_SCOPE("Unknown tag in GeneralNames choice"sv);
  448. }
  449. static ErrorOr<Vector<String>> parse_general_names(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  450. {
  451. // GeneralNames ::= Sequence OF GeneralName
  452. ENTER_TYPED_SCOPE(Sequence, "GeneralNames");
  453. Vector<String> names;
  454. while (!decoder.eof()) {
  455. names.append(TRY(parse_general_name(decoder, current_scope)));
  456. }
  457. EXIT_SCOPE();
  458. return names;
  459. }
  460. static ErrorOr<Vector<String>> parse_subject_alternative_names(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  461. {
  462. // SubjectAlternativeName ::= GeneralNames
  463. PUSH_SCOPE("SubjectAlternativeName"sv);
  464. auto values = TRY(parse_general_names(decoder, current_scope));
  465. POP_SCOPE();
  466. return values;
  467. }
  468. static ErrorOr<Vector<String>> parse_issuer_alternative_names(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  469. {
  470. // issuerAltName ::= GeneralNames
  471. PUSH_SCOPE("issuerAltName"sv);
  472. auto values = TRY(parse_general_names(decoder, current_scope));
  473. POP_SCOPE();
  474. return values;
  475. }
  476. static ErrorOr<Crypto::ASN1::BitStringView> parse_key_usage(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  477. {
  478. // KeyUsage ::= BIT STRING {
  479. // digitalSignature (0),
  480. // contentCommitment (1),
  481. // keyEncipherment (2),
  482. // dataEncipherment (3),
  483. // keyAgreement (4),
  484. // keyCertSign (5),
  485. // cRLSign (6),
  486. // encipherOnly (7),
  487. // decipherOnly (8)
  488. // }
  489. PUSH_SCOPE("KeyUsage"sv);
  490. READ_OBJECT(BitString, Crypto::ASN1::BitStringView, usage);
  491. POP_SCOPE();
  492. return usage;
  493. }
  494. static ErrorOr<BasicConstraints> parse_basic_constraints(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  495. {
  496. // BasicConstraints ::= SEQUENCE {
  497. // cA BOOLEAN DEFAULT FALSE,
  498. // pathLenConstraint INTEGER (0..MAX) OPTIONAL
  499. // }
  500. BasicConstraints constraints {};
  501. ENTER_TYPED_SCOPE(Sequence, "BasicConstraints"sv);
  502. if (decoder.eof()) {
  503. EXIT_SCOPE();
  504. return constraints;
  505. }
  506. auto ca_tag = TRY(decoder.peek());
  507. if (ca_tag.kind == Crypto::ASN1::Kind::Boolean) {
  508. PUSH_SCOPE("cA"sv);
  509. READ_OBJECT(Boolean, bool, is_certificate_authority);
  510. constraints.is_certificate_authority = is_certificate_authority;
  511. POP_SCOPE();
  512. }
  513. if (decoder.eof()) {
  514. EXIT_SCOPE();
  515. return constraints;
  516. }
  517. auto path_length_tag = TRY(decoder.peek());
  518. if (path_length_tag.kind == Crypto::ASN1::Kind::Integer) {
  519. PUSH_SCOPE("pathLenConstraint"sv);
  520. READ_OBJECT(Integer, Crypto::UnsignedBigInteger, path_length_constraint);
  521. constraints.path_length_constraint = path_length_constraint;
  522. POP_SCOPE();
  523. }
  524. EXIT_SCOPE();
  525. return constraints;
  526. }
  527. static ErrorOr<void> parse_extension(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope, Certificate& certificate)
  528. {
  529. // Extension ::= Sequence {
  530. // extension_id ObjectIdentifier,
  531. // critical Boolean DEFAULT false,
  532. // extension_value OctetString (DER-encoded)
  533. // }
  534. ENTER_TYPED_SCOPE(Sequence, "Extension"sv);
  535. PUSH_SCOPE("extension_id"sv);
  536. READ_OBJECT(ObjectIdentifier, Vector<int>, extension_id);
  537. POP_SCOPE();
  538. bool is_critical = false;
  539. auto peek = TRY(decoder.peek());
  540. if (peek.kind == Crypto::ASN1::Kind::Boolean) {
  541. PUSH_SCOPE("critical"sv);
  542. READ_OBJECT(Boolean, bool, extension_critical);
  543. is_critical = extension_critical;
  544. POP_SCOPE();
  545. }
  546. PUSH_SCOPE("extension_value"sv);
  547. READ_OBJECT(OctetString, StringView, extension_value);
  548. POP_SCOPE();
  549. bool is_known_extension = false;
  550. Crypto::ASN1::Decoder extension_decoder { extension_value.bytes() };
  551. Vector<StringView, 8> extension_scope {};
  552. if (extension_id == subject_alternative_name_oid) {
  553. is_known_extension = true;
  554. auto alternate_names = TRY(parse_subject_alternative_names(extension_decoder, extension_scope));
  555. certificate.SAN = alternate_names;
  556. }
  557. if (extension_id == key_usage_oid) {
  558. is_known_extension = true;
  559. auto usage = TRY(parse_key_usage(extension_decoder, extension_scope));
  560. certificate.is_allowed_to_sign_certificate = usage.get(5);
  561. }
  562. if (extension_id == basic_constraints_oid) {
  563. is_known_extension = true;
  564. auto constraints = TRY(parse_basic_constraints(extension_decoder, extension_scope));
  565. certificate.is_certificate_authority = constraints.is_certificate_authority;
  566. certificate.path_length_constraint = constraints.path_length_constraint.to_u64();
  567. }
  568. if (extension_id == issuer_alternative_name_oid) {
  569. is_known_extension = true;
  570. auto alternate_names = TRY(parse_issuer_alternative_names(extension_decoder, extension_scope));
  571. certificate.IAN = alternate_names;
  572. }
  573. EXIT_SCOPE();
  574. if (is_critical && !is_known_extension) {
  575. ERROR_WITH_SCOPE(TRY(String::formatted("Extension {} is critical, but we do not support it", extension_id)));
  576. }
  577. if (!is_known_extension) {
  578. dbgln_if(TLS_DEBUG, TRY(String::formatted("{}: Unhandled extension: {}", current_scope, extension_id)));
  579. }
  580. return {};
  581. }
  582. static ErrorOr<void> parse_extensions(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope, Certificate& certificate)
  583. {
  584. // Extensions ::= Sequence OF Extension
  585. ENTER_TYPED_SCOPE(Sequence, "Extensions"sv);
  586. while (!decoder.eof()) {
  587. TRY(parse_extension(decoder, current_scope, certificate));
  588. }
  589. EXIT_SCOPE();
  590. return {};
  591. }
  592. static ErrorOr<Certificate> parse_tbs_certificate(Crypto::ASN1::Decoder& decoder, Vector<StringView> current_scope)
  593. {
  594. // TBSCertificate ::= SEQUENCE {
  595. // version [0] Version DEFAULT v1,
  596. // serialNumber CertificateSerialNumber,
  597. // signature AlgorithmIdentifier{{SupportedAlgorithms}},
  598. // issuer Name,
  599. // validity Validity,
  600. // subject Name,
  601. // subjectPublicKeyInfo SubjectPublicKeyInfo,
  602. // issuerUniqueIdentifier [1] IMPLICIT UniqueIdentifier OPTIONAL,
  603. // ...,
  604. // [[2: -- if present, version shall be v2 or v3
  605. // subjectUniqueIdentifier [2] IMPLICIT UniqueIdentifier OPTIONAL]],
  606. // [[3: -- if present, version shall be v2 or v3
  607. // extensions [3] Extensions OPTIONAL]]
  608. // -- If present, version shall be v3]]
  609. // }
  610. // Note: Parse out the ASN.1 of this object, since its used for TLS verification.
  611. // To do this, we get the bytes of our parent, the size of ourself, and slice the parent buffer.
  612. auto pre_cert_buffer = TRY(decoder.peek_entry_bytes());
  613. // FIXME: Dont assume this value.
  614. // Note: we assume this to be 4. 1 for the tag, and 3 for the length.
  615. auto entry_length_byte_count = 4;
  616. ENTER_TYPED_SCOPE(Sequence, "TBSCertificate"sv);
  617. auto post_cert_buffer = TRY(decoder.peek_entry_bytes());
  618. if (pre_cert_buffer.size() < post_cert_buffer.size() + entry_length_byte_count) {
  619. ERROR_WITH_SCOPE("Unexpected end of file");
  620. }
  621. Certificate certificate;
  622. certificate.version = TRY(parse_certificate_version(decoder, current_scope)).to_u64();
  623. certificate.serial_number = TRY(parse_serial_number(decoder, current_scope));
  624. certificate.algorithm = TRY(parse_algorithm_identifier(decoder, current_scope));
  625. certificate.issuer = TRY(parse_name(decoder, current_scope));
  626. certificate.validity = TRY(parse_validity(decoder, current_scope));
  627. certificate.subject = TRY(parse_name(decoder, current_scope));
  628. certificate.public_key = TRY(parse_subject_public_key_info(decoder, current_scope));
  629. certificate.tbs_asn1 = TRY(ByteBuffer::copy(pre_cert_buffer.slice(0, post_cert_buffer.size() + entry_length_byte_count)));
  630. if (!decoder.eof()) {
  631. auto tag = TRY(decoder.peek());
  632. if (static_cast<u8>(tag.kind) == 1) {
  633. REWRITE_TAG(BitString)
  634. TRY(parse_unique_identifier(decoder, current_scope));
  635. }
  636. }
  637. if (!decoder.eof()) {
  638. auto tag = TRY(decoder.peek());
  639. if (static_cast<u8>(tag.kind) == 2) {
  640. REWRITE_TAG(BitString)
  641. TRY(parse_unique_identifier(decoder, current_scope));
  642. }
  643. }
  644. if (!decoder.eof()) {
  645. auto tag = TRY(decoder.peek());
  646. if (static_cast<u8>(tag.kind) == 3) {
  647. REWRITE_TAG(Sequence)
  648. ENTER_TYPED_SCOPE(Sequence, "extensions"sv);
  649. TRY(parse_extensions(decoder, current_scope, certificate));
  650. EXIT_SCOPE();
  651. }
  652. }
  653. if (!decoder.eof()) {
  654. ERROR_WITH_SCOPE("Reached end of TBS parse with more data left"sv);
  655. }
  656. certificate.is_self_issued = TRY(certificate.issuer.to_string()) == TRY(certificate.subject.to_string());
  657. EXIT_SCOPE();
  658. return certificate;
  659. }
  660. ErrorOr<Certificate> Certificate::parse_certificate(ReadonlyBytes buffer, bool)
  661. {
  662. Crypto::ASN1::Decoder decoder { buffer };
  663. Vector<StringView, 8> current_scope {};
  664. // Certificate ::= SIGNED{TBSCertificate}
  665. // SIGNED{ToBeSigned} ::= SEQUENCE {
  666. // toBeSigned ToBeSigned,
  667. // COMPONENTS OF SIGNATURE{ToBeSigned},
  668. // }
  669. // SIGNATURE{ToBeSigned} ::= SEQUENCE {
  670. // algorithmIdentifier AlgorithmIdentifier{{SupportedAlgorithms}},
  671. // encrypted ENCRYPTED-HASH{ToBeSigned},
  672. // }
  673. // ENCRYPTED-HASH{ToBeSigned} ::= BIT STRING (CONSTRAINED BY {
  674. // -- shall be the result of applying a hashing procedure to the DER-encoded (see 6.2)
  675. // -- octets of a value of -- ToBeSigned -- and then applying an encipherment procedure
  676. // -- to those octets -- } )
  677. ENTER_TYPED_SCOPE(Sequence, "Certificate"sv);
  678. Certificate certificate = TRY(parse_tbs_certificate(decoder, current_scope));
  679. certificate.original_asn1 = TRY(ByteBuffer::copy(buffer));
  680. certificate.signature_algorithm = TRY(parse_algorithm_identifier(decoder, current_scope));
  681. PUSH_SCOPE("signature"sv);
  682. READ_OBJECT(BitString, Crypto::ASN1::BitStringView, signature);
  683. certificate.signature_value = TRY(ByteBuffer::copy(TRY(signature.raw_bytes())));
  684. POP_SCOPE();
  685. if (!decoder.eof()) {
  686. ERROR_WITH_SCOPE("Reached end of Certificate parse with more data left"sv);
  687. }
  688. EXIT_SCOPE();
  689. return certificate;
  690. }
  691. #undef PUSH_SCOPE
  692. #undef ENTER_SCOPE
  693. #undef ENTER_TYPED_SCOPE
  694. #undef POP_SCOPE
  695. #undef EXIT_SCOPE
  696. #undef READ_OBJECT
  697. #undef DROP_OBJECT
  698. #undef REWRITE_TAG
  699. ErrorOr<String> RelativeDistinguishedName::to_string() const
  700. {
  701. #define ADD_IF_RECOGNIZED(identifier, shorthand_code) \
  702. if (member_identifier == identifier) { \
  703. cert_name.appendff("\\{}={}", shorthand_code, value); \
  704. continue; \
  705. }
  706. StringBuilder cert_name;
  707. for (auto const& [member_identifier, value] : m_members) {
  708. ADD_IF_RECOGNIZED(enum_value(AttributeType::SerialNumber), "SERIALNUMBER");
  709. ADD_IF_RECOGNIZED(enum_value(AttributeType::Email), "MAIL");
  710. ADD_IF_RECOGNIZED(enum_value(AttributeType::Title), "T");
  711. ADD_IF_RECOGNIZED(enum_value(AttributeType::PostalCode), "PC");
  712. ADD_IF_RECOGNIZED(enum_value(AttributeType::DnQualifier), "DNQ");
  713. ADD_IF_RECOGNIZED(enum_value(AttributeType::GivenName), "GIVENNAME");
  714. ADD_IF_RECOGNIZED(enum_value(AttributeType::Surname), "SN");
  715. ADD_IF_RECOGNIZED(enum_value(AttributeType::Cn), "CN");
  716. ADD_IF_RECOGNIZED(enum_value(AttributeType::L), "L");
  717. ADD_IF_RECOGNIZED(enum_value(AttributeType::St), "ST");
  718. ADD_IF_RECOGNIZED(enum_value(AttributeType::O), "O");
  719. ADD_IF_RECOGNIZED(enum_value(AttributeType::Ou), "OU");
  720. ADD_IF_RECOGNIZED(enum_value(AttributeType::C), "C");
  721. ADD_IF_RECOGNIZED(enum_value(AttributeType::Street), "STREET");
  722. ADD_IF_RECOGNIZED(enum_value(AttributeType::Dc), "DC");
  723. ADD_IF_RECOGNIZED(enum_value(AttributeType::Uid), "UID");
  724. cert_name.appendff("\\{}={}", member_identifier, value);
  725. }
  726. #undef ADD_IF_RECOGNIZED
  727. return cert_name.to_string();
  728. }
  729. }