src/lib/BasicASN1Reader.h
author František Kučera <franta-hg@frantovo.cz>
Mon, 05 Jul 2021 19:31:25 +0200
branchv_0
changeset 28 fade2f562970
parent 27 d9cc2d356cdb
child 29 c232d8b8efbf
permissions -rw-r--r--
UTCTime: fix short variant
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);
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   174
			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);
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   180
			std::vector<bool> bits;
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   181
			// TODO: throw exception on wrong padding or insufficient length?
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   182
			if (s.size() > 1) {
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   183
				uint8_t padding = s[0];
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   184
				for (uint8_t j = padding; j < 8; j++) bits.push_back(s.back() & 1 << j);
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   185
				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);
8941a679299f BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents: 22
diff changeset
   186
			}
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   187
			handlers.writeBitString(typeHeader, bits);
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   188
		} 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
   189
			// 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
   190
			// TODO: check encoding
21
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   191
			std::string s;
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   192
			s.resize(typeHeader.length);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   193
			read((uint8_t*) s.data(), typeHeader.length);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   194
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   195
			ASN1ContentHandler::DateTime dateTime;
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
			std::smatch match;
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   198
			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})'?)"))) {
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   199
				// Supported UTCTime formats:
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   200
				// YYMMDDhhmmZ
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   201
				// YYMMDDhhmmssZ
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   202
				// YYMMDDhhmm+hhmm
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   203
				// YYMMDDhhmm-hhmm
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   204
				// YYMMDDhhmmss+hhmm
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   205
				// YYMMDDhhmmss-hhmm
21
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   206
				int i = 1;
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   207
				uint32_t year = std::stoi(match[i++]);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   208
				dateTime.year = year < 50 ? 2000 + year : 1900 + year;
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   209
				dateTime.month = std::stoi(match[i++]);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   210
				dateTime.day = std::stoi(match[i++]);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   211
				dateTime.hour = std::stoi(match[i++]);
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   212
				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
   213
				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
   214
				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
   215
				i++;
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   216
				if (match[i++] != "Z") {
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   217
					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
   218
					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
   219
				}
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   220
				handlers.writeDateTime(typeHeader, dateTime);
21
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   221
			} else {
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   222
				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
   223
			}
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   224
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   225
		} 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
   226
			// 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
   227
			std::string s;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   228
			s.resize(typeHeader.length);
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   229
			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
   230
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   231
			ASN1ContentHandler::DateTime dateTime;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   232
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   233
			std::smatch match;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   234
			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})'?)"))) {
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   235
				int i = 1;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   236
				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
   237
				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
   238
				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
   239
				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
   240
				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
   241
				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
   242
				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
   243
				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
   244
				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
   245
				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
   246
				else i++;
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   247
				if (match[i++] != "Z") {
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   248
					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
   249
					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
   250
				}
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   251
				handlers.writeDateTime(typeHeader, dateTime);
22
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   252
			} else {
9b6f86760384 slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents: 21
diff changeset
   253
				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
   254
			}
705036445672 partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents: 20
diff changeset
   255
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
   256
		} 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
   257
			// TODO: do not skip, parse
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
			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
   259
			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
   260
			// 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
   261
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
			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
   263
			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
   264
					<< " 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
   265
					<< " 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
   266
					<< " 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
   267
					<< " 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
   268
					<< " 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
   269
27
d9cc2d356cdb add common Header argument to ASN1ContentHandler methods
František Kučera <franta-hg@frantovo.cz>
parents: 26
diff changeset
   270
			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
   271
		}
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
   272
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
   273
		commit();
9
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   274
	}
1
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   275
11
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   276
protected:
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   277
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   278
	void update() override {
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   279
		while (true) readNext();
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   280
	}
8fbe93f78e2b BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents: 9
diff changeset
   281
9
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   282
public:
1
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   283
9
7a6abdd00ab5 partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents: 8
diff changeset
   284
	void close() override {
15
95ca127ba816 support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents: 14
diff changeset
   285
		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
   286
		// 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
   287
		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
   288
	}
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   289
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   290
};
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   291
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   292
}
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   293
}
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   294
}
2179f13227f4 AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff changeset
   295
}