From 40f17d92608b48c9f8f49767e42bab09f9a6ad3d Mon Sep 17 00:00:00 2001 From: devgianlu Date: Fri, 29 Nov 2024 15:27:28 +0100 Subject: [PATCH] LibCrypto: Move ASN1 macros to `Crypto::ASN1` Makes more sense to have them in `Crypto::ASN1` rather than in `Crypto::Certificate`. --- Libraries/LibCrypto/ASN1/DER.h | 57 ++++++++++++++++++ .../LibCrypto/Certificate/Certificate.cpp | 58 +------------------ 2 files changed, 58 insertions(+), 57 deletions(-) diff --git a/Libraries/LibCrypto/ASN1/DER.h b/Libraries/LibCrypto/ASN1/DER.h index 6bcc4a132b8..cdbe5864c60 100644 --- a/Libraries/LibCrypto/ASN1/DER.h +++ b/Libraries/LibCrypto/ASN1/DER.h @@ -13,6 +13,63 @@ namespace Crypto::ASN1 { +#define ERROR_WITH_SCOPE(error) \ + do { \ + s_error_string = TRY(String::formatted("{}: {}", current_scope, error)); \ + return Error::from_string_view(s_error_string.bytes_as_string_view()); \ + } while (0) + +#define ENTER_TYPED_SCOPE(tag_kind_name, scope) \ + do { \ + if (auto tag = decoder.peek(); tag.is_error() || tag.value().kind != Crypto::ASN1::Kind::tag_kind_name) { \ + if (tag.is_error()) \ + ERROR_WITH_SCOPE(TRY(String::formatted(scope " data was invalid: {}", tag.error()))); \ + else \ + ERROR_WITH_SCOPE(TRY(String::formatted(scope " data was not of kind " #tag_kind_name " was {}", Crypto::ASN1::kind_name(tag.value().kind)))); \ + } \ + ENTER_SCOPE(scope); \ + } while (0) + +#define ENTER_SCOPE(scope) \ + do { \ + if (auto result = decoder.enter(); result.is_error()) { \ + ERROR_WITH_SCOPE(TRY(String::formatted("Failed to enter scope: {}", scope))); \ + } \ + PUSH_SCOPE(scope) \ + } while (0) + +#define PUSH_SCOPE(scope) current_scope.append(#scope##sv); + +#define EXIT_SCOPE() \ + do { \ + if (auto error = decoder.leave(); error.is_error()) { \ + ERROR_WITH_SCOPE(TRY(String::formatted("Failed to exit scope: {}", error.error()))); \ + } \ + POP_SCOPE(); \ + } while (0) + +#define POP_SCOPE() current_scope.remove(current_scope.size() - 1); + +#define READ_OBJECT(kind_name, type_name, value_name) \ + auto value_name##_result = decoder.read(Crypto::ASN1::Class::Universal, Crypto::ASN1::Kind::kind_name); \ + if (value_name##_result.is_error()) { \ + ERROR_WITH_SCOPE(TRY(String::formatted("Read of kind " #kind_name " failed: {}", value_name##_result.error()))); \ + } \ + auto value_name = value_name##_result.release_value(); + +#define REWRITE_TAG(kind_name) \ + auto value_name##_result = decoder.rewrite_tag(Crypto::ASN1::Kind::kind_name); \ + if (value_name##_result.is_error()) { \ + ERROR_WITH_SCOPE(TRY(String::formatted("Rewrite of kind " #kind_name " failed: {}", value_name##_result.error()))); \ + } + +#define DROP_OBJECT() \ + do { \ + if (auto error = decoder.drop(); error.is_error()) { \ + ERROR_WITH_SCOPE(TRY(String::formatted("Drop failed: {}", error.error()))); \ + } \ + } while (0) + class BitStringView { public: BitStringView(ReadonlyBytes data, size_t unused_bits) diff --git a/Libraries/LibCrypto/Certificate/Certificate.cpp b/Libraries/LibCrypto/Certificate/Certificate.cpp index 45d67029df1..50c91af2c77 100644 --- a/Libraries/LibCrypto/Certificate/Certificate.cpp +++ b/Libraries/LibCrypto/Certificate/Certificate.cpp @@ -15,68 +15,12 @@ #include namespace { +// Used by ASN1 macros static String s_error_string; } namespace Crypto::Certificate { -#define ERROR_WITH_SCOPE(error) \ - do { \ - s_error_string = TRY(String::formatted("{}: {}", current_scope, error)); \ - return Error::from_string_view(s_error_string.bytes_as_string_view()); \ - } while (0) - -#define ENTER_TYPED_SCOPE(tag_kind_name, scope) \ - do { \ - if (auto tag = decoder.peek(); tag.is_error() || tag.value().kind != Crypto::ASN1::Kind::tag_kind_name) { \ - if (tag.is_error()) \ - ERROR_WITH_SCOPE(TRY(String::formatted(scope " data was invalid: {}", tag.error()))); \ - else \ - ERROR_WITH_SCOPE(TRY(String::formatted(scope " data was not of kind " #tag_kind_name " was {}", Crypto::ASN1::kind_name(tag.value().kind)))); \ - } \ - ENTER_SCOPE(scope); \ - } while (0) - -#define ENTER_SCOPE(scope) \ - do { \ - if (auto result = decoder.enter(); result.is_error()) { \ - ERROR_WITH_SCOPE(TRY(String::formatted("Failed to enter scope: {}", scope))); \ - } \ - PUSH_SCOPE(scope) \ - } while (0) - -#define PUSH_SCOPE(scope) current_scope.append(#scope##sv); - -#define EXIT_SCOPE() \ - do { \ - if (auto error = decoder.leave(); error.is_error()) { \ - ERROR_WITH_SCOPE(TRY(String::formatted("Failed to exit scope: {}", error.error()))); \ - } \ - POP_SCOPE(); \ - } while (0) - -#define POP_SCOPE() current_scope.remove(current_scope.size() - 1); - -#define READ_OBJECT(kind_name, type_name, value_name) \ - auto value_name##_result = decoder.read(Crypto::ASN1::Class::Universal, Crypto::ASN1::Kind::kind_name); \ - if (value_name##_result.is_error()) { \ - ERROR_WITH_SCOPE(TRY(String::formatted("Read of kind " #kind_name " failed: {}", value_name##_result.error()))); \ - } \ - auto value_name = value_name##_result.release_value(); - -#define REWRITE_TAG(kind_name) \ - auto value_name##_result = decoder.rewrite_tag(Crypto::ASN1::Kind::kind_name); \ - if (value_name##_result.is_error()) { \ - ERROR_WITH_SCOPE(TRY(String::formatted("Rewrite of kind " #kind_name " failed: {}", value_name##_result.error()))); \ - } - -#define DROP_OBJECT() \ - do { \ - if (auto error = decoder.drop(); error.is_error()) { \ - ERROR_WITH_SCOPE(TRY(String::formatted("Drop failed: {}", error.error()))); \ - } \ - } while (0) - static ErrorOr parse_certificate_version(Crypto::ASN1::Decoder& decoder, Vector current_scope) { // Version ::= INTEGER {v1(0), v2(1), v3(2)}