#include "util-decode-der-get.h"
static const uint8_t SEQ_IDX_ISSUER[] = { 0, 2 };
+static const uint8_t SEQ_IDX_VALIDITY[] = { 0, 3 };
static const uint8_t SEQ_IDX_SUBJECT[] = { 0, 4 };
static const char *Oid2ShortStr(const char *oid)
return "unknown";
}
+static time_t GentimeToTime(char *gentime)
+{
+ time_t time;
+ struct tm tm;
+
+ /* GeneralizedTime values MUST be expressed in Greenwich Mean Time
+ * (Zulu) and MUST include seconds (rfc5280 4.1.2.5.2). It MUST NOT
+ * include fractional seconds. It should therefore be on the format
+ * YYYYmmddHHMMSSZ. */
+ if (strlen(gentime) != 15)
+ goto error;
+
+ tm.tm_gmtoff = 0;
+ strptime(gentime, "%Y%m%d%H%M%SZ", &tm);
+ time = SCMkTimeUtc(&tm);
+
+ if (time < 0)
+ goto error;
+
+ return time;
+
+error:
+ return -1;
+}
+
+static time_t UtctimeToTime(char *utctime)
+{
+ time_t time;
+ unsigned int year;
+ char yy[2];
+ char buf[20];
+
+ /* UTCTime values MUST be expressed in Greenwich Mean Time (Zulu)
+ * and MUST include seconds (rfc5280 4.1.2.5.1). It should
+ * therefore be on the format YYmmddHHMMSSZ. */
+ if (strlen(utctime) != 13)
+ goto error;
+
+ /* UTCTime use two digits to represent the year. The year field (YY)
+ * should be interpreted as 19YY when it is greater than or equal to
+ * 50. If it is less than 50 it should be interpreted as 20YY.
+ * Because of this, GeneralizedTime must be used for dates in the
+ * year 2050 or later. */
+ strlcpy(yy, utctime, sizeof(yy));
+ year = strtol(yy, NULL, 10);
+ if (year >= 50)
+ snprintf(buf, sizeof(buf), "%i%s", 19, utctime);
+ else if (year < 50)
+ snprintf(buf, sizeof(buf), "%i%s", 20, utctime);
+ else
+ goto error;
+
+ time = GentimeToTime(buf);
+ if (time == -1)
+ goto error;
+
+ return time;
+
+error:
+ return -1;
+}
+
/**
* \brief Iterate through an ASN.1 structure, following the index sequence.
* Context specific elements are skipped.
return node;
}
+int Asn1DerGetValidity(const Asn1Generic *cert, time_t *not_before,
+ time_t *not_after, uint32_t *errcode)
+{
+ const Asn1Generic *node, *it;
+ int rc = -1;
+
+ if (errcode)
+ *errcode = ERR_DER_MISSING_ELEMENT;
+
+ node = Asn1DerGet(cert, SEQ_IDX_VALIDITY, sizeof(SEQ_IDX_VALIDITY), errcode);
+ if ((node == NULL) || node->type != ASN1_SEQUENCE)
+ goto validity_error;
+
+ it = node->data;
+ if (it == NULL || it->str == NULL)
+ goto validity_error;
+
+ if (it->type == ASN1_UTCTIME)
+ *not_before = UtctimeToTime(it->str);
+ else if (it->type == ASN1_GENERALIZEDTIME)
+ *not_before = GentimeToTime(it->str);
+ else
+ goto validity_error;
+
+ if (*not_before == -1)
+ goto validity_error;
+
+ if (node->next == NULL)
+ goto validity_error;
+
+ it = node->next->data;
+
+ if (it == NULL || it->str == NULL)
+ goto validity_error;
+
+ if (it->type == ASN1_UTCTIME)
+ *not_after = UtctimeToTime(it->str);
+ else if (it->type == ASN1_GENERALIZEDTIME)
+ *not_after = GentimeToTime(it->str);
+ else
+ goto validity_error;
+
+ if (*not_after == -1)
+ goto validity_error;
+
+ rc = 0;
+
+validity_error:
+ return rc;
+}
+
int Asn1DerGetIssuerDN(const Asn1Generic *cert, char *buffer, uint32_t length,
uint32_t *errcode)
{