parser.cc 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/der/parser.h"
  5. #include "base/check.h"
  6. #include "net/der/parse_values.h"
  7. namespace net::der {
  8. Parser::Parser() {
  9. CBS_init(&cbs_, nullptr, 0);
  10. }
  11. Parser::Parser(const Input& input) {
  12. CBS_init(&cbs_, input.UnsafeData(), input.Length());
  13. }
  14. bool Parser::PeekTagAndValue(Tag* tag, Input* out) {
  15. CBS peeker = cbs_;
  16. CBS tmp_out;
  17. size_t header_len;
  18. unsigned tag_value;
  19. if (!CBS_get_any_asn1_element(&peeker, &tmp_out, &tag_value, &header_len) ||
  20. !CBS_skip(&tmp_out, header_len)) {
  21. return false;
  22. }
  23. advance_len_ = CBS_len(&tmp_out) + header_len;
  24. *tag = tag_value;
  25. *out = Input(CBS_data(&tmp_out), CBS_len(&tmp_out));
  26. return true;
  27. }
  28. bool Parser::Advance() {
  29. if (advance_len_ == 0)
  30. return false;
  31. bool ret = !!CBS_skip(&cbs_, advance_len_);
  32. advance_len_ = 0;
  33. return ret;
  34. }
  35. bool Parser::HasMore() {
  36. return CBS_len(&cbs_) > 0;
  37. }
  38. bool Parser::ReadRawTLV(Input* out) {
  39. CBS tmp_out;
  40. if (!CBS_get_any_asn1_element(&cbs_, &tmp_out, nullptr, nullptr))
  41. return false;
  42. *out = Input(CBS_data(&tmp_out), CBS_len(&tmp_out));
  43. return true;
  44. }
  45. bool Parser::ReadTagAndValue(Tag* tag, Input* out) {
  46. if (!PeekTagAndValue(tag, out))
  47. return false;
  48. CHECK(Advance());
  49. return true;
  50. }
  51. bool Parser::ReadOptionalTag(Tag tag, absl::optional<Input>* out) {
  52. if (!HasMore()) {
  53. *out = absl::nullopt;
  54. return true;
  55. }
  56. Tag actual_tag;
  57. Input value;
  58. if (!PeekTagAndValue(&actual_tag, &value)) {
  59. return false;
  60. }
  61. if (actual_tag == tag) {
  62. CHECK(Advance());
  63. *out = value;
  64. } else {
  65. advance_len_ = 0;
  66. *out = absl::nullopt;
  67. }
  68. return true;
  69. }
  70. bool Parser::ReadOptionalTag(Tag tag, Input* out, bool* present) {
  71. absl::optional<Input> tmp_out;
  72. if (!ReadOptionalTag(tag, &tmp_out))
  73. return false;
  74. *present = tmp_out.has_value();
  75. *out = tmp_out.value_or(der::Input());
  76. return true;
  77. }
  78. bool Parser::SkipOptionalTag(Tag tag, bool* present) {
  79. Input out;
  80. return ReadOptionalTag(tag, &out, present);
  81. }
  82. bool Parser::ReadTag(Tag tag, Input* out) {
  83. Tag actual_tag;
  84. Input value;
  85. if (!PeekTagAndValue(&actual_tag, &value) || actual_tag != tag) {
  86. return false;
  87. }
  88. CHECK(Advance());
  89. *out = value;
  90. return true;
  91. }
  92. bool Parser::SkipTag(Tag tag) {
  93. Input out;
  94. return ReadTag(tag, &out);
  95. }
  96. // Type-specific variants of ReadTag
  97. bool Parser::ReadConstructed(Tag tag, Parser* out) {
  98. if (!IsConstructed(tag))
  99. return false;
  100. Input data;
  101. if (!ReadTag(tag, &data))
  102. return false;
  103. *out = Parser(data);
  104. return true;
  105. }
  106. bool Parser::ReadSequence(Parser* out) {
  107. return ReadConstructed(kSequence, out);
  108. }
  109. bool Parser::ReadUint8(uint8_t* out) {
  110. Input encoded_int;
  111. if (!ReadTag(kInteger, &encoded_int))
  112. return false;
  113. return ParseUint8(encoded_int, out);
  114. }
  115. bool Parser::ReadUint64(uint64_t* out) {
  116. Input encoded_int;
  117. if (!ReadTag(kInteger, &encoded_int))
  118. return false;
  119. return ParseUint64(encoded_int, out);
  120. }
  121. absl::optional<BitString> Parser::ReadBitString() {
  122. Input value;
  123. if (!ReadTag(kBitString, &value))
  124. return absl::nullopt;
  125. return ParseBitString(value);
  126. }
  127. bool Parser::ReadGeneralizedTime(GeneralizedTime* out) {
  128. Input value;
  129. if (!ReadTag(kGeneralizedTime, &value))
  130. return false;
  131. return ParseGeneralizedTime(value, out);
  132. }
  133. } // namespace net::der