ASN1.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. /*
  2. * Copyright (c) 2021, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/GenericLexer.h>
  7. #include <LibCrypto/ASN1/ASN1.h>
  8. namespace Crypto::ASN1 {
  9. ByteString kind_name(Kind kind)
  10. {
  11. switch (kind) {
  12. case Kind::Eol:
  13. return "EndOfList";
  14. case Kind::Boolean:
  15. return "Boolean";
  16. case Kind::Integer:
  17. return "Integer";
  18. case Kind::BitString:
  19. return "BitString";
  20. case Kind::OctetString:
  21. return "OctetString";
  22. case Kind::Null:
  23. return "Null";
  24. case Kind::ObjectIdentifier:
  25. return "ObjectIdentifier";
  26. case Kind::ObjectDescriptor:
  27. return "ObjectDescriptor";
  28. case Kind::External:
  29. return "External";
  30. case Kind::Real:
  31. return "Real";
  32. case Kind::Enumerated:
  33. return "Enumerated";
  34. case Kind::EmbeddedPdv:
  35. return "EmbeddedPdv";
  36. case Kind::Utf8String:
  37. return "Utf8String";
  38. case Kind::RelativeOid:
  39. return "RelativeOid";
  40. case Kind::Time:
  41. return "Time";
  42. case Kind::Reserved:
  43. return "Reserved";
  44. case Kind::Sequence:
  45. return "Sequence";
  46. case Kind::Set:
  47. return "Set";
  48. case Kind::NumericString:
  49. return "NumericString";
  50. case Kind::PrintableString:
  51. return "PrintableString";
  52. case Kind::T61String:
  53. return "T61String";
  54. case Kind::VideotexString:
  55. return "VideotexString";
  56. case Kind::IA5String:
  57. return "IA5String";
  58. case Kind::UTCTime:
  59. return "UTCTime";
  60. case Kind::GeneralizedTime:
  61. return "GeneralizedTime";
  62. case Kind::GraphicString:
  63. return "GraphicString";
  64. case Kind::VisibleString:
  65. return "VisibleString";
  66. case Kind::GeneralString:
  67. return "GeneralString";
  68. case Kind::UniversalString:
  69. return "UniversalString";
  70. case Kind::CharacterString:
  71. return "CharacterString";
  72. case Kind::BMPString:
  73. return "BMPString";
  74. case Kind::Date:
  75. return "Date";
  76. case Kind::TimeOfDay:
  77. return "TimeOfDay";
  78. case Kind::DateTime:
  79. return "DateTime";
  80. case Kind::Duration:
  81. return "Duration";
  82. case Kind::OidIri:
  83. return "OidIri";
  84. case Kind::RelativeOidIri:
  85. return "RelativeOidIri";
  86. }
  87. return "InvalidKind";
  88. }
  89. ByteString class_name(Class class_)
  90. {
  91. switch (class_) {
  92. case Class::Application:
  93. return "Application";
  94. case Class::Context:
  95. return "Context";
  96. case Class::Private:
  97. return "Private";
  98. case Class::Universal:
  99. return "Universal";
  100. }
  101. return "InvalidClass";
  102. }
  103. ByteString type_name(Type type)
  104. {
  105. switch (type) {
  106. case Type::Constructed:
  107. return "Constructed";
  108. case Type::Primitive:
  109. return "Primitive";
  110. }
  111. return "InvalidType";
  112. }
  113. Optional<Core::DateTime> parse_utc_time(StringView time)
  114. {
  115. // YYMMDDhhmm[ss]Z or YYMMDDhhmm[ss](+|-)hhmm
  116. GenericLexer lexer(time);
  117. auto year_in_century = lexer.consume(2).to_number<unsigned>();
  118. auto month = lexer.consume(2).to_number<unsigned>();
  119. auto day = lexer.consume(2).to_number<unsigned>();
  120. auto hour = lexer.consume(2).to_number<unsigned>();
  121. auto minute = lexer.consume(2).to_number<unsigned>();
  122. Optional<unsigned> seconds, offset_hours, offset_minutes;
  123. [[maybe_unused]] bool negative_offset = false;
  124. if (lexer.next_is(is_any_of("0123456789"sv))) {
  125. seconds = lexer.consume(2).to_number<unsigned>();
  126. if (!seconds.has_value()) {
  127. return {};
  128. }
  129. }
  130. if (lexer.next_is('Z')) {
  131. lexer.consume();
  132. } else if (lexer.next_is(is_any_of("+-"sv))) {
  133. negative_offset = lexer.consume() == '-';
  134. offset_hours = lexer.consume(2).to_number<unsigned>();
  135. offset_minutes = lexer.consume(2).to_number<unsigned>();
  136. if (!offset_hours.has_value() || !offset_minutes.has_value()) {
  137. return {};
  138. }
  139. } else {
  140. return {};
  141. }
  142. if (!year_in_century.has_value() || !month.has_value() || !day.has_value() || !hour.has_value() || !minute.has_value()) {
  143. return {};
  144. }
  145. // RFC5280 section 4.1.2.5.1.
  146. auto full_year = year_in_century.value();
  147. full_year += (full_year < 50) ? 2000 : 1900;
  148. auto full_seconds = seconds.value_or(0);
  149. // FIXME: Handle offsets!
  150. if (offset_hours.has_value() || offset_minutes.has_value())
  151. dbgln("FIXME: Implement UTCTime with offset!");
  152. return Core::DateTime::create(full_year, month.value(), day.value(), hour.value(), minute.value(), full_seconds);
  153. }
  154. Optional<Core::DateTime> parse_generalized_time(StringView time)
  155. {
  156. // YYYYMMDDhh[mm[ss[.fff]]] or YYYYMMDDhh[mm[ss[.fff]]]Z or YYYYMMDDhh[mm[ss[.fff]]](+|-)hhmm
  157. GenericLexer lexer(time);
  158. auto year = lexer.consume(4).to_number<unsigned>();
  159. auto month = lexer.consume(2).to_number<unsigned>();
  160. auto day = lexer.consume(2).to_number<unsigned>();
  161. auto hour = lexer.consume(2).to_number<unsigned>();
  162. Optional<unsigned> minute, seconds, milliseconds, offset_hours, offset_minutes;
  163. [[maybe_unused]] bool negative_offset = false;
  164. if (!lexer.is_eof()) {
  165. if (lexer.consume_specific('Z'))
  166. goto done_parsing;
  167. if (!lexer.next_is(is_any_of("+-"sv))) {
  168. minute = lexer.consume(2).to_number<unsigned>();
  169. if (!minute.has_value()) {
  170. return {};
  171. }
  172. if (lexer.is_eof() || lexer.consume_specific('Z'))
  173. goto done_parsing;
  174. }
  175. if (!lexer.next_is(is_any_of("+-"sv))) {
  176. seconds = lexer.consume(2).to_number<unsigned>();
  177. if (!seconds.has_value()) {
  178. return {};
  179. }
  180. if (lexer.is_eof() || lexer.consume_specific('Z'))
  181. goto done_parsing;
  182. }
  183. if (lexer.consume_specific('.')) {
  184. milliseconds = lexer.consume(3).to_number<unsigned>();
  185. if (!milliseconds.has_value()) {
  186. return {};
  187. }
  188. if (lexer.is_eof() || lexer.consume_specific('Z'))
  189. goto done_parsing;
  190. }
  191. if (lexer.next_is(is_any_of("+-"sv))) {
  192. negative_offset = lexer.consume() == '-';
  193. offset_hours = lexer.consume(2).to_number<unsigned>();
  194. offset_minutes = lexer.consume(2).to_number<unsigned>();
  195. if (!offset_hours.has_value() || !offset_minutes.has_value()) {
  196. return {};
  197. }
  198. }
  199. // Any character would be garbage.
  200. if (!lexer.is_eof()) {
  201. return {};
  202. }
  203. }
  204. done_parsing:;
  205. if (!year.has_value() || !month.has_value() || !day.has_value() || !hour.has_value()) {
  206. return {};
  207. }
  208. // FIXME: Handle offsets!
  209. if (offset_hours.has_value() || offset_minutes.has_value())
  210. dbgln("FIXME: Implement GeneralizedTime with offset!");
  211. // Unceremoniously drop the milliseconds on the floor.
  212. return Core::DateTime::create(year.value(), month.value(), day.value(), hour.value(), minute.value_or(0), seconds.value_or(0));
  213. }
  214. }