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