author | František Kučera <franta-hg@frantovo.cz> |
Mon, 26 Jul 2021 23:41:18 +0200 | |
branch | v_0 |
changeset 6 | 523c9c39c996 |
parent 1 | 68a281aefa76 |
permissions | -rw-r--r-- |
1
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
1 |
/** |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
2 |
* Relational pipes |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
3 |
* Copyright © 2021 František Kučera (Frantovo.cz, GlobalCode.info) |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
4 |
* |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
5 |
* This program is free software: you can redistribute it and/or modify |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
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 |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
7 |
* the Free Software Foundation, version 3 of the License. |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
8 |
* |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
9 |
* This program is distributed in the hope that it will be useful, |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
12 |
* GNU General Public License for more details. |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
13 |
* |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
14 |
* You should have received a copy of the GNU General Public License |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
15 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
16 |
*/ |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
17 |
#pragma once |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
18 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
19 |
#include <memory> |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
20 |
#include <vector> |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
21 |
#include <array> |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
22 |
#include <sstream> |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
23 |
#include <regex> |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
24 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
25 |
#include "ASN1Reader.h" |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
26 |
#include "ValidatingASN1ContentHandler.h" |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
27 |
#include "uri.h" |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
28 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
29 |
namespace relpipe { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
30 |
namespace in { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
31 |
namespace asn1 { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
32 |
namespace lib { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
33 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
34 |
/** |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
35 |
* Reads ASN.1 data encoded as BER (DER, CER). |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
36 |
*/ |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
37 |
class BasicASN1Reader : public ASN1Reader { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
38 |
private: |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
39 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
40 |
bool started = false; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
41 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
42 |
bool parseEncapsulated = true; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
43 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
44 |
/** |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
45 |
* TODO: use a common method |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
46 |
*/ |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
47 |
bool parseBoolean(const std::string& value) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
48 |
if (value == "true") return true; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
49 |
else if (value == "false") return false; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
50 |
else throw std::invalid_argument(std::string("Unable to parse boolean value: ") + value + " (expecting true or false)"); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
51 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
52 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
53 |
class BasicHeader : public ASN1ContentHandler::Header { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
54 |
public: |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
55 |
bool definiteLength; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
56 |
size_t length; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
57 |
}; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
58 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
59 |
class LevelMetadata { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
60 |
public: |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
61 |
bool definiteLength; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
62 |
size_t length; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
63 |
size_t start; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
64 |
}; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
65 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
66 |
std::vector<LevelMetadata> level; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
67 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
68 |
void checkRemainingItems() { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
69 |
if (level.size()) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
70 |
LevelMetadata& l = level.back(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
71 |
if (l.definiteLength && l.length == getBytesRead() - l.start) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
72 |
level.pop_back(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
73 |
handlers->writeCollectionEnd(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
74 |
checkRemainingItems(); // multiple collections may end at the same point |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
75 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
76 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
77 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
78 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
79 |
BasicHeader readHeader() { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
80 |
using TagClass = ASN1ContentHandler::TagClass; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
81 |
using PC = ASN1ContentHandler::PC; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
82 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
83 |
BasicHeader h; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
84 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
85 |
memset(&h, 0, sizeof (h)); // TODO: remove, not needed |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
86 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
87 |
uint8_t tagByte; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
88 |
read(&tagByte, 1); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
89 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
90 |
h.tagClass = (TagClass) (tagByte >> 6); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
91 |
h.pc = (PC) ((tagByte >> 5) & 1); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
92 |
h.tag = tagByte & (0xFF >> 3); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
93 |
if (h.tag == 31) { // all five tag bits are set → tag number (greater than 30) is encoded in following octets |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
94 |
h.tag = 0; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
95 |
uint8_t moreTag = 0; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
96 |
do { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
97 |
read(&moreTag, 1); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
98 |
h.tag = h.tag << 7 | (moreTag & (0xFF >> 1)); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
99 |
} while (moreTag & (1 << 7)); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
100 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
101 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
102 |
uint8_t lengthByte; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
103 |
read(&lengthByte, 1); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
104 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
105 |
if (lengthByte >> 7 == 0) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
106 |
// definite short |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
107 |
h.definiteLength = true; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
108 |
h.length = lengthByte; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
109 |
} else if (lengthByte == 0b10000000) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
110 |
// indefinite |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
111 |
h.definiteLength = false; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
112 |
h.length = 0; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
113 |
} else if (lengthByte == 0xFF) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
114 |
throw relpipe::writer::RelpipeWriterException(L"ASN.1 lengthByte == 0xFF (reserved value)"); // TODO: better exception |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
115 |
} else { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
116 |
// definite long |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
117 |
h.definiteLength = true; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
118 |
h.length = 0; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
119 |
std::vector<uint8_t> lengthBytes(lengthByte & 0b01111111, 0); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
120 |
read(lengthBytes.data(), lengthBytes.size()); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
121 |
for (uint8_t l : lengthBytes) h.length = (h.length << 8) + l; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
122 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
123 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
124 |
return h; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
125 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
126 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
127 |
const std::string readString(size_t length) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
128 |
std::string result; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
129 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
130 |
for (size_t remaining = length; remaining;) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
131 |
size_t current = std::min(remaining, (size_t) 3); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
132 |
result.resize(result.size() + current); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
133 |
read((uint8_t*) result.data() + result.size() - current, current); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
134 |
remaining -= current; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
135 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
136 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
137 |
return result; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
138 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
139 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
140 |
const std::vector<uint8_t> readVector(size_t length) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
141 |
std::vector<uint8_t> result; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
142 |
std::string s = readString(length); // TODO: read directly to the vector |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
143 |
result.resize(length); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
144 |
for (size_t i = 0; i < length; i++) result[i] = (uint8_t) s[i]; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
145 |
return result; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
146 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
147 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
148 |
void processNext() { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
149 |
using TagClass = ASN1ContentHandler::TagClass; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
150 |
using PC = ASN1ContentHandler::PC; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
151 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
152 |
checkRemainingItems(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
153 |
BasicHeader typeHeader = readHeader(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
154 |
// commit(); // TODO: commit here and recover later instead of rollback? |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
155 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
156 |
if (!started) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
157 |
handlers->writeStreamStart(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
158 |
started = true; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
159 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
160 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
161 |
// TODO: check tagClass and pc |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
162 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
163 |
// TODO: constants, more types |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
164 |
if (typeHeader.tag == UniversalType::EndOfContent && typeHeader.tagClass == TagClass::Universal && typeHeader.pc == PC::Primitive) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
165 |
handlers->writeCollectionEnd(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
166 |
} else if (typeHeader.tag == UniversalType::Sequence) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
167 |
level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
168 |
handlers->writeCollectionStart(typeHeader); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
169 |
} else if (typeHeader.tag == UniversalType::Set) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
170 |
level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
171 |
handlers->writeCollectionStart(typeHeader); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
172 |
} else if (typeHeader.pc == PC::Constructed) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
173 |
level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
174 |
handlers->writeCollectionStart(typeHeader); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
175 |
} else if (typeHeader.tag == UniversalType::Null && typeHeader.length == 0) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
176 |
handlers->writeNull(typeHeader); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
177 |
} else if (typeHeader.tag == UniversalType::Boolean && typeHeader.definiteLength && typeHeader.length == 1) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
178 |
bool value; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
179 |
read((uint8_t*) & value, 1); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
180 |
handlers->writeBoolean(typeHeader, value); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
181 |
} else if (typeHeader.tag == UniversalType::Integer && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
182 |
std::vector<uint8_t> value = readVector(typeHeader.length); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
183 |
handlers->writeInteger(typeHeader, ASN1ContentHandler::Integer(value)); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
184 |
} else if (typeHeader.tag == UniversalType::ObjectIdentifier && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
185 |
std::vector<uint8_t> value(typeHeader.length, 0x00); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
186 |
read(value.data(), typeHeader.length); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
187 |
handlers->writeOID(typeHeader,{value}); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
188 |
} else if (typeHeader.tag == UniversalType::UTF8String && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
189 |
std::string s = readString(typeHeader.length); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
190 |
handlers->writeTextString(typeHeader, s); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
191 |
} else if (typeHeader.tag == UniversalType::PrintableString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
192 |
// TODO: check encoding |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
193 |
std::string s = readString(typeHeader.length); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
194 |
handlers->writeTextString(typeHeader, s); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
195 |
} else if (typeHeader.tag == UniversalType::OctetString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
196 |
std::string s = readString(typeHeader.length); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
197 |
if (processEncapsulatedContent(typeHeader, s) == false) handlers->writeOctetString(typeHeader, s); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
198 |
} else if (typeHeader.tag == UniversalType::BitString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
199 |
std::string s = readString(typeHeader.length); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
200 |
if (processEncapsulatedContent(typeHeader, s) == false) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
201 |
std::vector<bool> bits; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
202 |
// TODO: throw exception on wrong padding or insufficient length? |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
203 |
if (s.size() > 1) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
204 |
uint8_t padding = s[0]; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
205 |
for (uint8_t j = padding; j < 8; j++) bits.push_back(s.back() & 1 << j); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
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); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
207 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
208 |
handlers->writeBitString(typeHeader, bits); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
209 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
210 |
} else if (typeHeader.tag == UniversalType::UTCTime && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
211 |
// TODO: check encoding |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
212 |
std::string s = readString(typeHeader.length); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
213 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
214 |
ASN1ContentHandler::DateTime dateTime; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
215 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
216 |
std::smatch match; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
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}))"))) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
218 |
int i = 1; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
219 |
uint32_t year = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
220 |
dateTime.year = year < 50 ? 2000 + year : 1900 + year; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
221 |
dateTime.month = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
222 |
dateTime.day = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
223 |
dateTime.hour = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
224 |
dateTime.minute = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
225 |
dateTime.precision = match[i].length() ? ASN1ContentHandler::DateTime::Precision::Second : ASN1ContentHandler::DateTime::Precision::Minute; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
226 |
dateTime.second = match[i].length() ? std::stoi(match[i]) : 0; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
227 |
i++; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
228 |
if (match[i++] != "Z") { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
229 |
dateTime.timezoneHour = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
230 |
dateTime.timezoneMinute = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
231 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
232 |
handlers->writeDateTime(typeHeader, dateTime); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
233 |
} else { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
234 |
throw std::invalid_argument("Unsupported UTCTime format: " + s); // TODO: better exception |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
235 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
236 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
237 |
} else if (typeHeader.tag == UniversalType::GeneralizedTime && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
238 |
std::string s = readString(typeHeader.length); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
239 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
240 |
ASN1ContentHandler::DateTime dateTime; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
241 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
242 |
std::smatch match; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
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}))"))) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
244 |
// TODO: support also fractions of minutes and hours in GeneralizedTime |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
245 |
int i = 1; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
246 |
dateTime.year = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
247 |
dateTime.month = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
248 |
dateTime.day = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
249 |
dateTime.hour = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
250 |
dateTime.minute = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
251 |
dateTime.second = match[i].length() ? std::stoi(match[i++]) : 0; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
252 |
dateTime.precision = match[i++].length() ? ASN1ContentHandler::DateTime::Precision::Nanosecond : ASN1ContentHandler::DateTime::Precision::Second; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
253 |
if (match[i].length() == 1) dateTime.nanosecond = std::stoi(match[i++]) * 100 * 1000000; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
254 |
else if (match[i].length() == 2) dateTime.nanosecond = std::stoi(match[i++]) * 10 * 1000000; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
255 |
else if (match[i].length() == 3) dateTime.nanosecond = std::stoi(match[i++]) * 1000000; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
256 |
else i++; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
257 |
if (match[i++] != "Z") { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
258 |
dateTime.timezoneHour = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
259 |
dateTime.timezoneMinute = std::stoi(match[i++]); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
260 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
261 |
handlers->writeDateTime(typeHeader, dateTime); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
262 |
} else { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
263 |
throw std::invalid_argument("Unsupported GeneralizedTime format: " + s); // TODO: better exception |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
264 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
265 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
266 |
} else { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
267 |
// TODO: do not skip, parse |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
268 |
std::string s = readString(typeHeader.length); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
269 |
handlers->writeSpecific(typeHeader, s); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
270 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
271 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
272 |
commit(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
273 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
274 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
275 |
bool hasAvailableForReading() { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
276 |
// TODO: API in AbstractParser for checking available bytes? |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
277 |
uint8_t tmp; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
278 |
try { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
279 |
peek(&tmp, 1); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
280 |
return true; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
281 |
} catch (...) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
282 |
return false; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
283 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
284 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
285 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
286 |
bool isValidBER(const std::string& input) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
287 |
BasicASN1Reader encapsulatedReader; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
288 |
std::shared_ptr<ValidatingASN1ContentHandler> validatingHandler = std::make_shared<ValidatingASN1ContentHandler>(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
289 |
encapsulatedReader.addHandler(validatingHandler); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
290 |
try { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
291 |
encapsulatedReader.write((const uint8_t*) input.c_str(), input.size()); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
292 |
encapsulatedReader.close(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
293 |
validatingHandler->finalCheck(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
294 |
return true; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
295 |
} catch (...) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
296 |
return false; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
297 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
298 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
299 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
300 |
class EncapsulatedASN1ContentHandler : public ASN1ContentHandlerProxy { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
301 |
public: |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
302 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
303 |
void writeStreamStart() override { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
304 |
// skip this event |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
305 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
306 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
307 |
void writeStreamEnd() override { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
308 |
// skip this event |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
309 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
310 |
}; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
311 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
312 |
/** |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
313 |
* @param typeHeader |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
314 |
* @param input OCTET STRING or BIT STRING raw bytes |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
315 |
* @return whether we found valid content and passed parsed results to handlers |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
316 |
*/ |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
317 |
bool processEncapsulatedContent(const BasicHeader& typeHeader, const std::string& input) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
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) |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
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. |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
320 |
if (parseEncapsulated && isValidBER(input)) { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
321 |
handlers->writeCollectionStart(typeHeader); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
322 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
323 |
BasicASN1Reader encapsulatedReader; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
324 |
std::shared_ptr<EncapsulatedASN1ContentHandler> encapsulatedHandler = std::make_shared<EncapsulatedASN1ContentHandler>(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
325 |
encapsulatedHandler->addHandler(handlers); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
326 |
encapsulatedReader.addHandler(encapsulatedHandler); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
327 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
328 |
encapsulatedReader.write((const uint8_t*) input.c_str(), input.size()); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
329 |
encapsulatedReader.close(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
330 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
331 |
handlers->writeCollectionEnd(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
332 |
return true; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
333 |
} else { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
334 |
return false; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
335 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
336 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
337 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
338 |
protected: |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
339 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
340 |
void update() override { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
341 |
while (true) processNext(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
342 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
343 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
344 |
public: |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
345 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
346 |
bool setOption(const std::string& uri, const std::string& value) override { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
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 |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
348 |
else if (uri == option::Encoding && value == encoding::cer); // in future versions, this might switch the parser into more strict mode |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
349 |
else if (uri == option::Encoding && value == encoding::der); // in future versions, this might switch the parser into more strict mode |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
350 |
else if (uri == option::Encoding && value == encoding::per) throw std::invalid_argument("PER encoding is not yet supported"); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
351 |
else if (uri == option::Encoding && value == encoding::xer) throw std::invalid_argument("XER encoding is not yet supported"); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
352 |
else if (uri == option::Encoding && value == encoding::asn1) throw std::invalid_argument("ASN.1 encoding is not yet supported"); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
353 |
else if (uri == option::Encoding) throw std::invalid_argument("Unsupported ASN.1 encoding: " + value); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
354 |
else if (uri == option::ParseEncapsulated) parseEncapsulated = parseBoolean(value); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
355 |
else return false; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
356 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
357 |
return true; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
358 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
359 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
360 |
void close() override { |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
361 |
if (hasAvailableForReading()) throw std::logic_error("Unexpected content at the end of the stream"); // TODO: better exception |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
362 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
363 |
// TODO: check also open sequences etc.; maybe in the handler |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
364 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
365 |
checkRemainingItems(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
366 |
// TODO: check the bytes remaining in the buffer |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
367 |
if (started) handlers->writeStreamEnd(); |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
368 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
369 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
370 |
}; |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
371 |
|
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
372 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
373 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
374 |
} |
68a281aefa76
import common parser code from relpipe-in-asn1table (85b6f13f1088)
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
375 |
} |