--- a/src/lib/ASN1ContentHandler.h Sun Jun 27 19:22:23 2021 +0200
+++ b/src/lib/ASN1ContentHandler.h Mon Jun 28 22:48:04 2021 +0200
@@ -52,6 +52,17 @@
BMPString,
};
+ enum class DateTimeType : uint64_t {
+ UTCTime,
+ GeneralizedTime,
+ Time,
+ Date,
+ TimeOfDay,
+ DateTime,
+ Duration,
+ // TODO: review date/time types
+ };
+
class Integer {
private:
// TODO: use std::string (of octets, not ASCII) instead of std::vector?
@@ -167,9 +178,52 @@
};
+ class DateTime {
+ public:
+
+ enum class Precision {
+ Year,
+ Month,
+ Day,
+ Hour,
+ Minute,
+ Second,
+ Milisecond,
+ Nanosecond
+ };
+
+ // TODO: timezone (in minutes or 1/4 hours)
+
+ Precision precision = Precision::Second;
+ int32_t year = 1970;
+ int8_t month = 1;
+ int8_t day = 1;
+ int8_t hour = 0;
+ int8_t minute = 0;
+ int8_t second = 0;
+ // TODO: ms/ns
+
+ virtual ~DateTime() {
+ }
+
+ const std::string toString() const {
+ std::stringstream result;
+ result << std::setfill('0');
+ result << std::setw(4) << (int) year;
+ result << "-" << std::setw(2) << (int) month;
+ result << "-" << std::setw(2) << (int) day;
+ result << "T" << std::setw(2) << (int) hour;
+ result << ":" << std::setw(2) << (int) minute;
+ result << ":" << std::setw(2) << (int) second;
+ result << "+00:00"; // TODO: timezone
+ return result.str();
+ }
+ };
+
virtual ~ASN1ContentHandler() = default;
// TODO: more metadata, support OID decoding and ASN.1 modules (schema), probably through a plug-in
+ // TODO: support also extension extractor plug-ins? (could decode some opaque structures like octet strings and replace them with nested elements) e.g. subjectAltName in https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.6
virtual void writeStreamStart() = 0;
virtual void writeStreamEnd() = 0;
@@ -181,18 +235,12 @@
virtual void writeInteger(Integer value) = 0;
virtual void writeString(StringType type, std::string value) = 0;
virtual void writeOID(ObjectIdentifier value) = 0;
+ virtual void writeDateTime(DateTimeType type, DateTime value) = 0;
// Object descriptor
// virtual void writeReal(float value) = 0;
// Enumerated
// Embedded PVD
// Relative OID
- // TIME
- // UTC time
- // Generalized time
- // Date
- // Time of day
- // Date-time
- // Duration
// OID-IRI
// Relative OID-IRI
@@ -245,6 +293,9 @@
handler->writeOID(value);
}
+ void writeDateTime(DateTimeType type, DateTime value) override {
+ handler->writeDateTime(type, value);
+ }
#undef handler
--- a/src/lib/BasicASN1Reader.h Sun Jun 27 19:22:23 2021 +0200
+++ b/src/lib/BasicASN1Reader.h Mon Jun 28 22:48:04 2021 +0200
@@ -20,6 +20,7 @@
#include <vector>
#include <array>
#include <sstream>
+#include <regex>
#include "ASN1Reader.h"
@@ -174,6 +175,36 @@
s.resize(typeHeader.length);
read((uint8_t*) s.data(), typeHeader.length);
handlers.writeString(ASN1ContentHandler::StringType::PrintableString, s);
+ } else if (typeHeader.tag == 0x17 && 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);
+
+ ASN1ContentHandler::DateTime dateTime;
+
+ std::smatch match;
+ 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"))) {
+ int i = 1;
+ uint32_t year = std::stoi(match[i++]);
+ dateTime.year = year < 50 ? 2000 + year : 1900 + year;
+ dateTime.month = std::stoi(match[i++]);
+ dateTime.day = std::stoi(match[i++]);
+ dateTime.hour = std::stoi(match[i++]);
+ dateTime.minute = std::stoi(match[i++]);
+ dateTime.precision = ASN1ContentHandler::DateTime::Precision::Second;
+ handlers.writeDateTime(ASN1ContentHandler::DateTimeType::UTCTime, dateTime);
+ } else {
+ // FIXME: decode more UTCTime formats:
+ // YYMMDDhhmmZ
+ // YYMMDDhhmm+hh'mm'
+ // YYMMDDhhmm-hh'mm'
+ // YYMMDDhhmmssZ
+ // YYMMDDhhmmss+hh'mm'
+ // YYMMDDhhmmss-hh'mm'
+ handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "FIXME: UTCTime format not yet supported: " + s);
+ }
+
} else {
// TODO: do not skip, parse
std::vector<uint8_t> temp(typeHeader.length, 0);
--- a/src/lib/GenericASN1ContentHandler.h Sun Jun 27 19:22:23 2021 +0200
+++ b/src/lib/GenericASN1ContentHandler.h Mon Jun 28 22:48:04 2021 +0200
@@ -89,6 +89,11 @@
handlers.writeEndElement();
}
+ void writeDateTime(DateTimeType type, DateTime value) override {
+ handlers.writeStartElement("date-time");
+ handlers.writeCharacters(value.toString());
+ handlers.writeEndElement();
+ }
};