summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjpierre%netscape.com <devnull@localhost>2003-09-19 04:08:51 +0000
committerjpierre%netscape.com <devnull@localhost>2003-09-19 04:08:51 +0000
commitb7dbfb715beafac22aeee2060d840d4bd88141cd (patch)
treea89a5aa7e921a72a65080f56a65373049f24c630
parent16da93c3d350a30fcdb9dd1522451cfd8aa096cb (diff)
downloadnss-hg-b7dbfb715beafac22aeee2060d840d4bd88141cd.tar.gz
Fix for bug 143334 : add support for GeneralizedTime in certificates and CRLs. r=wtc,nelsonb
-rw-r--r--security/nss/lib/certdb/certdb.c17
-rw-r--r--security/nss/lib/certdb/certt.h2
-rw-r--r--security/nss/lib/certdb/crl.c30
-rw-r--r--security/nss/lib/certhigh/certhtml.c4
-rw-r--r--security/nss/lib/certhigh/certvfy.c2
-rw-r--r--security/nss/lib/nss/nss.def3
-rw-r--r--security/nss/lib/softoken/lowcert.c61
-rw-r--r--security/nss/lib/util/dertime.c34
-rw-r--r--security/nss/lib/util/seccomon.h4
-rw-r--r--security/nss/lib/util/secder.h25
-rw-r--r--security/nss/lib/util/sectime.c110
-rwxr-xr-xsecurity/nss/tests/cert/cert.sh4
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, &notBefore, &notAfter);
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,
- &notBefore->len,PR_FALSE);
+ &notBefore->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,
- &notAfter->len,PR_FALSE);
+ &notAfter->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