1 #include "asn1-cerstream.h"
5 Serializer& Serializer::operator<<(int32_t val) {
6 result.append(cer_encode_integer(val));
10 Serializer& Serializer::operator<<(
bool val) {
11 result.append(cer_encode_integer(
static_cast<int32_t
>(val)));
15 Serializer& Serializer::operator<<(
const std::string& val) {
16 result.append(cer_encode_string(val, last_type));
20 Serializer& Serializer::operator<<(ASN1_UniversalTag tag) {
22 result.push_back(
static_cast<char>(tag & 0xFF));
27 Serializer& Serializer::operator<<(
const Token& tok) {
31 result.push_back(
static_cast<char>(0x80));
33 case Token::endseq_tok:
34 case Token::endexpl_tok:
38 case Token::expl_tok: {
39 auto full_tag =
static_cast<uint8_t
>(
dynamic_cast<const ExplicitToken&
>(tok).tag |
40 dynamic_cast<const ExplicitToken&
>(tok).tag_class);
41 result.push_back(
static_cast<char>(full_tag | 0x20));
42 result.push_back(
static_cast<char>(0x80));
46 throw std::runtime_error(
"Unknown token type in ASN1 serialization");
51 Deserializer& Deserializer::operator>>(int32_t& val) {
52 if ((opt_count == 0) || opt_present) {
58 Deserializer& Deserializer::operator>>(
bool& val) {
59 if ((opt_count == 0) || opt_present) {
60 val = (int_param != 0);
65 Deserializer& Deserializer::operator>>(std::string& val) {
66 if ((opt_count == 0) || opt_present) {
72 Deserializer& Deserializer::operator>>(ASN1_UniversalTag tag) {
74 if ((opt_count != 0) && !opt_present && !opt_first) {
78 if (tag != cer_decode_token(
data, &endpos, &int_param, &string_param)) {
80 if ((opt_count != 0) && opt_first) {
88 if ((opt_count != 0) && opt_first) {
92 if (!seq_lengths.empty() && seq_lengths.top() > 0) {
93 seq_consumed.top() += endpos;
94 if (seq_consumed.top() > seq_lengths.top()) {
98 data =
data.substr(
static_cast<size_t>(endpos));
102 Deserializer& Deserializer::operator>>(
const Token& tok) {
106 if ((opt_count != 0) && !opt_present && !opt_first) {
107 if (tok.type == Token::endopt_tok) {
109 bool*
result =
dynamic_cast<const EndoptToken&
>(tok).result_p;
119 if (kAsn1Sequence != cer_decode_token(
data, &endpos, &seq_len,
nullptr)) {
120 if ((opt_count != 0) && opt_first) {
128 if ((opt_count != 0) && opt_first) {
133 data =
data.substr(
static_cast<size_t>(endpos));
134 seq_lengths.push(seq_len);
135 seq_consumed.push(0);
138 case Token::endseq_tok:
139 case Token::endexpl_tok: {
140 int32_t len = seq_lengths.top();
141 int32_t cons_len = seq_consumed.top();
145 if (cons_len != len) {
149 if (kAsn1EndSequence != cer_decode_token(
data, &endpos,
nullptr,
nullptr)) {
152 data =
data.substr(
static_cast<size_t>(endpos));
157 if (!seq_lengths.empty()) {
158 seq_consumed.top() += cons_len + 2;
163 case Token::restseq_tok: {
164 int32_t len = seq_lengths.top();
165 int32_t cons_len = seq_consumed.top();
169 while (len > cons_len) {
170 if (cer_decode_token(
data, &endpos,
nullptr,
nullptr) == kUnknown) {
173 data =
data.substr(
static_cast<size_t>(endpos));
176 if (cons_len != len) {
181 int32_t decoded_int = 0;
187 uint8_t ret = cer_decode_token(
data, &endpos, &decoded_int,
nullptr);
188 data =
data.substr(
static_cast<size_t>(endpos));
191 if (ret == kUnknown) {
194 if (ret == kAsn1Sequence) {
196 if (decoded_int == -1) {
199 }
else if (ret == kAsn1EndSequence) {
200 if (nestedness == 0) {
207 if (!seq_lengths.empty()) {
208 seq_consumed.top() += cons_len + 2;
213 case Token::expl_tok: {
214 auto full_tag =
static_cast<uint8_t
>(
dynamic_cast<const ExplicitToken&
>(tok).tag |
215 dynamic_cast<const ExplicitToken&
>(tok).tag_class);
216 if (full_tag != cer_decode_token(
data, &endpos, &seq_len,
nullptr)) {
217 if ((opt_count != 0) && opt_first) {
224 if ((opt_count != 0) && opt_first) {
229 data =
data.substr(
static_cast<size_t>(endpos));
230 seq_lengths.push(seq_len);
231 seq_consumed.push(0);
235 case Token::peekexpl_tok: {
236 uint8_t full_tag = cer_decode_token(
data, &endpos, &seq_len,
nullptr);
237 if (full_tag == kUnknown) {
240 if ((opt_count != 0) && opt_first) {
245 uint8_t* out_tag =
dynamic_cast<const PeekExplicitToken&
>(tok).tag;
246 ASN1_Class* out_tag_class =
dynamic_cast<const PeekExplicitToken&
>(tok).tag_class;
247 if (out_tag !=
nullptr) {
248 *out_tag = full_tag & 0x1F;
250 if (out_tag_class !=
nullptr) {
251 *out_tag_class =
static_cast<ASN1_Class
>(full_tag & 0xC0);
254 data =
data.substr(
static_cast<size_t>(endpos));
255 seq_lengths.push(seq_len);
256 seq_consumed.push(0);
265 case Token::endopt_tok: {
267 bool*
result =
dynamic_cast<const EndoptToken&
>(tok).result_p;
275 throw std::runtime_error(
"Unknown token type in ASN1 serialization");