--- a/src/lib/ASN1ContentHandler.h Tue Jun 22 21:41:59 2021 +0200
+++ b/src/lib/ASN1ContentHandler.h Sat Jun 26 20:04:52 2021 +0200
@@ -18,6 +18,9 @@
#include <memory>
#include <vector>
+#include <sstream>
+#include <iomanip>
+#include <cmath>
namespace relpipe {
namespace in {
@@ -49,6 +52,62 @@
BMPString,
};
+ class Integer {
+ private:
+ std::vector<uint8_t> data;
+ public:
+
+ /**
+ * @param data integer octets as in BER encoding
+ */
+ Integer(std::vector<uint8_t> data) : data(data) {
+ }
+
+ virtual ~Integer() {
+ }
+
+ size_t size() const {
+ return data.size();
+ }
+
+ const uint8_t& operator[](std::size_t index) const {
+ return data[index];
+ }
+
+ const std::string toHex() const {
+ std::stringstream hex;
+ hex << std::hex << std::setfill('0');
+ for (uint8_t b : data) hex << std::setw(2) << (int) b;
+ return hex.str();
+ }
+
+ const std::string toString() const {
+ try {
+ return std::to_string(toInt64());
+ } catch (...) {
+ // TODO: support longer values than 64 bits
+ // integer has more than 64 bits → only HEX form value will be available
+ return "";
+ }
+ }
+
+ const int64_t toInt64() const {
+ int64_t value = 0;
+
+ if (data.size() > sizeof (value)) throw std::invalid_argument("integer is too long");
+
+ for (size_t i = 0, limit = data.size(), negative = 0; i < limit; i++) {
+ uint8_t b = data[i];
+ if (i == 0 && b & 0x80) negative = true;
+ value = (value << 8) | b;
+ if (i == (limit - 1) && negative) value -= std::pow(256, data.size());
+ }
+
+ return value;
+ }
+
+ };
+
virtual ~ASN1ContentHandler() = default;
virtual void writeStreamStart() = 0;
@@ -58,7 +117,7 @@
virtual void writeCollectionEnd() = 0;
virtual void writeBoolean(bool value) = 0;
virtual void writeNull() = 0;
- virtual void writeInteger(int64_t value) = 0;
+ virtual void writeInteger(Integer value) = 0;
virtual void writeString(StringType type, std::string value) = 0;
// virtual void writeOID(std::string value) = 0;
// Object descriptor
@@ -113,7 +172,7 @@
handler->writeNull();
}
- void writeInteger(int64_t value) override { // TODO: Integer class containing raw data + methods for converting them to particular numeric data types
+ void writeInteger(Integer value) override {
handler->writeInteger(value);
}
--- a/src/lib/BasicASN1Reader.h Tue Jun 22 21:41:59 2021 +0200
+++ b/src/lib/BasicASN1Reader.h Sat Jun 26 20:04:52 2021 +0200
@@ -145,13 +145,20 @@
bool value;
read((uint8_t*) & value, 1);
handlers.writeBoolean(value);
- } else if (typeHeader.tag == 12 && typeHeader.tagClass == TagClass::Universal) {
+ } else if (typeHeader.tag == 2 && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
+ // TODO: check available bytes before allocating buffer
+ std::vector<uint8_t> value(typeHeader.length, 0x00);
+ read(value.data(), typeHeader.length);
+ handlers.writeInteger(ASN1ContentHandler::Integer(value));
+ } else if (typeHeader.tag == 12 && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
+ // TODO: check available bytes before allocating buffer
std::string s;
s.resize(typeHeader.length);
read((uint8_t*) s.data(), typeHeader.length);
handlers.writeString(ASN1ContentHandler::StringType::UTF8String, s);
- } else if (typeHeader.tag == 19 && typeHeader.tagClass == TagClass::Universal) {
+ } else if (typeHeader.tag == 19 && typeHeader.tagClass == TagClass::Universal && typeHeader.definiteLength) {
// TODO: check encoding
+ // TODO: check available bytes before allocating buffer
std::string s;
s.resize(typeHeader.length);
read((uint8_t*) s.data(), typeHeader.length);
@@ -174,27 +181,6 @@
}
commit();
-
-
- // TODO: remove debug/demo output:
- return;
- handlers.writeCollectionStart(ASN1ContentHandler::CollectionType::Sequence);
- handlers.writeNull();
- handlers.writeBoolean(true);
-
- handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "tagClass:");
- handlers.writeInteger((int64_t) typeHeader.tagClass);
- handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "pc:");
- handlers.writeInteger((int64_t) typeHeader.pc);
- handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "tag:");
- handlers.writeInteger((int64_t) typeHeader.tag);
- handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "definiteLength:");
- handlers.writeBoolean(typeHeader.definiteLength);
- handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "length:");
- handlers.writeInteger((int64_t) typeHeader.length);
-
- handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "relational pipes");
- handlers.writeCollectionEnd();
}
protected:
--- a/src/lib/GenericASN1ContentHandler.h Tue Jun 22 21:41:59 2021 +0200
+++ b/src/lib/GenericASN1ContentHandler.h Sat Jun 26 20:04:52 2021 +0200
@@ -71,9 +71,9 @@
handlers.writeEndElement();
}
- void writeInteger(int64_t value) override {
- handlers.writeStartElement("integer");
- handlers.writeCharacters(std::to_string(value));
+ void writeInteger(Integer value) override {
+ handlers.writeStartElement("integer",{"hex", value.toHex()});
+ handlers.writeCharacters(value.toString());
handlers.writeEndElement();
}