DER.h 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*
  2. * Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/BitmapView.h>
  8. #include <AK/Result.h>
  9. #include <AK/Types.h>
  10. #include <LibCrypto/ASN1/ASN1.h>
  11. #include <LibCrypto/BigInt/UnsignedBigInteger.h>
  12. namespace Crypto::ASN1 {
  13. class BitStringView {
  14. public:
  15. BitStringView(ReadonlyBytes data, size_t unused_bits)
  16. : m_data(data)
  17. , m_unused_bits(unused_bits)
  18. {
  19. }
  20. ReadonlyBytes raw_bytes() const
  21. {
  22. VERIFY(m_unused_bits == 0);
  23. return m_data;
  24. }
  25. bool get(size_t index)
  26. {
  27. if (index >= 8 * m_data.size() - m_unused_bits)
  28. return false;
  29. return 0 != (m_data[index / 8] & (1u << (7 - (index % 8))));
  30. }
  31. private:
  32. ReadonlyBytes m_data;
  33. size_t m_unused_bits;
  34. };
  35. class Decoder {
  36. public:
  37. Decoder(ReadonlyBytes data)
  38. {
  39. m_stack.append(data);
  40. }
  41. // Read a tag without consuming it (and its data).
  42. ErrorOr<Tag> peek();
  43. bool eof() const;
  44. template<typename ValueType>
  45. struct TaggedValue {
  46. Tag tag;
  47. ValueType value;
  48. };
  49. ErrorOr<void> rewrite_tag(Kind kind)
  50. {
  51. if (m_stack.is_empty())
  52. return Error::from_string_view("Nothing on stack to rewrite"sv);
  53. if (eof())
  54. return Error::from_string_view("Stream is empty"sv);
  55. if (m_current_tag.has_value()) {
  56. m_current_tag->kind = kind;
  57. return {};
  58. }
  59. auto tag = TRY(read_tag());
  60. m_current_tag = tag;
  61. m_current_tag->kind = kind;
  62. return {};
  63. }
  64. ErrorOr<void> drop()
  65. {
  66. if (m_stack.is_empty())
  67. return Error::from_string_literal("ASN1::Decoder: Trying to drop using an empty stack");
  68. if (eof())
  69. return Error::from_string_literal("ASN1::Decoder: Trying to drop using a decoder that is EOF");
  70. auto previous_position = m_stack;
  71. auto tag_or_error = peek();
  72. if (tag_or_error.is_error()) {
  73. m_stack = move(previous_position);
  74. return tag_or_error.release_error();
  75. }
  76. auto length_or_error = read_length();
  77. if (length_or_error.is_error()) {
  78. m_stack = move(previous_position);
  79. return length_or_error.release_error();
  80. }
  81. auto length = length_or_error.value();
  82. auto bytes_result = read_bytes(length);
  83. if (bytes_result.is_error()) {
  84. m_stack = move(previous_position);
  85. return bytes_result.release_error();
  86. }
  87. m_current_tag.clear();
  88. return {};
  89. }
  90. template<typename ValueType>
  91. ErrorOr<ValueType> read(Optional<Class> class_override = {}, Optional<Kind> kind_override = {})
  92. {
  93. if (m_stack.is_empty())
  94. return Error::from_string_literal("ASN1::Decoder: Trying to read using an empty stack");
  95. if (eof())
  96. return Error::from_string_literal("ASN1::Decoder: Trying to read using a decoder that is EOF");
  97. auto previous_position = m_stack;
  98. auto tag_or_error = peek();
  99. if (tag_or_error.is_error()) {
  100. m_stack = move(previous_position);
  101. return tag_or_error.release_error();
  102. }
  103. auto length_or_error = read_length();
  104. if (length_or_error.is_error()) {
  105. m_stack = move(previous_position);
  106. return length_or_error.release_error();
  107. }
  108. auto tag = tag_or_error.value();
  109. auto length = length_or_error.value();
  110. auto value_or_error = read_value<ValueType>(class_override.value_or(tag.class_), kind_override.value_or(tag.kind), length);
  111. if (value_or_error.is_error()) {
  112. m_stack = move(previous_position);
  113. return value_or_error.release_error();
  114. }
  115. m_current_tag.clear();
  116. return value_or_error.release_value();
  117. }
  118. ErrorOr<void> enter();
  119. ErrorOr<void> leave();
  120. private:
  121. template<typename ValueType, typename DecodedType>
  122. ErrorOr<ValueType> with_type_check(DecodedType&& value)
  123. {
  124. if constexpr (requires { ValueType { value }; })
  125. return ValueType { value };
  126. return Error::from_string_literal("ASN1::Decoder: Trying to decode a value from an incompatible type");
  127. }
  128. template<typename ValueType, typename DecodedType>
  129. ErrorOr<ValueType> with_type_check(ErrorOr<DecodedType>&& value_or_error)
  130. {
  131. if (value_or_error.is_error())
  132. return value_or_error.release_error();
  133. if constexpr (IsSame<ValueType, bool> && !IsSame<DecodedType, bool>) {
  134. return Error::from_string_literal("ASN1::Decoder: Trying to decode a boolean from a non-boolean type");
  135. } else {
  136. auto&& value = value_or_error.value();
  137. if constexpr (requires { ValueType { value }; })
  138. return ValueType { value };
  139. }
  140. return Error::from_string_literal("ASN1::Decoder: Trying to decode a value from an incompatible type");
  141. }
  142. template<typename ValueType>
  143. ErrorOr<ValueType> read_value(Class klass, Kind kind, size_t length)
  144. {
  145. auto data = TRY(read_bytes(length));
  146. if (klass != Class::Universal)
  147. return with_type_check<ValueType>(data);
  148. if (kind == Kind::Boolean)
  149. return with_type_check<ValueType>(decode_boolean(data));
  150. if (kind == Kind::Integer)
  151. return with_type_check<ValueType>(decode_arbitrary_sized_integer(data));
  152. if (kind == Kind::OctetString)
  153. return with_type_check<ValueType>(decode_octet_string(data));
  154. if (kind == Kind::Null)
  155. return with_type_check<ValueType>(decode_null(data));
  156. if (kind == Kind::ObjectIdentifier)
  157. return with_type_check<ValueType>(decode_object_identifier(data));
  158. if (kind == Kind::PrintableString || kind == Kind::IA5String || kind == Kind::UTCTime)
  159. return with_type_check<ValueType>(decode_printable_string(data));
  160. if (kind == Kind::Utf8String)
  161. return with_type_check<ValueType>(StringView { data.data(), data.size() });
  162. if (kind == Kind::BitString)
  163. return with_type_check<ValueType>(decode_bit_string(data));
  164. return with_type_check<ValueType>(data);
  165. }
  166. ErrorOr<Tag> read_tag();
  167. ErrorOr<size_t> read_length();
  168. ErrorOr<u8> read_byte();
  169. ErrorOr<ReadonlyBytes> read_bytes(size_t length);
  170. static ErrorOr<bool> decode_boolean(ReadonlyBytes);
  171. static ErrorOr<UnsignedBigInteger> decode_arbitrary_sized_integer(ReadonlyBytes);
  172. static ErrorOr<StringView> decode_octet_string(ReadonlyBytes);
  173. static ErrorOr<nullptr_t> decode_null(ReadonlyBytes);
  174. static ErrorOr<Vector<int>> decode_object_identifier(ReadonlyBytes);
  175. static ErrorOr<StringView> decode_printable_string(ReadonlyBytes);
  176. static ErrorOr<BitStringView> decode_bit_string(ReadonlyBytes);
  177. Vector<ReadonlyBytes> m_stack;
  178. Optional<Tag> m_current_tag;
  179. };
  180. ErrorOr<void> pretty_print(Decoder&, Stream&, int indent = 0);
  181. }