31 * Reads ASN.1 data encoded as BER (DER, CER). |
31 * Reads ASN.1 data encoded as BER (DER, CER). |
32 */ |
32 */ |
33 class BasicASN1Reader : public ASN1Reader { |
33 class BasicASN1Reader : public ASN1Reader { |
34 private: |
34 private: |
35 |
35 |
36 enum class State { |
36 bool started = false; |
37 A, |
37 |
38 B, |
38 enum class TagClass : uint8_t { |
39 C |
39 Universal = 0, |
|
40 Application = 1, |
|
41 ContextSpecific = 2, |
|
42 Private = 3 |
40 }; |
43 }; |
41 |
44 |
42 State state = State::A; |
45 enum class PC : uint8_t { |
|
46 Primitive = 0, |
|
47 Constructed = 1 |
|
48 }; |
43 |
49 |
44 bool started = false; |
50 class Header { |
|
51 public: |
|
52 TagClass tagClass; |
|
53 PC pc; |
|
54 uint64_t tag; |
|
55 bool definiteLength; |
|
56 size_t length; |
|
57 }; |
|
58 |
|
59 Header readHeader() { |
|
60 Header h; |
|
61 |
|
62 memset(&h, 0, sizeof (h)); // TODO: remove, not needed |
|
63 |
|
64 uint8_t tagByte; |
|
65 read(&tagByte, 1); |
|
66 |
|
67 h.tagClass = (TagClass) (tagByte >> 6); |
|
68 h.pc = (PC) ((tagByte >> 5) & 1); |
|
69 h.tag = tagByte & (0xFF >> 3); |
|
70 if (h.tag > 30) throw relpipe::writer::RelpipeWriterException(L"not yet implemented, ASN.1 tag > 30"); // FIXME: higher tag values → read more bytes |
|
71 |
|
72 uint8_t lengthByte; |
|
73 read(&lengthByte, 1); |
|
74 |
|
75 std::wcerr << L"lengthByte = " << lengthByte << std::endl; |
|
76 |
|
77 if (lengthByte >> 7 == 0) { |
|
78 h.definiteLength = true; |
|
79 h.length = lengthByte; |
|
80 } else if (lengthByte == 0b10000000) { |
|
81 h.definiteLength = false; |
|
82 h.length = 0; |
|
83 } else if (lengthByte == 0xFF) { |
|
84 throw relpipe::writer::RelpipeWriterException(L"ASN.1 lengthByte == 0xFF (reserved value)"); // TODO: better exception |
|
85 } else { |
|
86 // FIXME: longer values |
|
87 throw relpipe::writer::RelpipeWriterException(L"not yet implemented, ASN.1 lengthBytes: longer value"); // TODO: better exception |
|
88 } |
|
89 |
|
90 return h; |
|
91 } |
45 |
92 |
46 void readNext() { |
93 void readNext() { |
47 std::array<char, 2> typeAndLength; |
94 Header typeHeader = readHeader(); |
48 read(typeAndLength.data(), typeAndLength.size()); |
|
49 commit(); |
95 commit(); |
50 |
96 |
51 if (!started) { |
97 if (!started) { |
52 handlers.writeStreamStart(); |
98 handlers.writeStreamStart(); |
53 started = true; |
99 started = true; |
54 } |
100 } |
55 |
101 |
56 handlers.writeCollectionStart(ASN1ContentHandler::CollectionType::Sequence); |
102 handlers.writeCollectionStart(ASN1ContentHandler::CollectionType::Sequence); |
57 handlers.writeNull(); |
103 handlers.writeNull(); |
58 handlers.writeBoolean(true); |
104 handlers.writeBoolean(true); |
59 handlers.writeInteger(typeAndLength[0]); |
105 |
60 handlers.writeInteger(typeAndLength[1]); |
106 handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "tagClass:"); |
|
107 handlers.writeInteger((int64_t) typeHeader.tagClass); |
|
108 handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "pc:"); |
|
109 handlers.writeInteger((int64_t) typeHeader.pc); |
|
110 handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "tag:"); |
|
111 handlers.writeInteger((int64_t) typeHeader.tag); |
|
112 handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "definiteLength:"); |
|
113 handlers.writeBoolean(typeHeader.definiteLength); |
|
114 handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "length:"); |
|
115 handlers.writeInteger((int64_t) typeHeader.length); |
|
116 |
61 handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "relational pipes"); |
117 handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "relational pipes"); |
62 handlers.writeCollectionEnd(); |
118 handlers.writeCollectionEnd(); |
63 |
|
64 if (state == State::A) { |
|
65 |
|
66 } else if (state == State::B) { |
|
67 |
|
68 } else if (state == State::C) { |
|
69 |
|
70 } |
|
71 } |
119 } |
72 |
120 |
73 protected: |
121 protected: |
74 |
122 |
75 void update() override { |
123 void update() override { |