author | František Kučera <franta-hg@frantovo.cz> |
Thu, 22 Jul 2021 20:01:03 +0200 | |
branch | v_0 |
changeset 40 | 85b6f13f1088 |
parent 37 | 0845ca3636b6 |
permissions | -rw-r--r-- |
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" |
33
13aa7280ac7b
parse encapsulated structures (octet string or bit string containing valid ASN.1): add ValidatingASN1ContentHandler → avoid at least some false positives
František Kučera <franta-hg@frantovo.cz>
parents:
32
diff
changeset
|
26 |
#include "ValidatingASN1ContentHandler.h" |
40
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
27 |
#include "uri.h" |
1
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
28 |
|
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
29 |
namespace relpipe { |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
30 |
namespace in { |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
31 |
namespace asn1 { |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
32 |
namespace lib { |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
33 |
|
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 |
* 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
|
36 |
*/ |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
37 |
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
|
38 |
private: |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
39 |
|
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
|
40 |
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
|
41 |
|
40
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
42 |
bool parseEncapsulated = true; |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
43 |
|
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
44 |
/** |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
45 |
* TODO: use a common method |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
46 |
*/ |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
47 |
bool parseBoolean(const std::string& value) { |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
48 |
if (value == "true") return true; |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
49 |
else if (value == "false") return false; |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
50 |
else throw std::invalid_argument(std::string("Unable to parse boolean value: ") + value + " (expecting true or false)"); |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
51 |
} |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
52 |
|
25
ba79cebde109
move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
23
diff
changeset
|
53 |
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
|
54 |
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
|
55 |
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
|
56 |
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
|
57 |
}; |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
58 |
|
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
|
59 |
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
|
60 |
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
|
61 |
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
|
62 |
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
|
63 |
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
|
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 |
|
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
|
66 |
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
|
67 |
|
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
|
68 |
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
|
69 |
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
|
70 |
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
|
71 |
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
|
72 |
level.pop_back(); |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
73 |
handlers->writeCollectionEnd(); |
15
95ca127ba816
support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents:
14
diff
changeset
|
74 |
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
|
75 |
} |
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
|
76 |
} |
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
|
77 |
} |
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
|
78 |
|
25
ba79cebde109
move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
23
diff
changeset
|
79 |
BasicHeader readHeader() { |
ba79cebde109
move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
23
diff
changeset
|
80 |
using TagClass = ASN1ContentHandler::TagClass; |
ba79cebde109
move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
23
diff
changeset
|
81 |
using PC = ASN1ContentHandler::PC; |
ba79cebde109
move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
23
diff
changeset
|
82 |
|
ba79cebde109
move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
23
diff
changeset
|
83 |
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
|
84 |
|
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
|
85 |
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
|
86 |
|
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
|
87 |
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
|
88 |
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
|
89 |
|
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 |
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
|
91 |
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
|
92 |
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
|
93 |
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
|
94 |
h.tag = 0; |
b7431bc6069b
support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents:
17
diff
changeset
|
95 |
uint8_t moreTag = 0; |
b7431bc6069b
support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents:
17
diff
changeset
|
96 |
do { |
b7431bc6069b
support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents:
17
diff
changeset
|
97 |
read(&moreTag, 1); |
b7431bc6069b
support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents:
17
diff
changeset
|
98 |
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
|
99 |
} while (moreTag & (1 << 7)); |
b7431bc6069b
support tag numbers > 30 (multiple octets)
František Kučera <franta-hg@frantovo.cz>
parents:
17
diff
changeset
|
100 |
} |
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
|
101 |
|
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 |
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
|
103 |
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
|
104 |
|
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
|
105 |
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
|
106 |
// 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
|
107 |
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
|
108 |
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
|
109 |
} 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
|
110 |
// 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
|
111 |
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
|
112 |
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
|
113 |
} 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
|
114 |
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
|
115 |
} 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
|
116 |
// 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
|
117 |
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
|
118 |
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
|
119 |
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
|
120 |
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
|
121 |
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
|
122 |
} |
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
|
123 |
|
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
|
124 |
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
|
125 |
} |
9
7a6abdd00ab5
partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
8
diff
changeset
|
126 |
|
36
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
127 |
const std::string readString(size_t length) { |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
128 |
std::string result; |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
129 |
|
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
130 |
for (size_t remaining = length; remaining;) { |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
131 |
size_t current = std::min(remaining, (size_t) 3); |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
132 |
result.resize(result.size() + current); |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
133 |
read((uint8_t*) result.data() + result.size() - current, current); |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
134 |
remaining -= current; |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
135 |
} |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
136 |
|
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
137 |
return result; |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
138 |
} |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
139 |
|
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
140 |
const std::vector<uint8_t> readVector(size_t length) { |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
141 |
std::vector<uint8_t> result; |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
142 |
std::string s = readString(length); // TODO: read directly to the vector |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
143 |
result.resize(length); |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
144 |
for (size_t i = 0; i < length; i++) result[i] = (uint8_t) s[i]; |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
145 |
return result; |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
146 |
} |
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
147 |
|
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
148 |
void processNext() { |
25
ba79cebde109
move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
23
diff
changeset
|
149 |
using TagClass = ASN1ContentHandler::TagClass; |
ba79cebde109
move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
23
diff
changeset
|
150 |
using PC = ASN1ContentHandler::PC; |
ba79cebde109
move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
23
diff
changeset
|
151 |
|
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
|
152 |
checkRemainingItems(); |
25
ba79cebde109
move TagClass, PC and Header to ASN1ContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
23
diff
changeset
|
153 |
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
|
154 |
// 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
|
155 |
|
7a6abdd00ab5
partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
8
diff
changeset
|
156 |
if (!started) { |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
157 |
handlers->writeStreamStart(); |
9
7a6abdd00ab5
partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
8
diff
changeset
|
158 |
started = true; |
7a6abdd00ab5
partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
8
diff
changeset
|
159 |
} |
15
95ca127ba816
support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents:
14
diff
changeset
|
160 |
|
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
|
161 |
// TODO: check tagClass and pc |
9
7a6abdd00ab5
partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
8
diff
changeset
|
162 |
|
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
|
163 |
// TODO: constants, more types |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
164 |
if (typeHeader.tag == UniversalType::EndOfContent && typeHeader.tagClass == TagClass::Universal && typeHeader.pc == PC::Primitive) { |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
165 |
handlers->writeCollectionEnd(); |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
166 |
} 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
|
167 |
level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
168 |
handlers->writeCollectionStart(typeHeader); |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
169 |
} 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
|
170 |
level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
171 |
handlers->writeCollectionStart(typeHeader); |
15
95ca127ba816
support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents:
14
diff
changeset
|
172 |
} else if (typeHeader.pc == PC::Constructed) { |
95ca127ba816
support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents:
14
diff
changeset
|
173 |
level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
174 |
handlers->writeCollectionStart(typeHeader); |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
175 |
} else if (typeHeader.tag == UniversalType::Null && typeHeader.length == 0) { |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
176 |
handlers->writeNull(typeHeader); |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
177 |
} 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
|
178 |
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
|
179 |
read((uint8_t*) & value, 1); |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
180 |
handlers->writeBoolean(typeHeader, value); |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
181 |
} else if (typeHeader.tag == UniversalType::Integer && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
36
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
182 |
std::vector<uint8_t> value = readVector(typeHeader.length); |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
183 |
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
|
184 |
} 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
|
185 |
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
|
186 |
read(value.data(), typeHeader.length); |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
187 |
handlers->writeOID(typeHeader,{value}); |
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::UTF8String && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
36
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
189 |
std::string s = readString(typeHeader.length); |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
190 |
handlers->writeTextString(typeHeader, s); |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
191 |
} 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
|
192 |
// TODO: check encoding |
36
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
193 |
std::string s = readString(typeHeader.length); |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
194 |
handlers->writeTextString(typeHeader, s); |
23
8941a679299f
BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents:
22
diff
changeset
|
195 |
} else if (typeHeader.tag == UniversalType::OctetString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
36
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
196 |
std::string s = readString(typeHeader.length); |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
197 |
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
|
198 |
} else if (typeHeader.tag == UniversalType::BitString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
36
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
199 |
std::string s = readString(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
|
200 |
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
|
201 |
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
|
202 |
// 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
|
203 |
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
|
204 |
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
|
205 |
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
|
206 |
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
|
207 |
} |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
208 |
handlers->writeBitString(typeHeader, bits); |
23
8941a679299f
BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents:
22
diff
changeset
|
209 |
} |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
210 |
} else if (typeHeader.tag == UniversalType::UTCTime && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
23
8941a679299f
BitString and OctetString support
František Kučera <franta-hg@frantovo.cz>
parents:
22
diff
changeset
|
211 |
// TODO: check encoding |
36
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
212 |
std::string s = readString(typeHeader.length); |
21
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
213 |
|
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
214 |
ASN1ContentHandler::DateTime dateTime; |
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
215 |
|
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
216 |
std::smatch match; |
29
c232d8b8efbf
UTCTime and GeneralizedTime clean-up and comment
František Kučera <franta-hg@frantovo.cz>
parents:
28
diff
changeset
|
217 |
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
|
218 |
int i = 1; |
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
219 |
uint32_t year = std::stoi(match[i++]); |
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
220 |
dateTime.year = year < 50 ? 2000 + year : 1900 + year; |
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
221 |
dateTime.month = std::stoi(match[i++]); |
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
222 |
dateTime.day = std::stoi(match[i++]); |
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
223 |
dateTime.hour = std::stoi(match[i++]); |
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
224 |
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
|
225 |
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
|
226 |
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
|
227 |
i++; |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
228 |
if (match[i++] != "Z") { |
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
229 |
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
|
230 |
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
|
231 |
} |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
232 |
handlers->writeDateTime(typeHeader, dateTime); |
21
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
233 |
} else { |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
234 |
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
|
235 |
} |
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
236 |
|
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
237 |
} else if (typeHeader.tag == UniversalType::GeneralizedTime && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
36
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
238 |
std::string s = readString(typeHeader.length); |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
239 |
|
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
240 |
ASN1ContentHandler::DateTime dateTime; |
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
241 |
|
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
242 |
std::smatch match; |
29
c232d8b8efbf
UTCTime and GeneralizedTime clean-up and comment
František Kučera <franta-hg@frantovo.cz>
parents:
28
diff
changeset
|
243 |
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
|
244 |
// 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
|
245 |
int i = 1; |
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
246 |
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
|
247 |
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
|
248 |
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
|
249 |
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
|
250 |
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
|
251 |
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
|
252 |
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
|
253 |
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
|
254 |
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
|
255 |
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
|
256 |
else i++; |
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
257 |
if (match[i++] != "Z") { |
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
258 |
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
|
259 |
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
|
260 |
} |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
261 |
handlers->writeDateTime(typeHeader, dateTime); |
22
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
262 |
} else { |
9b6f86760384
slightly improved UTCTime and GeneralizedTime support
František Kučera <franta-hg@frantovo.cz>
parents:
21
diff
changeset
|
263 |
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
|
264 |
} |
705036445672
partial UTCTime support
František Kučera <franta-hg@frantovo.cz>
parents:
20
diff
changeset
|
265 |
|
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
|
266 |
} 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
|
267 |
// TODO: do not skip, parse |
36
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
268 |
std::string s = readString(typeHeader.length); |
35
bf2c546f49d1
format specific/unknown/unparsed/raw values in ASN1ContentHandler instead of in ASN1Reader
František Kučera <franta-hg@frantovo.cz>
parents:
34
diff
changeset
|
269 |
handlers->writeSpecific(typeHeader, s); |
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
|
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 |
|
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 |
commit(); |
9
7a6abdd00ab5
partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
8
diff
changeset
|
273 |
} |
1
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
274 |
|
30
e27e133731ee
throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents:
29
diff
changeset
|
275 |
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
|
276 |
// 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
|
277 |
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
|
278 |
try { |
e27e133731ee
throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents:
29
diff
changeset
|
279 |
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
|
280 |
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
|
281 |
} catch (...) { |
e27e133731ee
throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents:
29
diff
changeset
|
282 |
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
|
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 |
} |
e27e133731ee
throw error when we get superfluous octets at the end
František Kučera <franta-hg@frantovo.cz>
parents:
29
diff
changeset
|
285 |
|
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
|
286 |
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
|
287 |
BasicASN1Reader encapsulatedReader; |
33
13aa7280ac7b
parse encapsulated structures (octet string or bit string containing valid ASN.1): add ValidatingASN1ContentHandler → avoid at least some false positives
František Kučera <franta-hg@frantovo.cz>
parents:
32
diff
changeset
|
288 |
std::shared_ptr<ValidatingASN1ContentHandler> validatingHandler = std::make_shared<ValidatingASN1ContentHandler>(); |
13aa7280ac7b
parse encapsulated structures (octet string or bit string containing valid ASN.1): add ValidatingASN1ContentHandler → avoid at least some false positives
František Kučera <franta-hg@frantovo.cz>
parents:
32
diff
changeset
|
289 |
encapsulatedReader.addHandler(validatingHandler); |
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
|
290 |
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
|
291 |
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
|
292 |
encapsulatedReader.close(); |
37
0845ca3636b6
parse encapsulated structures (octet string or bit string containing valid ASN.1): add omitted finalCheck()
František Kučera <franta-hg@frantovo.cz>
parents:
36
diff
changeset
|
293 |
validatingHandler->finalCheck(); |
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
|
294 |
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
|
295 |
} 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
|
296 |
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
|
297 |
} |
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 |
|
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 |
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
|
301 |
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
|
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 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
|
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 |
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
|
308 |
// 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
|
309 |
} |
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 |
}; |
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 |
|
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 |
* @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
|
314 |
* @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
|
315 |
* @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
|
316 |
*/ |
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 |
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
|
318 |
// 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
|
319 |
// 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. |
40
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
320 |
if (parseEncapsulated && isValidBER(input)) { |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
321 |
handlers->writeCollectionStart(typeHeader); |
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
|
322 |
|
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 |
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
|
324 |
std::shared_ptr<EncapsulatedASN1ContentHandler> encapsulatedHandler = std::make_shared<EncapsulatedASN1ContentHandler>(); |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
325 |
encapsulatedHandler->addHandler(handlers); |
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
|
326 |
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
|
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 |
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
|
329 |
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
|
330 |
|
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
331 |
handlers->writeCollectionEnd(); |
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
|
332 |
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
|
333 |
} 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
|
334 |
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
|
335 |
} |
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
|
336 |
} |
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
|
337 |
|
11
8fbe93f78e2b
BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents:
9
diff
changeset
|
338 |
protected: |
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 |
void update() override { |
36
caed9146f72f
parse encapsulated structures (octet string or bit string containing valid ASN.1): reusable readString() method + let exception do its job on invalid input instead of attempt to allocate too much memory
František Kučera <franta-hg@frantovo.cz>
parents:
35
diff
changeset
|
341 |
while (true) processNext(); |
11
8fbe93f78e2b
BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents:
9
diff
changeset
|
342 |
} |
8fbe93f78e2b
BasicASN1Reader: read from the buffer and commit
František Kučera <franta-hg@frantovo.cz>
parents:
9
diff
changeset
|
343 |
|
9
7a6abdd00ab5
partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
8
diff
changeset
|
344 |
public: |
1
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
345 |
|
40
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
346 |
bool setOption(const std::string& uri, const std::string& value) override { |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
347 |
if (uri == option::Encoding && value == encoding::ber); // currently, we support only BER (and thus also CER and DER) encoding, but options have no actual effect – we just validate them |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
348 |
else if (uri == option::Encoding && value == encoding::cer); // in future versions, this might switch the parser into more strict mode |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
349 |
else if (uri == option::Encoding && value == encoding::der); // in future versions, this might switch the parser into more strict mode |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
350 |
else if (uri == option::Encoding && value == encoding::per) throw std::invalid_argument("PER encoding is not yet supported"); |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
351 |
else if (uri == option::Encoding && value == encoding::xer) throw std::invalid_argument("XER encoding is not yet supported"); |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
352 |
else if (uri == option::Encoding && value == encoding::asn1) throw std::invalid_argument("ASN.1 encoding is not yet supported"); |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
353 |
else if (uri == option::Encoding) throw std::invalid_argument("Unsupported ASN.1 encoding: " + value); |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
354 |
else if (uri == option::ParseEncapsulated) parseEncapsulated = parseBoolean(value); |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
355 |
else return false; |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
356 |
|
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
357 |
return true; |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
358 |
} |
85b6f13f1088
configuration: --parser-option encoding, parse-encapsulated, root-name, tree-style, tree-with-namespaces
František Kučera <franta-hg@frantovo.cz>
parents:
37
diff
changeset
|
359 |
|
9
7a6abdd00ab5
partial implementation of DOMBuildingXMLContentHandler
František Kučera <franta-hg@frantovo.cz>
parents:
8
diff
changeset
|
360 |
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
|
361 |
if (hasAvailableForReading()) throw std::logic_error("Unexpected content at the end of the stream"); // TODO: better exception |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
362 |
|
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
|
363 |
// 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
|
364 |
|
15
95ca127ba816
support constructed (like a collection)
František Kučera <franta-hg@frantovo.cz>
parents:
14
diff
changeset
|
365 |
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
|
366 |
// TODO: check the bytes remaining in the buffer |
32
00d76921c547
parse encapsulated structures (octet string or bit string containing valid ASN.1): improved memory management
František Kučera <franta-hg@frantovo.cz>
parents:
31
diff
changeset
|
367 |
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
|
368 |
} |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
369 |
|
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
370 |
}; |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
371 |
|
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
372 |
} |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
373 |
} |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
374 |
} |
2179f13227f4
AbstractParser: AbstractParser, ASN1Reader, ASN1ContentHandler, SAXContentHandler, BasicASN1Reader, DOMBuildingSAXContentHandler, GenericASN1ContentHandler skeletons
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
375 |
} |