src/lib/BasicASN1Reader.h
branchv_0
changeset 40 85b6f13f1088
parent 37 0845ca3636b6
equal deleted inserted replaced
39:6ef41443211e 40:85b6f13f1088
    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