No Description

asn1_decoder.cpp 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. * Copyright (C) 2013 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "asn1_decoder.h"
  17. #include <stdint.h>
  18. int asn1_context::peek_byte() const {
  19. if (length_ == 0) {
  20. return -1;
  21. }
  22. return *p_;
  23. }
  24. int asn1_context::get_byte() {
  25. if (length_ == 0) {
  26. return -1;
  27. }
  28. int byte = *p_;
  29. p_++;
  30. length_--;
  31. return byte;
  32. }
  33. bool asn1_context::skip_bytes(size_t num_skip) {
  34. if (length_ < num_skip) {
  35. return false;
  36. }
  37. p_ += num_skip;
  38. length_ -= num_skip;
  39. return true;
  40. }
  41. bool asn1_context::decode_length(size_t* out_len) {
  42. int num_octets = get_byte();
  43. if (num_octets == -1) {
  44. return false;
  45. }
  46. if ((num_octets & 0x80) == 0x00) {
  47. *out_len = num_octets;
  48. return true;
  49. }
  50. num_octets &= kMaskTag;
  51. if (static_cast<size_t>(num_octets) >= sizeof(size_t)) {
  52. return false;
  53. }
  54. size_t length = 0;
  55. for (int i = 0; i < num_octets; ++i) {
  56. int byte = get_byte();
  57. if (byte == -1) {
  58. return false;
  59. }
  60. length <<= 8;
  61. length += byte;
  62. }
  63. *out_len = length;
  64. return true;
  65. }
  66. /**
  67. * Returns the constructed type and advances the pointer. E.g. A0 -> 0
  68. */
  69. asn1_context* asn1_context::asn1_constructed_get() {
  70. int type = get_byte();
  71. if (type == -1 || (type & kMaskConstructed) != kTagConstructed) {
  72. return nullptr;
  73. }
  74. size_t length;
  75. if (!decode_length(&length) || length > length_) {
  76. return nullptr;
  77. }
  78. asn1_context* app_ctx = new asn1_context(p_, length);
  79. app_ctx->app_type_ = type & kMaskAppType;
  80. return app_ctx;
  81. }
  82. bool asn1_context::asn1_constructed_skip_all() {
  83. int byte = peek_byte();
  84. while (byte != -1 && (byte & kMaskConstructed) == kTagConstructed) {
  85. skip_bytes(1);
  86. size_t length;
  87. if (!decode_length(&length) || !skip_bytes(length)) {
  88. return false;
  89. }
  90. byte = peek_byte();
  91. }
  92. return byte != -1;
  93. }
  94. int asn1_context::asn1_constructed_type() const {
  95. return app_type_;
  96. }
  97. asn1_context* asn1_context::asn1_sequence_get() {
  98. if ((get_byte() & kMaskTag) != kTagSequence) {
  99. return nullptr;
  100. }
  101. size_t length;
  102. if (!decode_length(&length) || length > length_) {
  103. return nullptr;
  104. }
  105. return new asn1_context(p_, length);
  106. }
  107. asn1_context* asn1_context::asn1_set_get() {
  108. if ((get_byte() & kMaskTag) != kTagSet) {
  109. return nullptr;
  110. }
  111. size_t length;
  112. if (!decode_length(&length) || length > length_) {
  113. return nullptr;
  114. }
  115. return new asn1_context(p_, length);
  116. }
  117. bool asn1_context::asn1_sequence_next() {
  118. size_t length;
  119. if (get_byte() == -1 || !decode_length(&length) || !skip_bytes(length)) {
  120. return false;
  121. }
  122. return true;
  123. }
  124. bool asn1_context::asn1_oid_get(const uint8_t** oid, size_t* length) {
  125. if (get_byte() != kTagOid) {
  126. return false;
  127. }
  128. if (!decode_length(length) || *length == 0 || *length > length_) {
  129. return false;
  130. }
  131. *oid = p_;
  132. return true;
  133. }
  134. bool asn1_context::asn1_octet_string_get(const uint8_t** octet_string, size_t* length) {
  135. if (get_byte() != kTagOctetString) {
  136. return false;
  137. }
  138. if (!decode_length(length) || *length == 0 || *length > length_) {
  139. return false;
  140. }
  141. *octet_string = p_;
  142. return true;
  143. }