DER.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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)
  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. private:
  33. ReadonlyBytes m_data;
  34. size_t m_unused_bits;
  35. };
  36. class Decoder {
  37. public:
  38. Decoder(ReadonlyBytes data)
  39. {
  40. m_stack.append(data);
  41. }
  42. // Read a tag without consuming it (and its data).
  43. ErrorOr<Tag> peek();
  44. bool eof() const;
  45. template<typename ValueType>
  46. struct TaggedValue {
  47. Tag tag;
  48. ValueType value;
  49. };
  50. ErrorOr<void> rewrite_tag(Kind kind)
  51. {
  52. if (m_stack.is_empty())
  53. return Error::from_string_view("Nothing on stack to rewrite"sv);
  54. if (eof())
  55. return Error::from_string_view("Stream is empty"sv);
  56. if (m_current_tag.has_value()) {
  57. m_current_tag->kind = kind;
  58. return {};
  59. }
  60. auto tag = TRY(read_tag());
  61. m_current_tag = tag;
  62. m_current_tag->kind = kind;
  63. return {};
  64. }
  65. ErrorOr<void> drop()
  66. {
  67. if (m_stack.is_empty())
  68. return Error::from_string_literal("ASN1::Decoder: Trying to drop using an empty stack");
  69. if (eof())
  70. return Error::from_string_literal("ASN1::Decoder: Trying to drop using a decoder that is EOF");
  71. auto previous_position = m_stack;
  72. auto tag_or_error = peek();
  73. if (tag_or_error.is_error()) {
  74. m_stack = move(previous_position);
  75. return tag_or_error.release_error();
  76. }
  77. auto length_or_error = read_length();
  78. if (length_or_error.is_error()) {
  79. m_stack = move(previous_position);
  80. return length_or_error.release_error();
  81. }
  82. auto length = length_or_error.value();
  83. auto bytes_result = read_bytes(length);
  84. if (bytes_result.is_error()) {
  85. m_stack = move(previous_position);
  86. return bytes_result.release_error();
  87. }
  88. m_current_tag.clear();
  89. return {};
  90. }
  91. template<typename ValueType>
  92. ErrorOr<ValueType> read(Optional<Class> class_override = {}, Optional<Kind> kind_override = {})
  93. {
  94. if (m_stack.is_empty())
  95. return Error::from_string_literal("ASN1::Decoder: Trying to read using an empty stack");
  96. if (eof())
  97. return Error::from_string_literal("ASN1::Decoder: Trying to read using a decoder that is EOF");
  98. auto previous_position = m_stack;
  99. auto tag_or_error = peek();
  100. if (tag_or_error.is_error()) {
  101. m_stack = move(previous_position);
  102. return tag_or_error.release_error();
  103. }
  104. auto length_or_error = read_length();
  105. if (length_or_error.is_error()) {
  106. m_stack = move(previous_position);
  107. return length_or_error.release_error();
  108. }
  109. auto tag = tag_or_error.value();
  110. auto length = length_or_error.value();
  111. auto value_or_error = read_value<ValueType>(class_override.value_or(tag.class_), kind_override.value_or(tag.kind), length);
  112. if (value_or_error.is_error()) {
  113. m_stack = move(previous_position);
  114. return value_or_error.release_error();
  115. }
  116. m_current_tag.clear();
  117. return value_or_error.release_value();
  118. }
  119. ErrorOr<void> enter();
  120. ErrorOr<void> leave();
  121. ErrorOr<ReadonlyBytes> peek_entry_bytes();
  122. private:
  123. template<typename ValueType, typename DecodedType>
  124. ErrorOr<ValueType> with_type_check(DecodedType&& value)
  125. {
  126. if constexpr (requires { ValueType { value }; })
  127. return ValueType { value };
  128. return Error::from_string_literal("ASN1::Decoder: Trying to decode a value from an incompatible type");
  129. }
  130. template<typename ValueType, typename DecodedType>
  131. ErrorOr<ValueType> with_type_check(ErrorOr<DecodedType>&& value_or_error)
  132. {
  133. if (value_or_error.is_error())
  134. return value_or_error.release_error();
  135. if constexpr (IsSame<ValueType, bool> && !IsSame<DecodedType, bool>) {
  136. return Error::from_string_literal("ASN1::Decoder: Trying to decode a boolean from a non-boolean type");
  137. } else {
  138. auto&& value = value_or_error.value();
  139. if constexpr (requires { ValueType { value }; })
  140. return ValueType { value };
  141. }
  142. return Error::from_string_literal("ASN1::Decoder: Trying to decode a value from an incompatible type");
  143. }
  144. template<typename ValueType>
  145. ErrorOr<ValueType> read_value(Class klass, Kind kind, size_t length)
  146. {
  147. auto data = TRY(read_bytes(length));
  148. if (klass != Class::Universal)
  149. return with_type_check<ValueType>(data);
  150. if (kind == Kind::Boolean)
  151. return with_type_check<ValueType>(decode_boolean(data));
  152. if (kind == Kind::Integer)
  153. return with_type_check<ValueType>(decode_arbitrary_sized_integer(data));
  154. if (kind == Kind::OctetString)
  155. return with_type_check<ValueType>(decode_octet_string(data));
  156. if (kind == Kind::Null)
  157. return with_type_check<ValueType>(decode_null(data));
  158. if (kind == Kind::ObjectIdentifier)
  159. return with_type_check<ValueType>(decode_object_identifier(data));
  160. if (kind == Kind::PrintableString || kind == Kind::IA5String || kind == Kind::UTCTime)
  161. return with_type_check<ValueType>(decode_printable_string(data));
  162. if (kind == Kind::Utf8String)
  163. return with_type_check<ValueType>(StringView { data.data(), data.size() });
  164. if (kind == Kind::BitString)
  165. return with_type_check<ValueType>(decode_bit_string(data));
  166. return with_type_check<ValueType>(data);
  167. }
  168. ErrorOr<Tag> read_tag();
  169. ErrorOr<size_t> read_length();
  170. ErrorOr<u8> read_byte();
  171. ErrorOr<ReadonlyBytes> read_bytes(size_t length);
  172. static ErrorOr<bool> decode_boolean(ReadonlyBytes);
  173. static ErrorOr<UnsignedBigInteger> decode_arbitrary_sized_integer(ReadonlyBytes);
  174. static ErrorOr<StringView> decode_octet_string(ReadonlyBytes);
  175. static ErrorOr<nullptr_t> decode_null(ReadonlyBytes);
  176. static ErrorOr<Vector<int>> decode_object_identifier(ReadonlyBytes);
  177. static ErrorOr<StringView> decode_printable_string(ReadonlyBytes);
  178. static ErrorOr<BitStringView> decode_bit_string(ReadonlyBytes);
  179. Vector<ReadonlyBytes> m_stack;
  180. Optional<Tag> m_current_tag;
  181. };
  182. ErrorOr<void> pretty_print(Decoder&, Stream&, int indent = 0);
  183. }