DER.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  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> drop()
  50. {
  51. if (m_stack.is_empty())
  52. return Error::from_string_literal("ASN1::Decoder: Trying to drop using an empty stack");
  53. if (eof())
  54. return Error::from_string_literal("ASN1::Decoder: Trying to drop using a decoder that is EOF");
  55. auto previous_position = m_stack;
  56. auto tag_or_error = peek();
  57. if (tag_or_error.is_error()) {
  58. m_stack = move(previous_position);
  59. return tag_or_error.error();
  60. }
  61. auto length_or_error = read_length();
  62. if (length_or_error.is_error()) {
  63. m_stack = move(previous_position);
  64. return length_or_error.error();
  65. }
  66. auto length = length_or_error.value();
  67. auto bytes_result = read_bytes(length);
  68. if (bytes_result.is_error()) {
  69. m_stack = move(previous_position);
  70. return bytes_result.error();
  71. }
  72. m_current_tag.clear();
  73. return {};
  74. }
  75. template<typename ValueType>
  76. ErrorOr<ValueType> read(Optional<Class> class_override = {}, Optional<Kind> kind_override = {})
  77. {
  78. if (m_stack.is_empty())
  79. return Error::from_string_literal("ASN1::Decoder: Trying to read using an empty stack");
  80. if (eof())
  81. return Error::from_string_literal("ASN1::Decoder: Trying to read using a decoder that is EOF");
  82. auto previous_position = m_stack;
  83. auto tag_or_error = peek();
  84. if (tag_or_error.is_error()) {
  85. m_stack = move(previous_position);
  86. return tag_or_error.error();
  87. }
  88. auto length_or_error = read_length();
  89. if (length_or_error.is_error()) {
  90. m_stack = move(previous_position);
  91. return length_or_error.error();
  92. }
  93. auto tag = tag_or_error.value();
  94. auto length = length_or_error.value();
  95. auto value_or_error = read_value<ValueType>(class_override.value_or(tag.class_), kind_override.value_or(tag.kind), length);
  96. if (value_or_error.is_error()) {
  97. m_stack = move(previous_position);
  98. return value_or_error.error();
  99. }
  100. m_current_tag.clear();
  101. return value_or_error.release_value();
  102. }
  103. ErrorOr<void> enter();
  104. ErrorOr<void> leave();
  105. private:
  106. template<typename ValueType, typename DecodedType>
  107. ErrorOr<ValueType> with_type_check(DecodedType&& value)
  108. {
  109. if constexpr (requires { ValueType { value }; })
  110. return ValueType { value };
  111. return Error::from_string_literal("ASN1::Decoder: Trying to decode a value from an incompatible type");
  112. }
  113. template<typename ValueType, typename DecodedType>
  114. ErrorOr<ValueType> with_type_check(ErrorOr<DecodedType>&& value_or_error)
  115. {
  116. if (value_or_error.is_error())
  117. return value_or_error.error();
  118. if constexpr (IsSame<ValueType, bool> && !IsSame<DecodedType, bool>) {
  119. return Error::from_string_literal("ASN1::Decoder: Trying to decode a boolean from a non-boolean type");
  120. } else {
  121. auto&& value = value_or_error.value();
  122. if constexpr (requires { ValueType { value }; })
  123. return ValueType { value };
  124. }
  125. return Error::from_string_literal("ASN1::Decoder: Trying to decode a value from an incompatible type");
  126. }
  127. template<typename ValueType>
  128. ErrorOr<ValueType> read_value(Class klass, Kind kind, size_t length)
  129. {
  130. auto data_or_error = read_bytes(length);
  131. if (data_or_error.is_error())
  132. return data_or_error.error();
  133. auto data = data_or_error.value();
  134. if (klass != Class::Universal)
  135. return with_type_check<ValueType>(data);
  136. if (kind == Kind::Boolean)
  137. return with_type_check<ValueType>(decode_boolean(data));
  138. if (kind == Kind::Integer)
  139. return with_type_check<ValueType>(decode_arbitrary_sized_integer(data));
  140. if (kind == Kind::OctetString)
  141. return with_type_check<ValueType>(decode_octet_string(data));
  142. if (kind == Kind::Null)
  143. return with_type_check<ValueType>(decode_null(data));
  144. if (kind == Kind::ObjectIdentifier)
  145. return with_type_check<ValueType>(decode_object_identifier(data));
  146. if (kind == Kind::PrintableString || kind == Kind::IA5String || kind == Kind::UTCTime)
  147. return with_type_check<ValueType>(decode_printable_string(data));
  148. if (kind == Kind::Utf8String)
  149. return with_type_check<ValueType>(StringView { data.data(), data.size() });
  150. if (kind == Kind::BitString)
  151. return with_type_check<ValueType>(decode_bit_string(data));
  152. return with_type_check<ValueType>(data);
  153. }
  154. ErrorOr<Tag> read_tag();
  155. ErrorOr<size_t> read_length();
  156. ErrorOr<u8> read_byte();
  157. ErrorOr<ReadonlyBytes> read_bytes(size_t length);
  158. static ErrorOr<bool> decode_boolean(ReadonlyBytes);
  159. static ErrorOr<UnsignedBigInteger> decode_arbitrary_sized_integer(ReadonlyBytes);
  160. static ErrorOr<StringView> decode_octet_string(ReadonlyBytes);
  161. static ErrorOr<nullptr_t> decode_null(ReadonlyBytes);
  162. static ErrorOr<Vector<int>> decode_object_identifier(ReadonlyBytes);
  163. static ErrorOr<StringView> decode_printable_string(ReadonlyBytes);
  164. static ErrorOr<BitStringView> decode_bit_string(ReadonlyBytes);
  165. Vector<ReadonlyBytes> m_stack;
  166. Optional<Tag> m_current_tag;
  167. };
  168. ErrorOr<void> pretty_print(Decoder&, DeprecatedOutputStream&, int indent = 0);
  169. }