@@ -28292,15 +28292,32 @@ static WC_INLINE byte itob(int number)
2829228292}
2829328293
2829428294
28295- /* write time to output, format */
28296- static void SetTime(struct tm* date, byte* output)
28295+ /* RFC 5280: validity dates through 2049 encode as UTCTime, 2050 and later as
28296+ * GeneralizedTime. date->tm_year holds the full year here. */
28297+ static byte ValidityTimeFormat(const struct tm* date)
28298+ {
28299+ if (date->tm_year >= 1950 && date->tm_year < 2050)
28300+ return ASN_UTC_TIME;
28301+ return ASN_GENERALIZED_TIME;
28302+ }
28303+
28304+ /* write time value to output in the given ASN.1 format */
28305+ static void SetTime(struct tm* date, byte* output, byte format)
2829728306{
2829828307 int i = 0;
28308+ int year = date->tm_year;
2829928309
28300- output[i++] = itob((date->tm_year % 10000) / 1000);
28301- output[i++] = itob((date->tm_year % 1000) / 100);
28302- output[i++] = itob((date->tm_year % 100) / 10);
28303- output[i++] = itob( date->tm_year % 10);
28310+ if (format == ASN_UTC_TIME) {
28311+ year %= 100;
28312+ output[i++] = itob((year / 10) % 10);
28313+ output[i++] = itob( year % 10);
28314+ }
28315+ else {
28316+ output[i++] = itob((year % 10000) / 1000);
28317+ output[i++] = itob((year % 1000) / 100);
28318+ output[i++] = itob((year % 100) / 10);
28319+ output[i++] = itob( year % 10);
28320+ }
2830428321
2830528322 output[i++] = itob(date->tm_mon / 10);
2830628323 output[i++] = itob(date->tm_mon % 10);
@@ -30063,6 +30080,8 @@ static int SetValidity(byte* before, byte* after, int daysValid)
3006330080{
3006430081#ifndef NO_ASN_TIME
3006530082 int ret = 0;
30083+ byte format;
30084+ word32 timeSz;
3006630085 time_t now;
3006730086 time_t then;
3006830087 struct tm* tmpTime;
@@ -30093,7 +30112,12 @@ static int SetValidity(byte* before, byte* after, int daysValid)
3009330112 localTime.tm_year += 1900;
3009430113 localTime.tm_mon += 1;
3009530114
30096- SetTime(&localTime, before);
30115+ format = ValidityTimeFormat(&localTime);
30116+ timeSz = (format == ASN_UTC_TIME) ? ASN_UTC_TIME_SIZE - 1
30117+ : ASN_GEN_TIME_SZ;
30118+ before[0] = format;
30119+ SetLength(timeSz, before + 1);
30120+ SetTime(&localTime, before + 2, format);
3009730121
3009830122 /* add daysValid of seconds */
3009930123 then = now + (daysValid * (time_t)86400);
@@ -30110,7 +30134,12 @@ static int SetValidity(byte* before, byte* after, int daysValid)
3011030134 localTime.tm_year += 1900;
3011130135 localTime.tm_mon += 1;
3011230136
30113- SetTime(&localTime, after);
30137+ format = ValidityTimeFormat(&localTime);
30138+ timeSz = (format == ASN_UTC_TIME) ? ASN_UTC_TIME_SIZE - 1
30139+ : ASN_GEN_TIME_SZ;
30140+ after[0] = format;
30141+ SetLength(timeSz, after + 1);
30142+ SetTime(&localTime, after + 2, format);
3011430143 }
3011530144
3011630145 return ret;
@@ -30803,6 +30832,8 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
3080330832 int ret = 0;
3080430833 word32 issRawLen = 0;
3080530834 word32 sbjRawLen = 0;
30835+ byte localBefore[MAX_DATE_SIZE];
30836+ byte localAfter[MAX_DATE_SIZE];
3080630837
3080730838 /* Unused without PQC */
3080830839 (void)falconKey;
@@ -31028,16 +31059,35 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
3102831059 }
3102931060 else
3103031061 {
31031- /* Don't put out UTC before data. */
31032- dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].noOut = 1;
31033- /* Make space for before date data. */
31034- SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT],
31035- NULL, ASN_GEN_TIME_SZ);
31036- /* Don't put out UTC after data. */
31037- dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].noOut = 1;
31038- /* Make space for after date data. */
31039- SetASN_Buffer(&dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT],
31040- NULL, ASN_GEN_TIME_SZ);
31062+ /* Compute default validity dates; SetValidity picks UTCTime or
31063+ * Generalized Time per RFC 5280 based on the year. */
31064+ ret = SetValidity(localBefore, localAfter, cert->daysValid);
31065+ if (ret == 0) {
31066+ if (localBefore[0] == ASN_UTC_TIME) {
31067+ SetASN_Buffer(
31068+ &dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC],
31069+ localBefore + 2, ASN_UTC_TIME_SIZE - 1);
31070+ dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT].noOut = 1;
31071+ }
31072+ else {
31073+ dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_UTC].noOut = 1;
31074+ SetASN_Buffer(
31075+ &dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT],
31076+ localBefore + 2, ASN_GEN_TIME_SZ);
31077+ }
31078+ if (localAfter[0] == ASN_UTC_TIME) {
31079+ SetASN_Buffer(
31080+ &dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC],
31081+ localAfter + 2, ASN_UTC_TIME_SIZE - 1);
31082+ dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT].noOut = 1;
31083+ }
31084+ else {
31085+ dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_UTC].noOut = 1;
31086+ SetASN_Buffer(
31087+ &dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT],
31088+ localAfter + 2, ASN_GEN_TIME_SZ);
31089+ }
31090+ }
3104131091 }
3104231092 if (sbjRawLen > 0) {
3104331093 /* Put in encoded subject name. */
@@ -31075,7 +31125,9 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
3107531125 X509CERTASN_IDX_SIGNATURE);
3107631126
3107731127 /* Calculate encoded certificate body size. */
31078- ret = SizeASN_Items(x509CertASN, dataASN, x509CertASN_Length, &sz);
31128+ if (ret >= 0) {
31129+ ret = SizeASN_Items(x509CertASN, dataASN, x509CertASN_Length, &sz);
31130+ }
3107931131 }
3108031132 /* Check buffer is big enough for encoded data. */
3108131133 if ((ret == 0) && (sz > derSz)) {
@@ -31106,18 +31158,6 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz,
3110631158 dataASN[X509CERTASN_IDX_TBS_SUBJECT_SEQ].data.buffer.length,
3110731159 &cert->subject, cert->heap);
3110831160 }
31109- if (ret >= 0) {
31110- if (cert->beforeDateSz == 0 || cert->afterDateSz == 0)
31111- {
31112- /* Encode validity into buffer. */
31113- /* safe casts -- the pointers are actually inside derBuffer. */
31114- ret = SetValidity(
31115- (byte*)(wc_ptr_t)dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTB_GT]
31116- .data.buffer.data,
31117- (byte*)(wc_ptr_t)dataASN[X509CERTASN_IDX_TBS_VALIDITY_NOTA_GT]
31118- .data.buffer.data, cert->daysValid);
31119- }
31120- }
3112131161 if (ret >= 0) {
3112231162 /* Encode public key into buffer. */
3112331163 /* safe cast -- the pointer is actually inside derBuffer. */
0 commit comments