Back to index

lightning-sunbird  0.9+nobinonly
sectime.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #include "prlong.h"
00038 #include "prtime.h"
00039 #include "secder.h"
00040 #include "cert.h"
00041 #include "secitem.h"
00042 #include "secerr.h"
00043 
00044 static const PRTime January1st2050  = LL_INIT(0x0008f81e, 0x1b098000);
00045 
00046 const SEC_ASN1Template CERT_TimeChoiceTemplate[] = {
00047   { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) },
00048   { SEC_ASN1_UTC_TIME, 0, 0, siUTCTime },
00049   { SEC_ASN1_GENERALIZED_TIME, 0, 0, siGeneralizedTime },
00050   { 0 }
00051 };
00052 
00053 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_TimeChoiceTemplate)
00054 
00055 const SEC_ASN1Template CERT_ValidityTemplate[] = {
00056     { SEC_ASN1_SEQUENCE,
00057          0, NULL, sizeof(CERTValidity) },
00058     { SEC_ASN1_INLINE,
00059          offsetof(CERTValidity,notBefore), CERT_TimeChoiceTemplate, 0 },
00060     { SEC_ASN1_INLINE,
00061          offsetof(CERTValidity,notAfter), CERT_TimeChoiceTemplate, 0 },
00062     { 0 }
00063 };
00064 
00065 static char *DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format);
00066 static char *DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format);
00067 
00068 /* convert DER utc time to ascii time string */
00069 char *
00070 DER_UTCTimeToAscii(SECItem *utcTime)
00071 {
00072     return (DecodeUTCTime2FormattedAscii (utcTime, "%a %b %d %H:%M:%S %Y"));
00073 }
00074 
00075 /* convert DER utc time to ascii time string, only include day, not time */
00076 char *
00077 DER_UTCDayToAscii(SECItem *utctime)
00078 {
00079     return (DecodeUTCTime2FormattedAscii (utctime, "%a %b %d, %Y"));
00080 }
00081 
00082 /* convert DER generalized time to ascii time string, only include day,
00083    not time */
00084 char *
00085 DER_GeneralizedDayToAscii(SECItem *gentime)
00086 {
00087     return (DecodeGeneralizedTime2FormattedAscii (gentime, "%a %b %d, %Y"));
00088 }
00089 
00090 /* convert DER generalized or UTC time to ascii time string, only include
00091    day, not time */
00092 char *
00093 DER_TimeChoiceDayToAscii(SECItem *timechoice)
00094 {
00095     switch (timechoice->type) {
00096 
00097     case siUTCTime:
00098         return DER_UTCDayToAscii(timechoice);
00099 
00100     case siGeneralizedTime:
00101         return DER_GeneralizedDayToAscii(timechoice);
00102 
00103     default:
00104         PORT_Assert(0);
00105         PORT_SetError(SEC_ERROR_INVALID_ARGS);
00106         return NULL;
00107     }
00108 }
00109 
00110 
00111 
00112 CERTValidity *
00113 CERT_CreateValidity(int64 notBefore, int64 notAfter)
00114 {
00115     CERTValidity *v;
00116     int rv;
00117     PRArenaPool *arena;
00118 
00119     if (notBefore > notAfter) {
00120        PORT_SetError(SEC_ERROR_INVALID_ARGS);
00121        return NULL;
00122     }
00123     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
00124     
00125     if ( !arena ) {
00126        return(0);
00127     }
00128     
00129     v = (CERTValidity*) PORT_ArenaZAlloc(arena, sizeof(CERTValidity));
00130     if (v) {
00131        v->arena = arena;
00132        rv = DER_EncodeTimeChoice(arena, &v->notBefore, notBefore);
00133        if (rv) goto loser;
00134        rv = DER_EncodeTimeChoice(arena, &v->notAfter, notAfter);
00135        if (rv) goto loser;
00136     }
00137     return v;
00138 
00139   loser:
00140     CERT_DestroyValidity(v);
00141     return 0;
00142 }
00143 
00144 SECStatus
00145 CERT_CopyValidity(PRArenaPool *arena, CERTValidity *to, CERTValidity *from)
00146 {
00147     SECStatus rv;
00148 
00149     CERT_DestroyValidity(to);
00150     to->arena = arena;
00151     
00152     rv = SECITEM_CopyItem(arena, &to->notBefore, &from->notBefore);
00153     if (rv) return rv;
00154     rv = SECITEM_CopyItem(arena, &to->notAfter, &from->notAfter);
00155     return rv;
00156 }
00157 
00158 void
00159 CERT_DestroyValidity(CERTValidity *v)
00160 {
00161     if (v && v->arena) {
00162        PORT_FreeArena(v->arena, PR_FALSE);
00163     }
00164     return;
00165 }
00166 
00167 char *
00168 CERT_UTCTime2FormattedAscii (int64 utcTime, char *format)
00169 {
00170     PRExplodedTime printableTime; 
00171     char *timeString;
00172    
00173     /* Converse time to local time and decompose it into components */
00174     PR_ExplodeTime(utcTime, PR_LocalTimeParameters, &printableTime);
00175     
00176     timeString = (char *)PORT_Alloc(100);
00177 
00178     if ( timeString ) {
00179         PR_FormatTime( timeString, 100, format, &printableTime );
00180     }
00181     
00182     return (timeString);
00183 }
00184 
00185 char *CERT_GenTime2FormattedAscii (int64 genTime, char *format)
00186 {
00187     PRExplodedTime printableTime; 
00188     char *timeString;
00189    
00190     /* Decompose time into components */
00191     PR_ExplodeTime(genTime, PR_GMTParameters, &printableTime);
00192     
00193     timeString = (char *)PORT_Alloc(100);
00194 
00195     if ( timeString ) {
00196         PR_FormatTime( timeString, 100, format, &printableTime );
00197     }
00198     
00199     return (timeString);
00200 }
00201 
00202 
00203 /* convert DER utc time to ascii time string, The format of the time string
00204    depends on the input "format"
00205  */
00206 static char *
00207 DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER,  char *format)
00208 {
00209     int64 utcTime;
00210     int rv;
00211    
00212     rv = DER_UTCTimeToTime(&utcTime, utcTimeDER);
00213     if (rv) {
00214         return(NULL);
00215     }
00216     return (CERT_UTCTime2FormattedAscii (utcTime, format));
00217 }
00218 
00219 /* convert DER utc time to ascii time string, The format of the time string
00220    depends on the input "format"
00221  */
00222 static char *
00223 DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER,  char *format)
00224 {
00225     PRTime generalizedTime;
00226     int rv;
00227    
00228     rv = DER_GeneralizedTimeToTime(&generalizedTime, generalizedTimeDER);
00229     if (rv) {
00230         return(NULL);
00231     }
00232     return (CERT_GeneralizedTime2FormattedAscii (generalizedTime, format));
00233 }
00234 
00235 /* decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME 
00236    or a SEC_ASN1_UTC_TIME */
00237 
00238 SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input)
00239 {
00240     switch (input->type) {
00241         case siGeneralizedTime:
00242             return DER_GeneralizedTimeToTime(output, input);
00243 
00244         case siUTCTime:
00245             return DER_UTCTimeToTime(output, input);
00246 
00247         default:
00248             PORT_SetError(SEC_ERROR_INVALID_ARGS);
00249             PORT_Assert(0);
00250             return SECFailure;
00251     }
00252 }
00253 
00254 /* encode a PRTime to an ASN.1 DER SECItem containing either a
00255    SEC_ASN1_GENERALIZED_TIME or a SEC_ASN1_UTC_TIME */
00256 
00257 SECStatus DER_EncodeTimeChoice(PRArenaPool* arena, SECItem* output, PRTime input)
00258 {
00259     if (LL_CMP(input, >, January1st2050)) {
00260         return DER_TimeToGeneralizedTimeArena(arena, output, input);
00261     } else {
00262         return DER_TimeToUTCTimeArena(arena, output, input);
00263     }
00264 }