src/lib/BasicASN1Reader.h
branchv_0
changeset 36 caed9146f72f
parent 35 bf2c546f49d1
child 37 0845ca3636b6
equal deleted inserted replaced
35:bf2c546f49d1 36:caed9146f72f
   110 		}
   110 		}
   111 
   111 
   112 		return h;
   112 		return h;
   113 	}
   113 	}
   114 
   114 
   115 	void readNext() {
   115 	const std::string readString(size_t length) {
       
   116 		std::string result;
       
   117 
       
   118 		for (size_t remaining = length; remaining;) {
       
   119 			size_t current = std::min(remaining, (size_t) 3);
       
   120 			result.resize(result.size() + current);
       
   121 			read((uint8_t*) result.data() + result.size() - current, current);
       
   122 			remaining -= current;
       
   123 		}
       
   124 
       
   125 		return result;
       
   126 	}
       
   127 
       
   128 	const std::vector<uint8_t> readVector(size_t length) {
       
   129 		std::vector<uint8_t> result;
       
   130 		std::string s = readString(length); // TODO: read directly to the vector
       
   131 		result.resize(length);
       
   132 		for (size_t i = 0; i < length; i++) result[i] = (uint8_t) s[i];
       
   133 		return result;
       
   134 	}
       
   135 
       
   136 	void processNext() {
   116 		using TagClass = ASN1ContentHandler::TagClass;
   137 		using TagClass = ASN1ContentHandler::TagClass;
   117 		using PC = ASN1ContentHandler::PC;
   138 		using PC = ASN1ContentHandler::PC;
   118 
   139 
   119 		checkRemainingItems();
   140 		checkRemainingItems();
   120 		BasicHeader typeHeader = readHeader();
   141 		BasicHeader typeHeader = readHeader();
   144 		} else if (typeHeader.tag == UniversalType::Boolean && typeHeader.definiteLength && typeHeader.length == 1) {
   165 		} else if (typeHeader.tag == UniversalType::Boolean && typeHeader.definiteLength && typeHeader.length == 1) {
   145 			bool value;
   166 			bool value;
   146 			read((uint8_t*) & value, 1);
   167 			read((uint8_t*) & value, 1);
   147 			handlers->writeBoolean(typeHeader, value);
   168 			handlers->writeBoolean(typeHeader, value);
   148 		} else if (typeHeader.tag == UniversalType::Integer && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   169 		} else if (typeHeader.tag == UniversalType::Integer && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   149 			// TODO: check available bytes before allocating buffer
   170 			std::vector<uint8_t> value = readVector(typeHeader.length);
   150 			std::vector<uint8_t> value(typeHeader.length, 0x00);
       
   151 			read(value.data(), typeHeader.length);
       
   152 			handlers->writeInteger(typeHeader, ASN1ContentHandler::Integer(value));
   171 			handlers->writeInteger(typeHeader, ASN1ContentHandler::Integer(value));
   153 		} else if (typeHeader.tag == UniversalType::ObjectIdentifier && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   172 		} else if (typeHeader.tag == UniversalType::ObjectIdentifier && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   154 			std::vector<uint8_t> value(typeHeader.length, 0x00);
   173 			std::vector<uint8_t> value(typeHeader.length, 0x00);
   155 			read(value.data(), typeHeader.length);
   174 			read(value.data(), typeHeader.length);
   156 			handlers->writeOID(typeHeader,{value});
   175 			handlers->writeOID(typeHeader,{value});
   157 		} else if (typeHeader.tag == UniversalType::UTF8String && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   176 		} else if (typeHeader.tag == UniversalType::UTF8String && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   158 			// TODO: check available bytes before allocating buffer
   177 			std::string s = readString(typeHeader.length);
   159 			std::string s;
       
   160 			s.resize(typeHeader.length);
       
   161 			read((uint8_t*) s.data(), typeHeader.length);
       
   162 			handlers->writeTextString(typeHeader, s);
   178 			handlers->writeTextString(typeHeader, s);
   163 		} else if (typeHeader.tag == UniversalType::PrintableString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   179 		} else if (typeHeader.tag == UniversalType::PrintableString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   164 			// TODO: check encoding
   180 			// TODO: check encoding
   165 			// TODO: check available bytes before allocating buffer
   181 			std::string s = readString(typeHeader.length);
   166 			std::string s;
       
   167 			s.resize(typeHeader.length);
       
   168 			read((uint8_t*) s.data(), typeHeader.length);
       
   169 			handlers->writeTextString(typeHeader, s);
   182 			handlers->writeTextString(typeHeader, s);
   170 		} else if (typeHeader.tag == UniversalType::OctetString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   183 		} else if (typeHeader.tag == UniversalType::OctetString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   171 			// TODO: check available bytes before allocating buffer
   184 			std::string s = readString(typeHeader.length);
   172 			std::string s;
       
   173 			s.resize(typeHeader.length);
       
   174 			read((uint8_t*) s.data(), typeHeader.length);
       
   175 			if (processEncapsulatedContent(typeHeader, s) == false) handlers->writeOctetString(typeHeader, s);
   185 			if (processEncapsulatedContent(typeHeader, s) == false) handlers->writeOctetString(typeHeader, s);
   176 		} else if (typeHeader.tag == UniversalType::BitString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   186 		} else if (typeHeader.tag == UniversalType::BitString && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   177 			// TODO: check available bytes before allocating buffer
   187 			std::string s = readString(typeHeader.length);
   178 			std::string s;
       
   179 			s.resize(typeHeader.length);
       
   180 			read((uint8_t*) s.data(), typeHeader.length);
       
   181 			if (processEncapsulatedContent(typeHeader, s) == false) {
   188 			if (processEncapsulatedContent(typeHeader, s) == false) {
   182 				std::vector<bool> bits;
   189 				std::vector<bool> bits;
   183 				// TODO: throw exception on wrong padding or insufficient length?
   190 				// TODO: throw exception on wrong padding or insufficient length?
   184 				if (s.size() > 1) {
   191 				if (s.size() > 1) {
   185 					uint8_t padding = s[0];
   192 					uint8_t padding = s[0];
   187 					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);
   194 					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);
   188 				}
   195 				}
   189 				handlers->writeBitString(typeHeader, bits);
   196 				handlers->writeBitString(typeHeader, bits);
   190 			}
   197 			}
   191 		} else if (typeHeader.tag == UniversalType::UTCTime && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   198 		} else if (typeHeader.tag == UniversalType::UTCTime && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   192 			// TODO: check available bytes before allocating buffer
       
   193 			// TODO: check encoding
   199 			// TODO: check encoding
   194 			std::string s;
   200 			std::string s = readString(typeHeader.length);
   195 			s.resize(typeHeader.length);
       
   196 			read((uint8_t*) s.data(), typeHeader.length);
       
   197 
   201 
   198 			ASN1ContentHandler::DateTime dateTime;
   202 			ASN1ContentHandler::DateTime dateTime;
   199 
   203 
   200 			std::smatch match;
   204 			std::smatch match;
   201 			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}))"))) {
   205 			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}))"))) {
   217 			} else {
   221 			} else {
   218 				throw std::invalid_argument("Unsupported UTCTime format: " + s); // TODO: better exception
   222 				throw std::invalid_argument("Unsupported UTCTime format: " + s); // TODO: better exception
   219 			}
   223 			}
   220 
   224 
   221 		} else if (typeHeader.tag == UniversalType::GeneralizedTime && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   225 		} else if (typeHeader.tag == UniversalType::GeneralizedTime && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
   222 			// TODO: check available bytes before allocating buffer
   226 			std::string s = readString(typeHeader.length);
   223 			std::string s;
       
   224 			s.resize(typeHeader.length);
       
   225 			read((uint8_t*) s.data(), typeHeader.length);
       
   226 
   227 
   227 			ASN1ContentHandler::DateTime dateTime;
   228 			ASN1ContentHandler::DateTime dateTime;
   228 
   229 
   229 			std::smatch match;
   230 			std::smatch match;
   230 			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}))"))) {
   231 			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}))"))) {
   250 				throw std::invalid_argument("Unsupported GeneralizedTime format: " + s); // TODO: better exception
   251 				throw std::invalid_argument("Unsupported GeneralizedTime format: " + s); // TODO: better exception
   251 			}
   252 			}
   252 
   253 
   253 		} else {
   254 		} else {
   254 			// TODO: do not skip, parse
   255 			// TODO: do not skip, parse
   255 			// TODO: check available bytes before allocating buffer
   256 			std::string s = readString(typeHeader.length);
   256 			std::string s;
       
   257 			s.resize(typeHeader.length);
       
   258 			read((uint8_t*) s.data(), typeHeader.length);
       
   259 			handlers->writeSpecific(typeHeader, s);
   257 			handlers->writeSpecific(typeHeader, s);
   260 		}
   258 		}
   261 
   259 
   262 		commit();
   260 		commit();
   263 	}
   261 	}
   325 	}
   323 	}
   326 
   324 
   327 protected:
   325 protected:
   328 
   326 
   329 	void update() override {
   327 	void update() override {
   330 		while (true) readNext();
   328 		while (true) processNext();
   331 	}
   329 	}
   332 
   330 
   333 public:
   331 public:
   334 
   332 
   335 	void close() override {
   333 	void close() override {