Certificate.cpp 33 KB

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