Open woodruffw opened 4 years ago
Hi, regarding that. I have tinkered a bit with it already.
It seems straightforward to go from ASN1_TIME
to tm
with ASN1_TIME_to_tm(X509_get0_notBefore(cert)
(e.g. in the Certificate
ctor). According to the documentation the converted time in tm
is GMT (= UTC). Perfect.
Now what I am wondering is how you envision such an exposure of these points of data.
Exposing tm
directly via const reference would be doable, of course. But I find tm
always a bit unwieldy with its semantics of year-1900 ... and months and days start at 0 and so on. However, it would still be easier for a developer to go from tm
to something else, so perhaps that's an argument in favor of exposing it anyway.
Would it be acceptable to introduce a struct which contains year, month, day (of month), hour, minute and second? E.g.
typedef struct
{
unsigned int year;
unsigned int month;
unsigned int day;
unsigned int hour;
unsigned int minute;
unsigned int second;
} cert_timestamp;
And is std::optional
the right way to go for when this value doesn't exist? I know, formally it should always exist, but what to do if the OpenSSL call failed or if we have something signed with some awkward self-signed certificate?
I agree re: tm
being unwieldy.
A custom struct seems reasonable, but before we commit to that completely: is there something in std::chrono
we can reuse? chrono::time_point
seems like it's roughly appropriate, although I'm not sure if there's a convenient way to construct it in our case.
Either way: I think we should raise an exception in the constructor if these time fields don't exist. AFAICT x.509 requires them, so we should as well.
These are easy enough to extract with
X509_get0_notBefore
andX509_get0_notAfter
.Each returns an
ASN1_TIME *
, which can be dumped to a BIO usingASN1_TIME_print
.