equal
deleted
inserted
replaced
22 #include <sstream> |
22 #include <sstream> |
23 #include <regex> |
23 #include <regex> |
24 |
24 |
25 #include "ASN1Reader.h" |
25 #include "ASN1Reader.h" |
26 #include "ValidatingASN1ContentHandler.h" |
26 #include "ValidatingASN1ContentHandler.h" |
|
27 #include "uri.h" |
27 |
28 |
28 namespace relpipe { |
29 namespace relpipe { |
29 namespace in { |
30 namespace in { |
30 namespace asn1 { |
31 namespace asn1 { |
31 namespace lib { |
32 namespace lib { |
35 */ |
36 */ |
36 class BasicASN1Reader : public ASN1Reader { |
37 class BasicASN1Reader : public ASN1Reader { |
37 private: |
38 private: |
38 |
39 |
39 bool started = false; |
40 bool started = false; |
|
41 |
|
42 bool parseEncapsulated = true; |
|
43 |
|
44 /** |
|
45 * TODO: use a common method |
|
46 */ |
|
47 bool parseBoolean(const std::string& value) { |
|
48 if (value == "true") return true; |
|
49 else if (value == "false") return false; |
|
50 else throw std::invalid_argument(std::string("Unable to parse boolean value: ") + value + " (expecting true or false)"); |
|
51 } |
40 |
52 |
41 class BasicHeader : public ASN1ContentHandler::Header { |
53 class BasicHeader : public ASN1ContentHandler::Header { |
42 public: |
54 public: |
43 bool definiteLength; |
55 bool definiteLength; |
44 size_t length; |
56 size_t length; |
303 * @return whether we found valid content and passed parsed results to handlers |
315 * @return whether we found valid content and passed parsed results to handlers |
304 */ |
316 */ |
305 bool processEncapsulatedContent(const BasicHeader& typeHeader, const std::string& input) { |
317 bool processEncapsulatedContent(const BasicHeader& typeHeader, const std::string& input) { |
306 // 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) |
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) |
307 // 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. |
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. |
308 if (isValidBER(input)) { |
320 if (parseEncapsulated && isValidBER(input)) { |
309 handlers->writeCollectionStart(typeHeader); |
321 handlers->writeCollectionStart(typeHeader); |
310 |
322 |
311 BasicASN1Reader encapsulatedReader; |
323 BasicASN1Reader encapsulatedReader; |
312 std::shared_ptr<EncapsulatedASN1ContentHandler> encapsulatedHandler = std::make_shared<EncapsulatedASN1ContentHandler>(); |
324 std::shared_ptr<EncapsulatedASN1ContentHandler> encapsulatedHandler = std::make_shared<EncapsulatedASN1ContentHandler>(); |
313 encapsulatedHandler->addHandler(handlers); |
325 encapsulatedHandler->addHandler(handlers); |
329 while (true) processNext(); |
341 while (true) processNext(); |
330 } |
342 } |
331 |
343 |
332 public: |
344 public: |
333 |
345 |
|
346 bool setOption(const std::string& uri, const std::string& value) override { |
|
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 |
|
348 else if (uri == option::Encoding && value == encoding::cer); // in future versions, this might switch the parser into more strict mode |
|
349 else if (uri == option::Encoding && value == encoding::der); // in future versions, this might switch the parser into more strict mode |
|
350 else if (uri == option::Encoding && value == encoding::per) throw std::invalid_argument("PER encoding is not yet supported"); |
|
351 else if (uri == option::Encoding && value == encoding::xer) throw std::invalid_argument("XER encoding is not yet supported"); |
|
352 else if (uri == option::Encoding && value == encoding::asn1) throw std::invalid_argument("ASN.1 encoding is not yet supported"); |
|
353 else if (uri == option::Encoding) throw std::invalid_argument("Unsupported ASN.1 encoding: " + value); |
|
354 else if (uri == option::ParseEncapsulated) parseEncapsulated = parseBoolean(value); |
|
355 else return false; |
|
356 |
|
357 return true; |
|
358 } |
|
359 |
334 void close() override { |
360 void close() override { |
335 if (hasAvailableForReading()) throw std::logic_error("Unexpected content at the end of the stream"); // TODO: better exception |
361 if (hasAvailableForReading()) throw std::logic_error("Unexpected content at the end of the stream"); // TODO: better exception |
336 |
362 |
337 // TODO: check also open sequences etc.; maybe in the handler |
363 // TODO: check also open sequences etc.; maybe in the handler |
338 |
364 |