michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "prtime.h" michael@0: #include "secder.h" michael@0: #include "secitem.h" michael@0: #include "secerr.h" michael@0: michael@0: static char *DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format); michael@0: static char *DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format); michael@0: michael@0: /* convert DER utc time to ascii time string */ michael@0: char * michael@0: DER_UTCTimeToAscii(SECItem *utcTime) michael@0: { michael@0: return (DecodeUTCTime2FormattedAscii (utcTime, "%a %b %d %H:%M:%S %Y")); michael@0: } michael@0: michael@0: /* convert DER utc time to ascii time string, only include day, not time */ michael@0: char * michael@0: DER_UTCDayToAscii(SECItem *utctime) michael@0: { michael@0: return (DecodeUTCTime2FormattedAscii (utctime, "%a %b %d, %Y")); michael@0: } michael@0: michael@0: /* convert DER generalized time to ascii time string, only include day, michael@0: not time */ michael@0: char * michael@0: DER_GeneralizedDayToAscii(SECItem *gentime) michael@0: { michael@0: return (DecodeGeneralizedTime2FormattedAscii (gentime, "%a %b %d, %Y")); michael@0: } michael@0: michael@0: /* convert DER generalized or UTC time to ascii time string, only include michael@0: day, not time */ michael@0: char * michael@0: DER_TimeChoiceDayToAscii(SECItem *timechoice) michael@0: { michael@0: switch (timechoice->type) { michael@0: michael@0: case siUTCTime: michael@0: return DER_UTCDayToAscii(timechoice); michael@0: michael@0: case siGeneralizedTime: michael@0: return DER_GeneralizedDayToAscii(timechoice); michael@0: michael@0: default: michael@0: PORT_Assert(0); michael@0: PORT_SetError(SEC_ERROR_INVALID_ARGS); michael@0: return NULL; michael@0: } michael@0: } michael@0: michael@0: char * michael@0: CERT_UTCTime2FormattedAscii(PRTime utcTime, char *format) michael@0: { michael@0: PRExplodedTime printableTime; michael@0: char *timeString; michael@0: michael@0: /* Converse time to local time and decompose it into components */ michael@0: PR_ExplodeTime(utcTime, PR_LocalTimeParameters, &printableTime); michael@0: michael@0: timeString = (char *)PORT_Alloc(256); michael@0: michael@0: if ( timeString ) { michael@0: if ( ! PR_FormatTime( timeString, 256, format, &printableTime )) { michael@0: PORT_Free(timeString); michael@0: timeString = NULL; michael@0: } michael@0: } michael@0: michael@0: return (timeString); michael@0: } michael@0: michael@0: char *CERT_GenTime2FormattedAscii(PRTime genTime, char *format) michael@0: { michael@0: PRExplodedTime printableTime; michael@0: char *timeString; michael@0: michael@0: /* Decompose time into components */ michael@0: PR_ExplodeTime(genTime, PR_GMTParameters, &printableTime); michael@0: michael@0: timeString = (char *)PORT_Alloc(256); michael@0: michael@0: if ( timeString ) { michael@0: if ( ! PR_FormatTime( timeString, 256, format, &printableTime )) { michael@0: PORT_Free(timeString); michael@0: timeString = NULL; michael@0: PORT_SetError(SEC_ERROR_OUTPUT_LEN); michael@0: } michael@0: } michael@0: michael@0: return (timeString); michael@0: } michael@0: michael@0: michael@0: /* convert DER utc time to ascii time string, The format of the time string michael@0: depends on the input "format" michael@0: */ michael@0: static char * michael@0: DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format) michael@0: { michael@0: PRTime utcTime; michael@0: int rv; michael@0: michael@0: rv = DER_UTCTimeToTime(&utcTime, utcTimeDER); michael@0: if (rv) { michael@0: return(NULL); michael@0: } michael@0: return (CERT_UTCTime2FormattedAscii (utcTime, format)); michael@0: } michael@0: michael@0: /* convert DER utc time to ascii time string, The format of the time string michael@0: depends on the input "format" michael@0: */ michael@0: static char * michael@0: DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format) michael@0: { michael@0: PRTime generalizedTime; michael@0: int rv; michael@0: michael@0: rv = DER_GeneralizedTimeToTime(&generalizedTime, generalizedTimeDER); michael@0: if (rv) { michael@0: return(NULL); michael@0: } michael@0: return (CERT_GeneralizedTime2FormattedAscii (generalizedTime, format)); michael@0: } michael@0: michael@0: /* decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME michael@0: or a SEC_ASN1_UTC_TIME */ michael@0: michael@0: SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input) michael@0: { michael@0: switch (input->type) { michael@0: case siGeneralizedTime: michael@0: return DER_GeneralizedTimeToTime(output, input); michael@0: michael@0: case siUTCTime: michael@0: return DER_UTCTimeToTime(output, input); michael@0: michael@0: default: michael@0: PORT_SetError(SEC_ERROR_INVALID_ARGS); michael@0: PORT_Assert(0); michael@0: return SECFailure; michael@0: } michael@0: } michael@0: michael@0: /* encode a PRTime to an ASN.1 DER SECItem containing either a michael@0: SEC_ASN1_GENERALIZED_TIME or a SEC_ASN1_UTC_TIME */ michael@0: michael@0: SECStatus DER_EncodeTimeChoice(PLArenaPool* arena, SECItem* output, PRTime input) michael@0: { michael@0: SECStatus rv; michael@0: michael@0: rv = DER_TimeToUTCTimeArena(arena, output, input); michael@0: if (rv == SECSuccess || PORT_GetError() != SEC_ERROR_INVALID_ARGS) { michael@0: return rv; michael@0: } michael@0: return DER_TimeToGeneralizedTimeArena(arena, output, input); michael@0: }