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 const SEC_ASN1Template CERT_TimeChoiceTemplate[] = {
00045   { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) },
00046   { SEC_ASN1_UTC_TIME, 0, 0, siUTCTime },
00047   { SEC_ASN1_GENERALIZED_TIME, 0, 0, siGeneralizedTime },
00048   { 0 }
00049 };
00050 
00051 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_TimeChoiceTemplate)
00052 
00053 const SEC_ASN1Template CERT_ValidityTemplate[] = {
00054     { SEC_ASN1_SEQUENCE,
00055          0, NULL, sizeof(CERTValidity) },
00056     { SEC_ASN1_INLINE,
00057          offsetof(CERTValidity,notBefore), CERT_TimeChoiceTemplate, 0 },
00058     { SEC_ASN1_INLINE,
00059          offsetof(CERTValidity,notAfter), CERT_TimeChoiceTemplate, 0 },
00060     { 0 }
00061 };
00062 
00063 PRTime January1st2050 = LL_INIT(0x0008f81e,0x1b098000);
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     arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
00120     
00121     if ( !arena ) {
00122        return(0);
00123     }
00124     
00125     v = (CERTValidity*) PORT_ArenaZAlloc(arena, sizeof(CERTValidity));
00126     if (v) {
00127        v->arena = arena;
00128        rv = DER_EncodeTimeChoice(arena, &v->notBefore, notBefore);
00129        if (rv) goto loser;
00130        rv = DER_EncodeTimeChoice(arena, &v->notAfter, notAfter);
00131        if (rv) goto loser;
00132     }
00133     return v;
00134 
00135   loser:
00136     CERT_DestroyValidity(v);
00137     return 0;
00138 }
00139 
00140 SECStatus
00141 CERT_CopyValidity(PRArenaPool *arena, CERTValidity *to, CERTValidity *from)
00142 {
00143     SECStatus rv;
00144 
00145     CERT_DestroyValidity(to);
00146     to->arena = arena;
00147     
00148     rv = SECITEM_CopyItem(arena, &to->notBefore, &from->notBefore);
00149     if (rv) return rv;
00150     rv = SECITEM_CopyItem(arena, &to->notAfter, &from->notAfter);
00151     return rv;
00152 }
00153 
00154 void
00155 CERT_DestroyValidity(CERTValidity *v)
00156 {
00157     if (v && v->arena) {
00158        PORT_FreeArena(v->arena, PR_FALSE);
00159     }
00160     return;
00161 }
00162 
00163 char *
00164 CERT_UTCTime2FormattedAscii (int64 utcTime, char *format)
00165 {
00166     PRExplodedTime printableTime; 
00167     char *timeString;
00168    
00169     /* Converse time to local time and decompose it into components */
00170     PR_ExplodeTime(utcTime, PR_LocalTimeParameters, &printableTime);
00171     
00172     timeString = (char *)PORT_Alloc(100);
00173 
00174     if ( timeString ) {
00175         PR_FormatTime( timeString, 100, format, &printableTime );
00176     }
00177     
00178     return (timeString);
00179 }
00180 
00181 char *CERT_GenTime2FormattedAscii (int64 genTime, char *format)
00182 {
00183     PRExplodedTime printableTime; 
00184     char *timeString;
00185    
00186     /* Decompose time into components */
00187     PR_ExplodeTime(genTime, PR_GMTParameters, &printableTime);
00188     
00189     timeString = (char *)PORT_Alloc(100);
00190 
00191     if ( timeString ) {
00192         PR_FormatTime( timeString, 100, format, &printableTime );
00193     }
00194     
00195     return (timeString);
00196 }
00197 
00198 
00199 /* convert DER utc time to ascii time string, The format of the time string
00200    depends on the input "format"
00201  */
00202 static char *
00203 DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER,  char *format)
00204 {
00205     int64 utcTime;
00206     int rv;
00207    
00208     rv = DER_UTCTimeToTime(&utcTime, utcTimeDER);
00209     if (rv) {
00210         return(NULL);
00211     }
00212     return (CERT_UTCTime2FormattedAscii (utcTime, format));
00213 }
00214 
00215 /* convert DER utc time to ascii time string, The format of the time string
00216    depends on the input "format"
00217  */
00218 static char *
00219 DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER,  char *format)
00220 {
00221     PRTime generalizedTime;
00222     int rv;
00223    
00224     rv = DER_GeneralizedTimeToTime(&generalizedTime, generalizedTimeDER);
00225     if (rv) {
00226         return(NULL);
00227     }
00228     return (CERT_GeneralizedTime2FormattedAscii (generalizedTime, format));
00229 }
00230 
00231 /* decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME 
00232    or a SEC_ASN1_UTC_TIME */
00233 
00234 SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input)
00235 {
00236     switch (input->type) {
00237         case siGeneralizedTime:
00238             return DER_GeneralizedTimeToTime(output, input);
00239 
00240         case siUTCTime:
00241             return DER_UTCTimeToTime(output, input);
00242 
00243         default:
00244             PORT_SetError(SEC_ERROR_INVALID_ARGS);
00245             PORT_Assert(0);
00246             return SECFailure;
00247     }
00248 }
00249 
00250 /* encode a PRTime to an ASN.1 DER SECItem containing either a
00251    SEC_ASN1_GENERALIZED_TIME or a SEC_ASN1_UTC_TIME */
00252 
00253 SECStatus DER_EncodeTimeChoice(PRArenaPool* arena, SECItem* output, PRTime input)
00254 {
00255     if (LL_CMP(input, >, January1st2050)) {
00256         return DER_TimeToGeneralizedTimeArena(arena, output, input);
00257     } else {
00258         return DER_TimeToUTCTimeArena(arena, output, input);
00259     }
00260 }