src/lib/BasicASN1Reader.h
author František Kučera <franta-hg@frantovo.cz>
Fri, 16 Jul 2021 21:01:02 +0200
branchv_0
changeset 31 a87c97aecbf6
parent 30 e27e133731ee
child 32 00d76921c547
permissions -rw-r--r--
parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     1
/**
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     2
 * Relational pipes
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     3
 * Copyright © 2021 František Kučera (Frantovo.cz, GlobalCode.info)
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     4
 *
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     5
 * This program is free software: you can redistribute it and/or modify
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     6
 * it under the terms of the GNU General Public License as published by
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     7
 * the Free Software Foundation, version 3 of the License.
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     8
 *
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
     9
 * This program is distributed in the hope that it will be useful,
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    12
 * GNU General Public License for more details.
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    13
 *
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    14
 * You should have received a copy of the GNU General Public License
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    15
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    16
 */
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    17
#pragma once
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    18
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    19
#include <memory>
4
7230e1ea0b07 proxy handlers forwarding events to all subordinate handlers
František Kučera <franta-hg@frantovo.cz>
parents: 1
diff changeset
    20
#include <vector>
12
243ef6c91dbb BasicASN1Reader: parse type and length as array
František Kučera <franta-hg@frantovo.cz>
parents: 11
diff changeset
    21
#include <array>
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    22
#include <sstream>
21
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
    23
#include <regex>
1
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    24
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    25
#include "ASN1Reader.h"
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    26
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    27
namespace relpipe {
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    28
namespace in {
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    29
namespace asn1 {
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    30
namespace lib {
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    31
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    32
/**
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    33
 * Reads ASN.1 data encoded as BER (DER, CER).
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    34
 */
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    35
class BasicASN1Reader : public ASN1Reader {
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    36
private:
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    37
13
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    38
	bool started = false;
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    39
25
ba79cebde109 move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 23
diff changeset
    40
	class BasicHeader : public ASN1ContentHandler::Header {
13
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    41
	public:
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    42
		bool definiteLength;
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    43
		size_t length;
1
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    44
	};
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    45
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    46
	class LevelMetadata {
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    47
	public:
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    48
		bool definiteLength;
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    49
		size_t length;
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    50
		size_t start;
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    51
	};
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    52
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    53
	std::vector<LevelMetadata> level;
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    54
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    55
	void checkRemainingItems() {
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    56
		if (level.size()) {
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    57
			LevelMetadata& l = level.back();
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    58
			if (l.definiteLength && l.length == getBytesRead() - l.start) {
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    59
				level.pop_back();
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    60
				handlers.writeCollectionEnd();
15
95ca127ba816 support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents: 14
diff changeset
    61
				checkRemainingItems(); // multiple collections may end at the same point
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    62
			}
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    63
		}
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    64
	}
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    65
25
ba79cebde109 move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 23
diff changeset
    66
	BasicHeader readHeader() {
ba79cebde109 move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 23
diff changeset
    67
		using TagClass = ASN1ContentHandler::TagClass;
ba79cebde109 move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 23
diff changeset
    68
		using PC = ASN1ContentHandler::PC;
ba79cebde109 move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 23
diff changeset
    69
ba79cebde109 move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 23
diff changeset
    70
		BasicHeader h;
13
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    71
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    72
		memset(&h, 0, sizeof (h)); // TODO: remove, not needed
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    73
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    74
		uint8_t tagByte;
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    75
		read(&tagByte, 1);
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    76
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    77
		h.tagClass = (TagClass) (tagByte >> 6);
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    78
		h.pc = (PC) ((tagByte >> 5) & 1);
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    79
		h.tag = tagByte & (0xFF >> 3);
19
b7431bc6069b support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents: 17
diff changeset
    80
		if (h.tag == 31) { // all five tag bits are set → tag number (greater than 30) is encoded in following octets
b7431bc6069b support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents: 17
diff changeset
    81
			h.tag = 0;
b7431bc6069b support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents: 17
diff changeset
    82
			uint8_t moreTag = 0;
b7431bc6069b support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents: 17
diff changeset
    83
			do {
b7431bc6069b support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents: 17
diff changeset
    84
				read(&moreTag, 1);
b7431bc6069b support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents: 17
diff changeset
    85
				h.tag = h.tag << 7 | (moreTag & (0xFF >> 1));
b7431bc6069b support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents: 17
diff changeset
    86
			} while (moreTag & (1 << 7));
b7431bc6069b support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents: 17
diff changeset
    87
		}
13
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    88
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    89
		uint8_t lengthByte;
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    90
		read(&lengthByte, 1);
1
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
    91
13
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    92
		if (lengthByte >> 7 == 0) {
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    93
			// definite short
13
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    94
			h.definiteLength = true;
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    95
			h.length = lengthByte;
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    96
		} else if (lengthByte == 0b10000000) {
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
    97
			// indefinite
13
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    98
			h.definiteLength = false;
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
    99
			h.length = 0;
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   100
		} else if (lengthByte == 0xFF) {
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   101
			throw relpipe::writer::RelpipeWriterException(L"ASN.1 lengthByte == 0xFF (reserved value)"); // TODO: better exception
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   102
		} else {
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   103
			// definite long
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   104
			h.definiteLength = true;
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   105
			h.length = 0;
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   106
			std::vector<uint8_t> lengthBytes(lengthByte & 0b01111111, 0);
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   107
			read(lengthBytes.data(), lengthBytes.size());
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   108
			for (uint8_t l : lengthBytes) h.length = (h.length << 8) + l;
13
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   109
		}
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   110
13
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   111
		return h;
d5e2cb9e31f1 switch TransactionalBuffer from char to uint8_t + partial parser of tags and lengths
František Kučera <franta-hg@frantovo.cz>
parents: 12
diff changeset
   112
	}
9
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   113
11
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   114
	void readNext() {
25
ba79cebde109 move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 23
diff changeset
   115
		using TagClass = ASN1ContentHandler::TagClass;
ba79cebde109 move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 23
diff changeset
   116
		using PC = ASN1ContentHandler::PC;
ba79cebde109 move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 23
diff changeset
   117
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   118
		checkRemainingItems();
25
ba79cebde109 move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 23
diff changeset
   119
		BasicHeader typeHeader = readHeader();
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   120
		// commit(); // TODO: commit here and recover later instead of rollback?
9
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   121
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   122
		if (!started) {
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   123
			handlers.writeStreamStart();
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   124
			started = true;
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   125
		}
15
95ca127ba816 support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents: 14
diff changeset
   126
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   127
		// TODO: check tagClass and pc
9
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   128
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   129
		// TODO: constants, more types
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   130
		if (typeHeader.tag == UniversalType::EndOfContent && typeHeader.tagClass == TagClass::Universal && typeHeader.pc == PC::Primitive) {
15
95ca127ba816 support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents: 14
diff changeset
   131
			handlers.writeCollectionEnd();
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   132
		} else if (typeHeader.tag == UniversalType::Sequence) {
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   133
			level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction
26
e39de9b8b3a1 move UniversalType to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   134
			handlers.writeCollectionStart(typeHeader);
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   135
		} else if (typeHeader.tag == UniversalType::Set) {
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   136
			level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction
26
e39de9b8b3a1 move UniversalType to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   137
			handlers.writeCollectionStart(typeHeader);
15
95ca127ba816 support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents: 14
diff changeset
   138
		} else if (typeHeader.pc == PC::Constructed) {
95ca127ba816 support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents: 14
diff changeset
   139
			level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction
26
e39de9b8b3a1 move UniversalType to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 25
diff changeset
   140
			handlers.writeCollectionStart(typeHeader);
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   141
		} else if (typeHeader.tag == UniversalType::Null && typeHeader.length == 0) {
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   142
			handlers.writeNull(typeHeader);
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   143
		} else if (typeHeader.tag == UniversalType::Boolean && typeHeader.definiteLength && typeHeader.length == 1) {
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   144
			bool value;
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   145
			read((uint8_t*) & value, 1);
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   146
			handlers.writeBoolean(typeHeader, value);
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   147
		} else if (typeHeader.tag == UniversalType::Integer && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
17
f5281ab3e68f some support for Integers
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   148
			// TODO: check available bytes before allocating buffer
f5281ab3e68f some support for Integers
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   149
			std::vector<uint8_t> value(typeHeader.length, 0x00);
f5281ab3e68f some support for Integers
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   150
			read(value.data(), typeHeader.length);
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   151
			handlers.writeInteger(typeHeader, ASN1ContentHandler::Integer(value));
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   152
		} else if (typeHeader.tag == UniversalType::ObjectIdentifier && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
20
fac034e3e867 support object identifiers (OID)
František Kučera <franta-hg@frantovo.cz>
parents: 19
diff changeset
   153
			std::vector<uint8_t> value(typeHeader.length, 0x00);
fac034e3e867 support object identifiers (OID)
František Kučera <franta-hg@frantovo.cz>
parents: 19
diff changeset
   154
			read(value.data(), typeHeader.length);
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   155
			handlers.writeOID(typeHeader,{value});
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   156
		} else if (typeHeader.tag == UniversalType::UTF8String && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
17
f5281ab3e68f some support for Integers
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   157
			// TODO: check available bytes before allocating buffer
16
bb457bb5b515 some support for UTF8String and PrintableString
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
   158
			std::string s;
bb457bb5b515 some support for UTF8String and PrintableString
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
   159
			s.resize(typeHeader.length);
bb457bb5b515 some support for UTF8String and PrintableString
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
   160
			read((uint8_t*) s.data(), typeHeader.length);
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   161
			handlers.writeTextString(typeHeader, s);
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   162
		} else if (typeHeader.tag == UniversalType::PrintableString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
16
bb457bb5b515 some support for UTF8String and PrintableString
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
   163
			// TODO: check encoding
17
f5281ab3e68f some support for Integers
František Kučera <franta-hg@frantovo.cz>
parents: 16
diff changeset
   164
			// TODO: check available bytes before allocating buffer
16
bb457bb5b515 some support for UTF8String and PrintableString
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
   165
			std::string s;
bb457bb5b515 some support for UTF8String and PrintableString
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
   166
			s.resize(typeHeader.length);
bb457bb5b515 some support for UTF8String and PrintableString
František Kučera <franta-hg@frantovo.cz>
parents: 15
diff changeset
   167
			read((uint8_t*) s.data(), typeHeader.length);
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   168
			handlers.writeTextString(typeHeader, s);
23
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   169
		} else if (typeHeader.tag == UniversalType::OctetString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   170
			// TODO: check available bytes before allocating buffer
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   171
			std::string s;
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   172
			s.resize(typeHeader.length);
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   173
			read((uint8_t*) s.data(), typeHeader.length);
31
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   174
			if (processEncapsulatedContent(typeHeader, s) == false) handlers.writeOctetString(typeHeader, s);
23
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   175
		} else if (typeHeader.tag == UniversalType::BitString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   176
			// TODO: check available bytes before allocating buffer
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   177
			std::string s;
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   178
			s.resize(typeHeader.length);
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   179
			read((uint8_t*) s.data(), typeHeader.length);
31
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   180
			if (processEncapsulatedContent(typeHeader, s) == false) {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   181
				std::vector<bool> bits;
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   182
				// TODO: throw exception on wrong padding or insufficient length?
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   183
				if (s.size() > 1) {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   184
					uint8_t padding = s[0];
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   185
					for (uint8_t j = padding; j < 8; j++) bits.push_back(s.back() & 1 << j);
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   186
					for (size_t i = s.size() - 2; i > 0; i--) for (uint8_t j = 0; j < 8; j++) bits.push_back(s[i] & 1 << j);
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   187
				}
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   188
				handlers.writeBitString(typeHeader, bits);
23
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   189
			}
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   190
		} else if (typeHeader.tag == UniversalType::UTCTime && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
21
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   191
			// TODO: check available bytes before allocating buffer
23
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   192
			// TODO: check encoding
21
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   193
			std::string s;
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   194
			s.resize(typeHeader.length);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   195
			read((uint8_t*) s.data(), typeHeader.length);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   196
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   197
			ASN1ContentHandler::DateTime dateTime;
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   198
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   199
			std::smatch match;
29
c232d8b8efbf UTCTime and GeneralizedTime clean-up and comment
František Kučera <franta-hg@frantovo.cz>
parents: 28
diff changeset
   200
			if (std::regex_match(s, match, std::regex("([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})?(Z|([+-][0-9]{2})([0-9]{2}))"))) {
21
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   201
				int i = 1;
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   202
				uint32_t year = std::stoi(match[i++]);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   203
				dateTime.year = year < 50 ? 2000 + year : 1900 + year;
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   204
				dateTime.month = std::stoi(match[i++]);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   205
				dateTime.day = std::stoi(match[i++]);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   206
				dateTime.hour = std::stoi(match[i++]);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   207
				dateTime.minute = std::stoi(match[i++]);
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   208
				dateTime.precision = match[i].length() ? ASN1ContentHandler::DateTime::Precision::Second : ASN1ContentHandler::DateTime::Precision::Minute;
28
fade2f562970 UTCTime: fix short variant
František Kučera <franta-hg@frantovo.cz>
parents: 27
diff changeset
   209
				dateTime.second = match[i].length() ? std::stoi(match[i]) : 0;
fade2f562970 UTCTime: fix short variant
František Kučera <franta-hg@frantovo.cz>
parents: 27
diff changeset
   210
				i++;
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   211
				if (match[i++] != "Z") {
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   212
					dateTime.timezoneHour = std::stoi(match[i++]);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   213
					dateTime.timezoneMinute = std::stoi(match[i++]);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   214
				}
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   215
				handlers.writeDateTime(typeHeader, dateTime);
21
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   216
			} else {
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   217
				throw std::invalid_argument("Unsupported UTCTime format: " + s); // TODO: better exception
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   218
			}
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   219
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   220
		} else if (typeHeader.tag == UniversalType::GeneralizedTime && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   221
			// TODO: check available bytes before allocating buffer
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   222
			std::string s;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   223
			s.resize(typeHeader.length);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   224
			read((uint8_t*) s.data(), typeHeader.length);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   225
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   226
			ASN1ContentHandler::DateTime dateTime;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   227
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   228
			std::smatch match;
29
c232d8b8efbf UTCTime and GeneralizedTime clean-up and comment
František Kučera <franta-hg@frantovo.cz>
parents: 28
diff changeset
   229
			if (std::regex_match(s, match, std::regex("([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})(\\.([0-9]{1,3}))?(Z|([+-][0-9]{2})([0-9]{2}))"))) {
c232d8b8efbf UTCTime and GeneralizedTime clean-up and comment
František Kučera <franta-hg@frantovo.cz>
parents: 28
diff changeset
   230
				// TODO: support also fractions of minutes and hours in GeneralizedTime
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   231
				int i = 1;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   232
				dateTime.year = std::stoi(match[i++]);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   233
				dateTime.month = std::stoi(match[i++]);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   234
				dateTime.day = std::stoi(match[i++]);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   235
				dateTime.hour = std::stoi(match[i++]);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   236
				dateTime.minute = std::stoi(match[i++]);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   237
				dateTime.second = match[i].length() ? std::stoi(match[i++]) : 0;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   238
				dateTime.precision = match[i++].length() ? ASN1ContentHandler::DateTime::Precision::Nanosecond : ASN1ContentHandler::DateTime::Precision::Second;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   239
				if (match[i].length() == 1) dateTime.nanosecond = std::stoi(match[i++]) * 100 * 1000000;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   240
				else if (match[i].length() == 2) dateTime.nanosecond = std::stoi(match[i++]) * 10 * 1000000;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   241
				else if (match[i].length() == 3) dateTime.nanosecond = std::stoi(match[i++]) * 1000000;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   242
				else i++;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   243
				if (match[i++] != "Z") {
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   244
					dateTime.timezoneHour = std::stoi(match[i++]);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   245
					dateTime.timezoneMinute = std::stoi(match[i++]);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   246
				}
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   247
				handlers.writeDateTime(typeHeader, dateTime);
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   248
			} else {
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   249
				throw std::invalid_argument("Unsupported GeneralizedTime format: " + s); // TODO: better exception
21
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   250
			}
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   251
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   252
		} else {
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   253
			// TODO: do not skip, parse
31
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   254
			// TODO: check available bytes before allocating buffer
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   255
			std::vector<uint8_t> temp(typeHeader.length, 0);
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   256
			read(temp.data(), typeHeader.length);
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   257
			// TODO: recover transaction?
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   258
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   259
			std::stringstream description;
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   260
			description << "value:"
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   261
					<< " tag = " << typeHeader.tag
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   262
					<< " tagClass = " << (int) typeHeader.tagClass
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   263
					<< " pc = " << (int) typeHeader.pc
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   264
					<< " length = " << typeHeader.length
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   265
					<< " definite = " << (typeHeader.definiteLength ? "true" : "false");
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   266
31
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   267
			// TODO: special event for unparsed? (instead of a text string)
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   268
			handlers.writeTextString(typeHeader, description.str());
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   269
		}
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   270
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   271
		commit();
9
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   272
	}
1
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   273
30
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   274
	bool hasAvailableForReading() {
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   275
		// TODO: API in AbstractParser for checking available bytes?
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   276
		uint8_t tmp;
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   277
		try {
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   278
			peek(&tmp, 1);
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   279
			return true;
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   280
		} catch (...) {
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   281
			return false;
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   282
		}
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   283
	}
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   284
31
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   285
	bool isValidBER(const std::string& input) {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   286
		BasicASN1Reader encapsulatedReader;
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   287
		try {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   288
			encapsulatedReader.write((const uint8_t*) input.c_str(), input.size());
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   289
			encapsulatedReader.close();
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   290
			return true;
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   291
		} catch (...) {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   292
			return false;
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   293
		}
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   294
	}
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   295
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   296
	class EncapsulatedASN1ContentHandler : public ASN1ContentHandlerProxy {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   297
	public:
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   298
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   299
		void writeStreamStart() override {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   300
			// skip this event
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   301
		}
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   302
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   303
		void writeStreamEnd() override {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   304
			// skip this event
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   305
		}
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   306
	};
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   307
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   308
	/**
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   309
	 * @param typeHeader
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   310
	 * @param input OCTET STRING or BIT STRING raw bytes
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   311
	 * @return whether we found valid content and passed parsed results to handlers
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   312
	 */
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   313
	bool processEncapsulatedContent(const BasicHeader& typeHeader, const std::string& input) {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   314
		// TODO: avoid double parsing + encapsulated content might be also processed at the XML/DOM level where we may even do conditional processing based on XPath (evaluate only certain octet- or bit- strings)
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   315
		// We may also do the same as with SEQUENCE or SET (continue nested reading in this ASN1Rreader instance), but it would require valid encapsulated data and would avoid easy fallback to raw OCTET or BIT STRING. We would also have to check the boundaries of the nested part.
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   316
		if (isValidBER(input)) {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   317
			handlers.writeCollectionStart(typeHeader);
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   318
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   319
			BasicASN1Reader encapsulatedReader;
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   320
			std::shared_ptr<EncapsulatedASN1ContentHandler> encapsulatedHandler = std::make_shared<EncapsulatedASN1ContentHandler>();
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   321
			encapsulatedHandler->addHandler(std::shared_ptr<ASN1ContentHandlerProxy>(&handlers, [](auto doNotDeleteHere) {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   322
			})); // FIXME: correct memory management
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   323
			encapsulatedReader.addHandler(encapsulatedHandler);
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   324
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   325
			encapsulatedReader.write((const uint8_t*) input.c_str(), input.size());
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   326
			encapsulatedReader.close();
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   327
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   328
			handlers.writeCollectionEnd();
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   329
			return true;
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   330
		} else {
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   331
			return false;
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   332
		}
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   333
	}
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   334
11
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   335
protected:
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   336
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   337
	void update() override {
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   338
		while (true) readNext();
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   339
	}
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   340
9
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   341
public:
1
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   342
9
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   343
	void close() override {
30
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   344
		if (hasAvailableForReading()) throw std::logic_error("Unexpected content at the end of the stream"); // TODO: better exception
31
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   345
		
a87c97aecbf6 parse encapsulated structures (octet string or bit string containing valid ASN.1): first dirty version
František Kučera <franta-hg@frantovo.cz>
parents: 30
diff changeset
   346
		// TODO: check also open sequences etc.; maybe in the handler
30
e27e133731ee throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents: 29
diff changeset
   347
15
95ca127ba816 support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents: 14
diff changeset
   348
		checkRemainingItems();
14
02725d301010 somehow parse nested SEQUENCEs and SETs + support definite long form of lengths (multiple length octets)
František Kučera <franta-hg@frantovo.cz>
parents: 13
diff changeset
   349
		// TODO: check the bytes remaining in the buffer
15
95ca127ba816 support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents: 14
diff changeset
   350
		if (started) handlers.writeStreamEnd();
1
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   351
	}
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   352
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   353
};
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   354
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   355
}
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   356
}
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   357
}
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   358
}