From 93fb5ea7e9a1c982d6df0eb5f0e5f129da84fcdc Mon Sep 17 00:00:00 2001 From: "julien.pierre.bugs%sun.com" Date: Fri, 4 May 2007 00:22:46 +0000 Subject: [PATCH] Fix for bug 378815 - DER_TimeToGeneralizedTimeArena and DER_TimeToUTCTimeArena don't check for valid range and may leak. r=nelson, wtc git-svn-id: svn://10.0.0.236/trunk@225557 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/security/nss/lib/util/dertime.c | 22 +++++++++++++++------- mozilla/security/nss/lib/util/secder.h | 8 ++++++-- mozilla/security/nss/lib/util/sectime.c | 4 ++-- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/mozilla/security/nss/lib/util/dertime.c b/mozilla/security/nss/lib/util/dertime.c index c47232b24a0..5fb887d1f6f 100644 --- a/mozilla/security/nss/lib/util/dertime.c +++ b/mozilla/security/nss/lib/util/dertime.c @@ -74,6 +74,11 @@ static long monthToDayInYear[12] = { 31+28+31+30+31+30+31+31+30+31+30, }; +static const PRTime January1st1 = (PRTime) LL_INIT(0xff234001U, 0x00d44000U); +static const PRTime January1st1950 = (PRTime) LL_INIT(0xfffdc1f8U, 0x793da000U); +static const PRTime January1st2050 = LL_INIT(0x0008f81e, 0x1b098000); +static const PRTime January1st10000 = LL_INIT(0x0384440c, 0xcc736000); + /* gmttime must contains UTC time in micro-seconds unit */ SECStatus DER_TimeToUTCTimeArena(PRArenaPool* arenaOpt, SECItem *dst, int64 gmttime) @@ -81,6 +86,11 @@ DER_TimeToUTCTimeArena(PRArenaPool* arenaOpt, SECItem *dst, int64 gmttime) PRExplodedTime printableTime; unsigned char *d; + if ( (gmttime < January1st1950) || (gmttime >= January1st2050) ) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + dst->len = 13; if (arenaOpt) { dst->data = d = (unsigned char*) PORT_ArenaAlloc(arenaOpt, dst->len); @@ -98,10 +108,6 @@ DER_TimeToUTCTimeArena(PRArenaPool* arenaOpt, SECItem *dst, int64 gmttime) /* The month in UTC time is base one */ printableTime.tm_month++; - /* UTC time does not handle the years before 1950 */ - if (printableTime.tm_year < 1950) - return SECFailure; - /* remove the century since it's added to the tm_year by the PR_ExplodeTime routine, but is not needed for UTC time */ printableTime.tm_year %= 100; @@ -269,6 +275,10 @@ DER_TimeToGeneralizedTimeArena(PRArenaPool* arenaOpt, SECItem *dst, int64 gmttim PRExplodedTime printableTime; unsigned char *d; + if ( (gmttime=January1st10000) ) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } dst->len = 15; if (arenaOpt) { dst->data = d = (unsigned char*) PORT_ArenaAlloc(arenaOpt, dst->len); @@ -280,9 +290,7 @@ DER_TimeToGeneralizedTimeArena(PRArenaPool* arenaOpt, SECItem *dst, int64 gmttim return SECFailure; } - /*Convert a int64 time to a printable format. This is a temporary call - until we change to NSPR 2.0 - */ + /* Convert an int64 time to a printable format. */ PR_ExplodeTime(gmttime, PR_GMTParameters, &printableTime); /* The month in Generalized time is base one */ diff --git a/mozilla/security/nss/lib/util/secder.h b/mozilla/security/nss/lib/util/secder.h index 79bbc8a9eb6..2dd588f31bc 100644 --- a/mozilla/security/nss/lib/util/secder.h +++ b/mozilla/security/nss/lib/util/secder.h @@ -41,7 +41,7 @@ * secder.h - public data structures and prototypes for the DER encoding and * decoding utilities library * - * $Id: secder.h,v 1.7 2004-04-25 15:03:18 gerv%gerv.net Exp $ + * $Id: secder.h,v 1.8 2007-05-04 00:22:32 julien.pierre.bugs%sun.com Exp $ */ #if defined(_WIN32_WCE) @@ -137,8 +137,10 @@ extern unsigned long DER_GetUInteger(SECItem *src); ** Convert a "UNIX" time value to a der encoded time value. ** "result" is the der encoded time (memory is allocated) ** "time" is the "UNIX" time value (Since Jan 1st, 1970). +** time must be on or after January 1, 1950, and +** before January 1, 2050 ** The caller is responsible for freeing up the buffer which -** result->data points to upon a successfull operation. +** result->data points to upon a successful operation. */ extern SECStatus DER_TimeToUTCTime(SECItem *result, int64 time); extern SECStatus DER_TimeToUTCTimeArena(PRArenaPool* arenaOpt, @@ -179,6 +181,8 @@ extern char *DER_TimeChoiceDayToAscii(SECItem *timechoice); /* ** Convert a int64 time to a DER encoded Generalized time +** gmttime must be on or after January 1, year 1 and +** before January 1, 10000. */ extern SECStatus DER_TimeToGeneralizedTime(SECItem *dst, int64 gmttime); extern SECStatus DER_TimeToGeneralizedTimeArena(PRArenaPool* arenaOpt, diff --git a/mozilla/security/nss/lib/util/sectime.c b/mozilla/security/nss/lib/util/sectime.c index bea0ffacc9c..53e18769a1e 100644 --- a/mozilla/security/nss/lib/util/sectime.c +++ b/mozilla/security/nss/lib/util/sectime.c @@ -41,6 +41,8 @@ #include "secitem.h" #include "secerr.h" +static const PRTime January1st2050 = LL_INIT(0x0008f81e, 0x1b098000); + const SEC_ASN1Template CERT_TimeChoiceTemplate[] = { { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) }, { SEC_ASN1_UTC_TIME, 0, 0, siUTCTime }, @@ -60,8 +62,6 @@ const SEC_ASN1Template CERT_ValidityTemplate[] = { { 0 } }; -PRTime January1st2050 = LL_INIT(0x0008f81e,0x1b098000); - static char *DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format); static char *DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format);