diff options
-rw-r--r-- | security/nss/lib/certdb/certdb.c | 17 | ||||
-rw-r--r-- | security/nss/lib/certdb/certt.h | 2 | ||||
-rw-r--r-- | security/nss/lib/certdb/crl.c | 30 | ||||
-rw-r--r-- | security/nss/lib/certhigh/certhtml.c | 4 | ||||
-rw-r--r-- | security/nss/lib/certhigh/certvfy.c | 2 | ||||
-rw-r--r-- | security/nss/lib/nss/nss.def | 3 | ||||
-rw-r--r-- | security/nss/lib/softoken/lowcert.c | 61 | ||||
-rw-r--r-- | security/nss/lib/util/dertime.c | 34 | ||||
-rw-r--r-- | security/nss/lib/util/seccomon.h | 4 | ||||
-rw-r--r-- | security/nss/lib/util/secder.h | 25 | ||||
-rw-r--r-- | security/nss/lib/util/sectime.c | 110 | ||||
-rwxr-xr-x | security/nss/tests/cert/cert.sh | 4 |
12 files changed, 230 insertions, 66 deletions
diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c index 8dee87107..06fe67499 100644 --- a/security/nss/lib/certdb/certdb.c +++ b/security/nss/lib/certdb/certdb.c @@ -955,16 +955,21 @@ CERT_SetSlopTime(PRInt32 slop) /* seconds */ SECStatus CERT_GetCertTimes(CERTCertificate *c, PRTime *notBefore, PRTime *notAfter) { - int rv; + SECStatus rv; + + if (!c || !notBefore || !notAfter) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } /* convert DER not-before time */ - rv = DER_UTCTimeToTime(notBefore, &c->validity.notBefore); + rv = CERT_DecodeTimeChoice(notBefore, &c->validity.notBefore); if (rv) { return(SECFailure); } /* convert DER not-after time */ - rv = DER_UTCTimeToTime(notAfter, &c->validity.notAfter); + rv = CERT_DecodeTimeChoice(notAfter, &c->validity.notAfter); if (rv) { return(SECFailure); } @@ -1015,14 +1020,14 @@ SEC_GetCrlTimes(CERTCrl *date, PRTime *notBefore, PRTime *notAfter) int rv; /* convert DER not-before time */ - rv = DER_UTCTimeToTime(notBefore, &date->lastUpdate); + rv = CERT_DecodeTimeChoice(notBefore, &date->lastUpdate); if (rv) { return(SECFailure); } /* convert DER not-after time */ if (date->nextUpdate.data) { - rv = DER_UTCTimeToTime(notAfter, &date->nextUpdate); + rv = CERT_DecodeTimeChoice(notAfter, &date->nextUpdate); if (rv) { return(SECFailure); } @@ -1924,7 +1929,7 @@ CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb) return(PR_FALSE); } - /* get current UTC time */ + /* get current time */ now = PR_Now(); if ( newerbefore ) { diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h index f6b8f74bc..e502bfdda 100644 --- a/security/nss/lib/certdb/certt.h +++ b/security/nss/lib/certdb/certt.h @@ -818,6 +818,7 @@ extern const SEC_ASN1Template CERT_CertExtensionTemplate[]; extern const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate[]; extern const SEC_ASN1Template SECKEY_PublicKeyTemplate[]; extern const SEC_ASN1Template CERT_SubjectPublicKeyInfoTemplate[]; +extern const SEC_ASN1Template CERT_TimeChoiceTemplate[]; extern const SEC_ASN1Template CERT_ValidityTemplate[]; extern const SEC_ASN1Template CERT_PublicKeyAndChallengeTemplate[]; extern const SEC_ASN1Template SEC_CertSequenceTemplate[]; @@ -847,6 +848,7 @@ SEC_ASN1_CHOOSER_DECLARE(CERT_SetOfSignedCrlTemplate) SEC_ASN1_CHOOSER_DECLARE(CERT_SignedDataTemplate) SEC_ASN1_CHOOSER_DECLARE(CERT_SubjectPublicKeyInfoTemplate) SEC_ASN1_CHOOSER_DECLARE(SEC_SignedCertificateTemplate) +SEC_ASN1_CHOOSER_DECLARE(CERT_TimeChoiceTemplate) SEC_END_PROTOS diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c index f5cf422f1..cf5796fe3 100644 --- a/security/nss/lib/certdb/crl.c +++ b/security/nss/lib/certdb/crl.c @@ -151,8 +151,8 @@ static const SEC_ASN1Template cert_CrlEntryTemplate[] = { 0, NULL, sizeof(CERTCrlEntry) }, { SEC_ASN1_INTEGER, offsetof(CERTCrlEntry,serialNumber) }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrlEntry,revocationDate) }, + { SEC_ASN1_INLINE, + offsetof(CERTCrlEntry,revocationDate), CERT_TimeChoiceTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, offsetof(CERTCrlEntry, extensions), SEC_CERTExtensionTemplate}, @@ -171,10 +171,10 @@ const SEC_ASN1Template CERT_CrlTemplate[] = { { SEC_ASN1_INLINE, offsetof(CERTCrl,name), CERT_NameTemplate }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,lastUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,nextUpdate) }, + { SEC_ASN1_INLINE, + offsetof(CERTCrl,lastUpdate), CERT_TimeChoiceTemplate }, + { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, + offsetof(CERTCrl,nextUpdate), CERT_TimeChoiceTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, offsetof(CERTCrl,entries), cert_CrlEntryTemplate }, @@ -197,10 +197,10 @@ const SEC_ASN1Template CERT_CrlTemplateNoEntries[] = { { SEC_ASN1_INLINE, offsetof(CERTCrl,name), CERT_NameTemplate }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,lastUpdate) }, - { SEC_ASN1_OPTIONAL | SEC_ASN1_UTC_TIME, - offsetof(CERTCrl,nextUpdate) }, + { SEC_ASN1_INLINE, + offsetof(CERTCrl,lastUpdate), CERT_TimeChoiceTemplate }, + { SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, + offsetof(CERTCrl,nextUpdate), CERT_TimeChoiceTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF | SEC_ASN1_SKIP }, /* skip entries */ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | @@ -216,8 +216,10 @@ const SEC_ASN1Template CERT_CrlTemplateEntriesOnly[] = { { SEC_ASN1_SKIP | SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL }, { SEC_ASN1_SKIP }, { SEC_ASN1_SKIP }, - { SEC_ASN1_SKIP | SEC_ASN1_UTC_TIME }, - { SEC_ASN1_SKIP | SEC_ASN1_OPTIONAL | SEC_ASN1_UTC_TIME }, + { SEC_ASN1_SKIP | SEC_ASN1_INLINE, + offsetof(CERTCrl,lastUpdate), CERT_TimeChoiceTemplate }, + { SEC_ASN1_SKIP | SEC_ASN1_INLINE | SEC_ASN1_OPTIONAL, + offsetof(CERTCrl,nextUpdate), CERT_TimeChoiceTemplate }, { SEC_ASN1_OPTIONAL | SEC_ASN1_SEQUENCE_OF, offsetof(CERTCrl,entries), cert_CrlEntryTemplate }, /* decode entries */ @@ -1873,8 +1875,8 @@ CERT_CheckCRL(CERTCertificate* cert, CERTCertificate* issuer, SECItem* dp, /* check the time if we have one */ if (entry->revocationDate.data && entry->revocationDate.len) { int64 revocationDate = 0; - if (SECSuccess == DER_UTCTimeToTime(&revocationDate, - &entry->revocationDate)) { + if (SECSuccess == CERT_DecodeTimeChoice(&revocationDate, + &entry->revocationDate)) { /* we got a good revocation date, only consider the certificate revoked if the time we are inquiring about is past the revocation date */ diff --git a/security/nss/lib/certhigh/certhtml.c b/security/nss/lib/certhigh/certhtml.c index ff5f3c82d..e4e1215c2 100644 --- a/security/nss/lib/certhigh/certhtml.c +++ b/security/nss/lib/certhigh/certhtml.c @@ -422,8 +422,8 @@ CERT_HTMLCertInfo(CERTCertificate *cert, PRBool showImages, PRBool showIssuer) subject = CERT_FormatName (&cert->subject); version = CERT_Hexify (&cert->version,1); serialNumber = CERT_Hexify (&cert->serialNumber,1); - notBefore = DER_UTCDayToAscii(&cert->validity.notBefore); - notAfter = DER_UTCDayToAscii(&cert->validity.notAfter); + notBefore = DER_TimeChoiceDayToAscii(&cert->validity.notBefore); + notAfter = DER_TimeChoiceDayToAscii(&cert->validity.notAfter); servername = CERT_FindNSStringExtension(cert, SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME); diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c index f267564fa..fd7d8c744 100644 --- a/security/nss/lib/certhigh/certvfy.c +++ b/security/nss/lib/certhigh/certvfy.c @@ -70,7 +70,7 @@ CERT_CertTimesValid(CERTCertificate *c) return(SECSuccess); } - /* get current UTC time */ + /* get current time */ now = PR_Now(); rv = CERT_GetCertTimes(c, ¬Before, ¬After); diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def index f144342b9..ff2a5053d 100644 --- a/security/nss/lib/nss/nss.def +++ b/security/nss/lib/nss/nss.def @@ -758,6 +758,9 @@ SECKEY_PublicKeyStrengthInBits; ;+}; ;+NSS_3.9 { # NSS 3.9 release ;+ global: +CERT_DecodeTimeChoice; +CERT_EncodeTimeChoice; +NSS_Get_CERT_TimeChoiceTemplate; PK11_FindSlotsByAliases; SEC_DupCrl; ;+ local: diff --git a/security/nss/lib/softoken/lowcert.c b/security/nss/lib/softoken/lowcert.c index 2a55538e7..c509012dc 100644 --- a/security/nss/lib/softoken/lowcert.c +++ b/security/nss/lib/softoken/lowcert.c @@ -129,12 +129,17 @@ nsslowcert_GetDefaultCertDB(void) */ static unsigned char * nsslowcert_dataStart(unsigned char *buf, unsigned int length, - unsigned int *data_length, PRBool includeTag) { + unsigned int *data_length, PRBool includeTag, + unsigned char* rettag) { unsigned char tag; unsigned int used_length= 0; tag = buf[used_length++]; + if (rettag) { + *rettag = tag; + } + /* blow out when we come to the end */ if (tag == 0) { return NULL; @@ -161,18 +166,38 @@ nsslowcert_dataStart(unsigned char *buf, unsigned int length, return (buf + (includeTag ? 0 : used_length)); } +static void SetTimeType(SECItem* item, unsigned char tagtype) +{ + switch (tagtype) { + case SEC_ASN1_UTC_TIME: + item->type = siUTCTime; + break; + + case SEC_ASN1_GENERALIZED_TIME: + item->type = siGeneralizedTime; + break; + + default: + PORT_Assert(0); + break; + } +} + static int nsslowcert_GetValidityFields(unsigned char *buf,int buf_length, SECItem *notBefore, SECItem *notAfter) { + unsigned char tagtype; notBefore->data = nsslowcert_dataStart(buf,buf_length, - ¬Before->len,PR_FALSE); + ¬Before->len,PR_FALSE, &tagtype); if (notBefore->data == NULL) return SECFailure; + SetTimeType(notBefore, tagtype); buf_length -= (notBefore->data-buf) + notBefore->len; buf = notBefore->data + notBefore->len; notAfter->data = nsslowcert_dataStart(buf,buf_length, - ¬After->len,PR_FALSE); + ¬After->len,PR_FALSE, &tagtype); if (notAfter->data == NULL) return SECFailure; + SetTimeType(notAfter, tagtype); return SECSuccess; } @@ -187,33 +212,33 @@ nsslowcert_GetCertFields(unsigned char *cert,int cert_length, unsigned int dummylen; /* get past the signature wrap */ - buf = nsslowcert_dataStart(cert,cert_length,&buf_length,PR_FALSE); + buf = nsslowcert_dataStart(cert,cert_length,&buf_length,PR_FALSE, NULL); if (buf == NULL) return SECFailure; /* get into the raw cert data */ - buf = nsslowcert_dataStart(buf,buf_length,&buf_length,PR_FALSE); + buf = nsslowcert_dataStart(buf,buf_length,&buf_length,PR_FALSE, NULL); if (buf == NULL) return SECFailure; /* skip past any optional version number */ if ((buf[0] & 0xa0) == 0xa0) { - dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE); + dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE, NULL); if (dummy == NULL) return SECFailure; buf_length -= (dummy-buf) + dummylen; buf = dummy + dummylen; } /* serial number */ if (derSN) { - derSN->data=nsslowcert_dataStart(buf,buf_length,&derSN->len,PR_TRUE); + derSN->data=nsslowcert_dataStart(buf,buf_length,&derSN->len,PR_TRUE, NULL); } - serial->data = nsslowcert_dataStart(buf,buf_length,&serial->len,PR_FALSE); + serial->data = nsslowcert_dataStart(buf,buf_length,&serial->len,PR_FALSE, NULL); if (serial->data == NULL) return SECFailure; buf_length -= (serial->data-buf) + serial->len; buf = serial->data + serial->len; /* skip the OID */ - dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE); + dummy = nsslowcert_dataStart(buf,buf_length,&dummylen,PR_FALSE, NULL); if (dummy == NULL) return SECFailure; buf_length -= (dummy-buf) + dummylen; buf = dummy + dummylen; /* issuer */ - issuer->data = nsslowcert_dataStart(buf,buf_length,&issuer->len,PR_TRUE); + issuer->data = nsslowcert_dataStart(buf,buf_length,&issuer->len,PR_TRUE, NULL); if (issuer->data == NULL) return SECFailure; buf_length -= (issuer->data-buf) + issuer->len; buf = issuer->data + issuer->len; @@ -223,17 +248,17 @@ nsslowcert_GetCertFields(unsigned char *cert,int cert_length, return SECSuccess; } /* validity */ - valid->data = nsslowcert_dataStart(buf,buf_length,&valid->len,PR_FALSE); + valid->data = nsslowcert_dataStart(buf,buf_length,&valid->len,PR_FALSE, NULL); if (valid->data == NULL) return SECFailure; buf_length -= (valid->data-buf) + valid->len; buf = valid->data + valid->len; /*subject */ - subject->data=nsslowcert_dataStart(buf,buf_length,&subject->len,PR_TRUE); + subject->data=nsslowcert_dataStart(buf,buf_length,&subject->len,PR_TRUE, NULL); if (subject->data == NULL) return SECFailure; buf_length -= (subject->data-buf) + subject->len; buf = subject->data + subject->len; /* subject key info */ - subjkey->data=nsslowcert_dataStart(buf,buf_length,&subjkey->len,PR_TRUE); + subjkey->data=nsslowcert_dataStart(buf,buf_length,&subjkey->len,PR_TRUE, NULL); if (subjkey->data == NULL) return SECFailure; buf_length -= (subjkey->data-buf) + subjkey->len; buf = subjkey->data + subjkey->len; @@ -253,15 +278,15 @@ nsslowcert_GetCertTimes(NSSLOWCERTCertificate *c, PRTime *notBefore, PRTime *not } /* convert DER not-before time */ - rv = DER_UTCTimeToTime(notBefore, &validity.notBefore); + rv = CERT_DecodeTimeChoice(notBefore, &validity.notBefore); if (rv) { - return(SECFailure); + return(SECFailure); } /* convert DER not-after time */ - rv = DER_UTCTimeToTime(notAfter, &validity.notAfter); + rv = CERT_DecodeTimeChoice(notAfter, &validity.notAfter); if (rv) { - return(SECFailure); + return(SECFailure); } return(SECSuccess); @@ -305,7 +330,7 @@ nsslowcert_IsNewer(NSSLOWCERTCertificate *certa, NSSLOWCERTCertificate *certb) return(PR_FALSE); } - /* get current UTC time */ + /* get current time */ now = PR_Now(); if ( newerbefore ) { diff --git a/security/nss/lib/util/dertime.c b/security/nss/lib/util/dertime.c index 75e1761a2..2651a4f00 100644 --- a/security/nss/lib/util/dertime.c +++ b/security/nss/lib/util/dertime.c @@ -73,14 +73,18 @@ static long monthToDayInYear[12] = { /* gmttime must contains UTC time in micro-seconds unit */ SECStatus -DER_TimeToUTCTime(SECItem *dst, int64 gmttime) +DER_TimeToUTCTimeArena(PRArenaPool* arenaOpt, SECItem *dst, int64 gmttime) { PRExplodedTime printableTime; unsigned char *d; dst->len = 13; - dst->data = d = (unsigned char*) PORT_Alloc(13); - dst->type = siBuffer; + if (arenaOpt) { + dst->data = d = (unsigned char*) PORT_ArenaAlloc(arenaOpt, dst->len); + } else { + dst->data = d = (unsigned char*) PORT_Alloc(dst->len); + } + dst->type = siUTCTime; if (!d) { return SECFailure; } @@ -116,6 +120,13 @@ DER_TimeToUTCTime(SECItem *dst, int64 gmttime) } SECStatus +DER_TimeToUTCTime(SECItem *dst, int64 gmttime) +{ + return DER_TimeToUTCTimeArena(NULL, dst, gmttime); +} + + +SECStatus DER_AsciiToTime(int64 *dst, char *string) { long year, month, mday, hour, minute, second, hourOff, minOff, days; @@ -222,14 +233,18 @@ DER_UTCTimeToTime(int64 *dst, SECItem *time) certificate extension, which does not have this restriction. */ SECStatus -DER_TimeToGeneralizedTime(SECItem *dst, int64 gmttime) +DER_TimeToGeneralizedTimeArena(PRArenaPool* arenaOpt, SECItem *dst, int64 gmttime) { PRExplodedTime printableTime; unsigned char *d; dst->len = 15; - dst->data = d = (unsigned char*) PORT_Alloc(15); - dst->type = siBuffer; + if (arenaOpt) { + dst->data = d = (unsigned char*) PORT_ArenaAlloc(arenaOpt, dst->len); + } else { + dst->data = d = (unsigned char*) PORT_Alloc(dst->len); + } + dst->type = siGeneralizedTime; if (!d) { return SECFailure; } @@ -260,6 +275,13 @@ DER_TimeToGeneralizedTime(SECItem *dst, int64 gmttime) return SECSuccess; } +SECStatus +DER_TimeToGeneralizedTime(SECItem *dst, int64 gmttime) +{ + return DER_TimeToGeneralizedTimeArena(NULL, dst, gmttime); +} + + /* The caller should make sure that the generalized time should only be used for the certificate validity after the year 2051; otherwise, diff --git a/security/nss/lib/util/seccomon.h b/security/nss/lib/util/seccomon.h index f55f1311d..96d41af07 100644 --- a/security/nss/lib/util/seccomon.h +++ b/security/nss/lib/util/seccomon.h @@ -68,7 +68,9 @@ typedef enum { siAsciiNameString = 7, siAsciiString = 8, siDEROID = 9, - siUnsignedInteger = 10 + siUnsignedInteger = 10, + siUTCTime = 11, + siGeneralizedTime = 12 } SECItemType; typedef struct SECItemStr SECItem; diff --git a/security/nss/lib/util/secder.h b/security/nss/lib/util/secder.h index fdd43b1de..a54967f61 100644 --- a/security/nss/lib/util/secder.h +++ b/security/nss/lib/util/secder.h @@ -51,6 +51,7 @@ #include "seccomon.h" #include "secdert.h" +#include "prtime.h" SEC_BEGIN_PROTOS @@ -137,6 +138,9 @@ extern unsigned long DER_GetUInteger(SECItem *src); ** result->data points to upon a successfull operation. */ extern SECStatus DER_TimeToUTCTime(SECItem *result, int64 time); +extern SECStatus DER_TimeToUTCTimeArena(PRArenaPool* arenaOpt, + SECItem *dst, int64 gmttime); + /* ** Convert an ascii encoded time value (according to DER rules) into @@ -165,11 +169,17 @@ extern char *DER_UTCTimeToAscii(SECItem *utcTime); ** The caller is responsible for deallocating the returned buffer. */ extern char *DER_UTCDayToAscii(SECItem *utctime); +/* same thing for DER encoded GeneralizedTime */ +extern char *DER_GeneralizedDayToAscii(SECItem *gentime); +/* same thing for either DER UTCTime or GeneralizedTime */ +extern char *DER_TimeChoiceDayToAscii(SECItem *timechoice); /* ** Convert a int64 time to a DER encoded Generalized time */ extern SECStatus DER_TimeToGeneralizedTime(SECItem *dst, int64 gmttime); +extern SECStatus DER_TimeToGeneralizedTimeArena(PRArenaPool* arenaOpt, + SECItem *dst, int64 gmttime); /* ** Convert a DER encoded Generalized time value into a UNIX time value. @@ -183,7 +193,7 @@ extern SECStatus DER_GeneralizedTimeToTime(int64 *dst, SECItem *time); ** caller is responsible for deallocating the returned buffer. */ extern char *CERT_UTCTime2FormattedAscii (int64 utcTime, char *format); - +#define CERT_GeneralizedTime2FormattedAscii CERT_UTCTime2FormattedAscii /* ** Convert from a int64 Generalized time value to a formatted ascii value. The @@ -191,6 +201,19 @@ extern char *CERT_UTCTime2FormattedAscii (int64 utcTime, char *format); */ extern char *CERT_GenTime2FormattedAscii (int64 genTime, char *format); +/* +** decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME +** or a SEC_ASN1_UTC_TIME +*/ + +extern SECStatus CERT_DecodeTimeChoice(PRTime* output, SECItem* input); + +/* encode a PRTime to an ASN.1 DER SECItem containing either a + SEC_ASN1_GENERALIZED_TIME or a SEC_ASN1_UTC_TIME */ + +extern SECStatus CERT_EncodeTimeChoice(PRArenaPool* arena, SECItem* output, + PRTime input); + SEC_END_PROTOS #endif /* _SECDER_H_ */ diff --git a/security/nss/lib/util/sectime.c b/security/nss/lib/util/sectime.c index d3cca6f87..678021853 100644 --- a/security/nss/lib/util/sectime.c +++ b/security/nss/lib/util/sectime.c @@ -36,28 +36,31 @@ #include "secder.h" #include "cert.h" #include "secitem.h" +#include "secerr.h" + +const SEC_ASN1Template CERT_TimeChoiceTemplate[] = { + { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) }, + { SEC_ASN1_UTC_TIME, 0, 0, siUTCTime }, + { SEC_ASN1_GENERALIZED_TIME, 0, 0, siGeneralizedTime }, + { 0 } +}; + +SEC_ASN1_CHOOSER_IMPLEMENT(CERT_TimeChoiceTemplate); const SEC_ASN1Template CERT_ValidityTemplate[] = { { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(CERTValidity) }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTValidity,notBefore) }, - { SEC_ASN1_UTC_TIME, - offsetof(CERTValidity,notAfter) }, + { SEC_ASN1_INLINE, + offsetof(CERTValidity,notBefore), CERT_TimeChoiceTemplate, 0 }, + { SEC_ASN1_INLINE, + offsetof(CERTValidity,notAfter), CERT_TimeChoiceTemplate, 0 }, { 0 } }; -DERTemplate CERTValidityTemplate[] = { - { DER_SEQUENCE, - 0, NULL, sizeof(CERTValidity) }, - { DER_UTC_TIME, - offsetof(CERTValidity,notBefore), }, - { DER_UTC_TIME, - offsetof(CERTValidity,notAfter), }, - { 0, } -}; +PRTime January1st2050 = LL_INIT(0x0008f81e,0x1b098000); static char *DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format); +static char *DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format); /* convert DER utc time to ascii time string */ char * @@ -73,6 +76,36 @@ DER_UTCDayToAscii(SECItem *utctime) return (DecodeUTCTime2FormattedAscii (utctime, "%a %b %d, %Y")); } +/* convert DER generalized time to ascii time string, only include day, + not time */ +char * +DER_GeneralizedDayToAscii(SECItem *gentime) +{ + return (DecodeGeneralizedTime2FormattedAscii (gentime, "%a %b %d, %Y")); +} + +/* convert DER generalized or UTC time to ascii time string, only include + day, not time */ +char * +DER_TimeChoiceDayToAscii(SECItem *timechoice) +{ + switch (timechoice->type) { + + case siUTCTime: + return DER_UTCDayToAscii(timechoice); + + case siGeneralizedTime: + return DER_GeneralizedDayToAscii(timechoice); + + default: + PORT_Assert(0); + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return NULL; + } +} + + + CERTValidity * CERT_CreateValidity(int64 notBefore, int64 notAfter) { @@ -89,9 +122,9 @@ CERT_CreateValidity(int64 notBefore, int64 notAfter) v = (CERTValidity*) PORT_ArenaZAlloc(arena, sizeof(CERTValidity)); if (v) { v->arena = arena; - rv = DER_TimeToUTCTime(&v->notBefore, notBefore); + rv = CERT_EncodeTimeChoice(arena, &v->notBefore, notBefore); if (rv) goto loser; - rv = DER_TimeToUTCTime(&v->notAfter, notAfter); + rv = CERT_EncodeTimeChoice(arena, &v->notAfter, notAfter); if (rv) goto loser; } return v; @@ -175,3 +208,50 @@ DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format) } return (CERT_UTCTime2FormattedAscii (utcTime, format)); } + +/* convert DER utc time to ascii time string, The format of the time string + depends on the input "format" + */ +static char * +DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format) +{ + PRTime generalizedTime; + int rv; + + rv = DER_GeneralizedTimeToTime(&generalizedTime, generalizedTimeDER); + if (rv) { + return(NULL); + } + return (CERT_GeneralizedTime2FormattedAscii (generalizedTime, format)); +} + +/* decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME + or a SEC_ASN1_UTC_TIME */ + +SECStatus CERT_DecodeTimeChoice(PRTime* output, SECItem* input) +{ + switch (input->type) { + case siGeneralizedTime: + return DER_GeneralizedTimeToTime(output, input); + + case siUTCTime: + return DER_UTCTimeToTime(output, input); + + default: + PORT_SetError(SEC_ERROR_INVALID_ARGS); + PORT_Assert(0); + return SECFailure; + } +} + +/* encode a PRTime to an ASN.1 DER SECItem containing either a + SEC_ASN1_GENERALIZED_TIME or a SEC_ASN1_UTC_TIME */ + +SECStatus CERT_EncodeTimeChoice(PRArenaPool* arena, SECItem* output, PRTime input) +{ + if (LL_CMP(input, >, January1st2050)) { + return DER_TimeToGeneralizedTimeArena(arena, output, input); + } else { + return DER_TimeToUTCTimeArena(arena, output, input); + } +} diff --git a/security/nss/tests/cert/cert.sh b/security/nss/tests/cert/cert.sh index 11d59456a..6bb91b6a8 100755 --- a/security/nss/tests/cert/cert.sh +++ b/security/nss/tests/cert/cert.sh @@ -339,7 +339,7 @@ cert_CA() # CU_ACTION="Creating CA Cert $NICKNAME " CU_SUBJECT=$ALL_CU_SUBJECT - certu -S -n $NICKNAME -t $TRUSTARG -v 60 $SIGNER -d ${LPROFILE} -1 -2 -5 \ + certu -S -n $NICKNAME -t $TRUSTARG -v 600 $SIGNER -d ${LPROFILE} -1 -2 -5 \ -f ${R_PWFILE} -z ${R_NOISE_FILE} -m $CERTSERIAL 2>&1 <<CERTSCRIPT 5 9 @@ -618,7 +618,7 @@ MODSCRIPT CU_ACTION="Generate Certificate for ${CERTNAME}" CU_SUBJECT="CN=${CERTNAME}, E=fips@bogus.com, O=BOGUS NSS, OU=FIPS PUB 140-1, L=Mountain View, ST=California, C=US" - certu -S -n ${FIPSCERTNICK} -x -t "Cu,Cu,Cu" -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" -k dsa -m 500 -z "${R_NOISE_FILE}" 2>&1 + certu -S -n ${FIPSCERTNICK} -x -t "Cu,Cu,Cu" -d "${PROFILEDIR}" -f "${R_FIPSPWFILE}" -k dsa -v 600 -m 500 -z "${R_NOISE_FILE}" 2>&1 if [ "$RET" -eq 0 ]; then cert_log "SUCCESS: FIPS passed" fi |