DER.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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. ErrorOr<ReadonlyBytes> raw_bytes() const
  21. {
  22. if (m_unused_bits != 0)
  23. return Error::from_string_literal("ASN1::Decoder: BitStringView contains unexpected partial bytes");
  24. return m_data;
  25. }
  26. bool get(size_t index) const
  27. {
  28. if (index >= 8 * m_data.size() - m_unused_bits)
  29. return false;
  30. return 0 != (m_data[index / 8] & (1u << (7 - (index % 8))));
  31. }
  32. size_t unused_bits() const { return m_unused_bits; }
  33. size_t byte_length() const { return m_data.size(); }
  34. ReadonlyBytes underlying_bytes() const { return m_data; }
  35. // FIXME: Improve me! I am naive!
  36. bool operator==(BitStringView const& other) const
  37. {
  38. for (size_t bit_index = 0; bit_index < 8 * m_data.size() - m_unused_bits; ++bit_index) {
  39. if (get(bit_index) != other.get(bit_index))
  40. return false;
  41. }
  42. return true;
  43. }
  44. private:
  45. ReadonlyBytes m_data;
  46. size_t m_unused_bits;
  47. };
  48. class Decoder {
  49. public:
  50. Decoder(ReadonlyBytes data)
  51. {
  52. m_stack.append(data);
  53. }
  54. // Read a tag without consuming it (and its data).
  55. ErrorOr<Tag> peek();
  56. bool eof() const;
  57. template<typename ValueType>
  58. struct TaggedValue {
  59. Tag tag;
  60. ValueType value;
  61. };
  62. ErrorOr<void> rewrite_tag(Kind kind)
  63. {
  64. if (m_stack.is_empty())
  65. return Error::from_string_view("Nothing on stack to rewrite"sv);
  66. if (eof())
  67. return Error::from_string_view("Stream is empty"sv);
  68. if (m_current_tag.has_value()) {
  69. m_current_tag->kind = kind;
  70. return {};
  71. }
  72. auto tag = TRY(read_tag());
  73. m_current_tag = tag;
  74. m_current_tag->kind = kind;
  75. return {};
  76. }
  77. ErrorOr<void> drop()
  78. {
  79. if (m_stack.is_empty())
  80. return Error::from_string_literal("ASN1::Decoder: Trying to drop using an empty stack");
  81. if (eof())
  82. return Error::from_string_literal("ASN1::Decoder: Trying to drop using a decoder that is EOF");
  83. auto previous_position = m_stack;
  84. auto tag_or_error = peek();
  85. if (tag_or_error.is_error()) {
  86. m_stack = move(previous_position);
  87. return tag_or_error.release_error();
  88. }
  89. auto length_or_error = read_length();
  90. if (length_or_error.is_error()) {
  91. m_stack = move(previous_position);
  92. return length_or_error.release_error();
  93. }
  94. auto length = length_or_error.value();
  95. auto bytes_result = read_bytes(length);
  96. if (bytes_result.is_error()) {
  97. m_stack = move(previous_position);
  98. return bytes_result.release_error();
  99. }
  100. m_current_tag.clear();
  101. return {};
  102. }
  103. template<typename ValueType>
  104. ErrorOr<ValueType> read(Optional<Class> class_override = {}, Optional<Kind> kind_override = {})
  105. {
  106. if (m_stack.is_empty())
  107. return Error::from_string_literal("ASN1::Decoder: Trying to read using an empty stack");
  108. if (eof())
  109. return Error::from_string_literal("ASN1::Decoder: Trying to read using a decoder that is EOF");
  110. auto previous_position = m_stack;
  111. auto tag_or_error = peek();
  112. if (tag_or_error.is_error()) {
  113. m_stack = move(previous_position);
  114. return tag_or_error.release_error();
  115. }
  116. auto length_or_error = read_length();
  117. if (length_or_error.is_error()) {
  118. m_stack = move(previous_position);
  119. return length_or_error.release_error();
  120. }
  121. auto tag = tag_or_error.value();
  122. auto length = length_or_error.value();
  123. auto value_or_error = read_value<ValueType>(class_override.value_or(tag.class_), kind_override.value_or(tag.kind), length);
  124. if (value_or_error.is_error()) {
  125. m_stack = move(previous_position);
  126. return value_or_error.release_error();
  127. }
  128. m_current_tag.clear();
  129. return value_or_error.release_value();
  130. }
  131. ErrorOr<void> enter();
  132. ErrorOr<void> leave();
  133. ErrorOr<ReadonlyBytes> peek_entry_bytes();
  134. private:
  135. template<typename ValueType, typename DecodedType>
  136. ErrorOr<ValueType> with_type_check(DecodedType&& value)
  137. {
  138. if constexpr (requires { ValueType { value }; })
  139. return ValueType { value };
  140. return Error::from_string_literal("ASN1::Decoder: Trying to decode a value from an incompatible type");
  141. }
  142. template<typename ValueType, typename DecodedType>
  143. ErrorOr<ValueType> with_type_check(ErrorOr<DecodedType>&& value_or_error)
  144. {
  145. if (value_or_error.is_error())
  146. return value_or_error.release_error();
  147. if constexpr (IsSame<ValueType, bool> && !IsSame<DecodedType, bool>) {
  148. return Error::from_string_literal("ASN1::Decoder: Trying to decode a boolean from a non-boolean type");
  149. } else {
  150. auto&& value = value_or_error.value();
  151. if constexpr (requires { ValueType { value }; })
  152. return ValueType { value };
  153. }
  154. return Error::from_string_literal("ASN1::Decoder: Trying to decode a value from an incompatible type");
  155. }
  156. template<typename ValueType>
  157. ErrorOr<ValueType> read_value(Class klass, Kind kind, size_t length)
  158. {
  159. auto data = TRY(read_bytes(length));
  160. if constexpr (IsSame<ValueType, ReadonlyBytes>) {
  161. return data;
  162. } else {
  163. if (klass != Class::Universal)
  164. return with_type_check<ValueType>(data);
  165. if (kind == Kind::Boolean)
  166. return with_type_check<ValueType>(decode_boolean(data));
  167. if (kind == Kind::Integer)
  168. return with_type_check<ValueType>(decode_arbitrary_sized_integer(data));
  169. if (kind == Kind::OctetString)
  170. return with_type_check<ValueType>(decode_octet_string(data));
  171. if (kind == Kind::Null)
  172. return with_type_check<ValueType>(decode_null(data));
  173. if (kind == Kind::ObjectIdentifier)
  174. return with_type_check<ValueType>(decode_object_identifier(data));
  175. if (kind == Kind::PrintableString || kind == Kind::IA5String || kind == Kind::UTCTime)
  176. return with_type_check<ValueType>(decode_printable_string(data));
  177. if (kind == Kind::Utf8String)
  178. return with_type_check<ValueType>(StringView { data.data(), data.size() });
  179. if (kind == Kind::BitString)
  180. return with_type_check<ValueType>(decode_bit_string(data));
  181. return with_type_check<ValueType>(data);
  182. }
  183. }
  184. ErrorOr<Tag> read_tag();
  185. ErrorOr<size_t> read_length();
  186. ErrorOr<u8> read_byte();
  187. ErrorOr<ReadonlyBytes> read_bytes(size_t length);
  188. static ErrorOr<bool> decode_boolean(ReadonlyBytes);
  189. static ErrorOr<UnsignedBigInteger> decode_arbitrary_sized_integer(ReadonlyBytes);
  190. static ErrorOr<StringView> decode_octet_string(ReadonlyBytes);
  191. static ErrorOr<nullptr_t> decode_null(ReadonlyBytes);
  192. static ErrorOr<Vector<int>> decode_object_identifier(ReadonlyBytes);
  193. static ErrorOr<StringView> decode_printable_string(ReadonlyBytes);
  194. static ErrorOr<BitStringView> decode_bit_string(ReadonlyBytes);
  195. Vector<ReadonlyBytes> m_stack;
  196. Optional<Tag> m_current_tag;
  197. };
  198. ErrorOr<void> pretty_print(Decoder&, Stream&, int indent = 0);
  199. class Encoder {
  200. public:
  201. Encoder()
  202. {
  203. m_buffer_stack.empend();
  204. }
  205. ReadonlyBytes active_bytes() const { return m_buffer_stack.last().bytes(); }
  206. ByteBuffer finish()
  207. {
  208. VERIFY(m_buffer_stack.size() == 1);
  209. return m_buffer_stack.take_last();
  210. }
  211. template<typename ValueType>
  212. ErrorOr<void> write(ValueType const& value, Optional<Class> class_override = {}, Optional<Kind> kind_override = {})
  213. {
  214. if constexpr (IsSame<ValueType, bool>) {
  215. return write_boolean(value, class_override, kind_override);
  216. } else if constexpr (IsSame<ValueType, UnsignedBigInteger> || (IsIntegral<ValueType> && IsUnsigned<ValueType>)) {
  217. return write_arbitrary_sized_integer(value, class_override, kind_override);
  218. } else if constexpr (IsOneOf<ValueType, StringView, String, ByteString>) {
  219. return write_printable_string(value, class_override, kind_override);
  220. } else if constexpr (IsOneOf<ValueType, ReadonlyBytes, ByteBuffer>) {
  221. return write_octet_string(value, class_override, kind_override);
  222. } else if constexpr (IsSame<ValueType, nullptr_t>) {
  223. return write_null(class_override, kind_override);
  224. } else if constexpr (IsOneOf<ValueType, Vector<int>, Span<int const>, Span<int>>) {
  225. return write_object_identifier(value, class_override, kind_override);
  226. } else if constexpr (IsSame<ValueType, BitStringView>) {
  227. return write_bit_string(value, class_override, kind_override);
  228. } else {
  229. dbgln("Unsupported type: {}", __PRETTY_FUNCTION__);
  230. return Error::from_string_literal("ASN1::Encoder: Trying to encode a value of an unsupported type");
  231. }
  232. }
  233. template<typename Fn>
  234. ErrorOr<void> write_constructed(Class class_, Kind kind, Fn&& fn)
  235. {
  236. return write_constructed(bit_cast<u8>(class_), bit_cast<u8>(kind), forward<Fn>(fn));
  237. }
  238. template<typename Fn>
  239. ErrorOr<void> write_constructed(u8 class_, u8 kind, Fn&& fn)
  240. {
  241. m_buffer_stack.empend();
  242. using ResultType = decltype(fn());
  243. if constexpr (IsSpecializationOf<ResultType, ErrorOr>) {
  244. TRY(fn());
  245. } else {
  246. fn();
  247. }
  248. auto buffer = m_buffer_stack.take_last();
  249. TRY(write_tag(bit_cast<Class>(class_), Type::Constructed, bit_cast<Kind>(kind)));
  250. TRY(write_length(buffer.size()));
  251. TRY(write_bytes(buffer.bytes()));
  252. return {};
  253. }
  254. private:
  255. ErrorOr<void> write_tag(Class, Type, Kind);
  256. ErrorOr<void> write_length(size_t);
  257. ErrorOr<void> write_bytes(ReadonlyBytes);
  258. ErrorOr<void> write_byte(u8);
  259. ErrorOr<void> write_boolean(bool, Optional<Class>, Optional<Kind>);
  260. ErrorOr<void> write_arbitrary_sized_integer(UnsignedBigInteger const&, Optional<Class>, Optional<Kind>);
  261. ErrorOr<void> write_printable_string(StringView, Optional<Class>, Optional<Kind>);
  262. ErrorOr<void> write_octet_string(ReadonlyBytes, Optional<Class>, Optional<Kind>);
  263. ErrorOr<void> write_null(Optional<Class>, Optional<Kind>);
  264. ErrorOr<void> write_object_identifier(Span<int const>, Optional<Class>, Optional<Kind>);
  265. ErrorOr<void> write_bit_string(BitStringView, Optional<Class>, Optional<Kind>);
  266. Vector<ByteBuffer> m_buffer_stack;
  267. };
  268. }