Import from 1.9a8 tarball
[mozilla-nss.git] / security / nss / lib / util / sectime.c
blob53e18769a1e51332ccbb4aa5ca0534cefd514e47
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 #include "prlong.h"
38 #include "prtime.h"
39 #include "secder.h"
40 #include "cert.h"
41 #include "secitem.h"
42 #include "secerr.h"
44 static const PRTime January1st2050 = LL_INIT(0x0008f81e, 0x1b098000);
46 const SEC_ASN1Template CERT_TimeChoiceTemplate[] = {
47 { SEC_ASN1_CHOICE, offsetof(SECItem, type), 0, sizeof(SECItem) },
48 { SEC_ASN1_UTC_TIME, 0, 0, siUTCTime },
49 { SEC_ASN1_GENERALIZED_TIME, 0, 0, siGeneralizedTime },
50 { 0 }
53 SEC_ASN1_CHOOSER_IMPLEMENT(CERT_TimeChoiceTemplate)
55 const SEC_ASN1Template CERT_ValidityTemplate[] = {
56 { SEC_ASN1_SEQUENCE,
57 0, NULL, sizeof(CERTValidity) },
58 { SEC_ASN1_INLINE,
59 offsetof(CERTValidity,notBefore), CERT_TimeChoiceTemplate, 0 },
60 { SEC_ASN1_INLINE,
61 offsetof(CERTValidity,notAfter), CERT_TimeChoiceTemplate, 0 },
62 { 0 }
65 static char *DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format);
66 static char *DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format);
68 /* convert DER utc time to ascii time string */
69 char *
70 DER_UTCTimeToAscii(SECItem *utcTime)
72 return (DecodeUTCTime2FormattedAscii (utcTime, "%a %b %d %H:%M:%S %Y"));
75 /* convert DER utc time to ascii time string, only include day, not time */
76 char *
77 DER_UTCDayToAscii(SECItem *utctime)
79 return (DecodeUTCTime2FormattedAscii (utctime, "%a %b %d, %Y"));
82 /* convert DER generalized time to ascii time string, only include day,
83 not time */
84 char *
85 DER_GeneralizedDayToAscii(SECItem *gentime)
87 return (DecodeGeneralizedTime2FormattedAscii (gentime, "%a %b %d, %Y"));
90 /* convert DER generalized or UTC time to ascii time string, only include
91 day, not time */
92 char *
93 DER_TimeChoiceDayToAscii(SECItem *timechoice)
95 switch (timechoice->type) {
97 case siUTCTime:
98 return DER_UTCDayToAscii(timechoice);
100 case siGeneralizedTime:
101 return DER_GeneralizedDayToAscii(timechoice);
103 default:
104 PORT_Assert(0);
105 PORT_SetError(SEC_ERROR_INVALID_ARGS);
106 return NULL;
112 CERTValidity *
113 CERT_CreateValidity(int64 notBefore, int64 notAfter)
115 CERTValidity *v;
116 int rv;
117 PRArenaPool *arena;
119 if (notBefore > notAfter) {
120 PORT_SetError(SEC_ERROR_INVALID_ARGS);
121 return NULL;
123 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
125 if ( !arena ) {
126 return(0);
129 v = (CERTValidity*) PORT_ArenaZAlloc(arena, sizeof(CERTValidity));
130 if (v) {
131 v->arena = arena;
132 rv = DER_EncodeTimeChoice(arena, &v->notBefore, notBefore);
133 if (rv) goto loser;
134 rv = DER_EncodeTimeChoice(arena, &v->notAfter, notAfter);
135 if (rv) goto loser;
137 return v;
139 loser:
140 CERT_DestroyValidity(v);
141 return 0;
144 SECStatus
145 CERT_CopyValidity(PRArenaPool *arena, CERTValidity *to, CERTValidity *from)
147 SECStatus rv;
149 CERT_DestroyValidity(to);
150 to->arena = arena;
152 rv = SECITEM_CopyItem(arena, &to->notBefore, &from->notBefore);
153 if (rv) return rv;
154 rv = SECITEM_CopyItem(arena, &to->notAfter, &from->notAfter);
155 return rv;
158 void
159 CERT_DestroyValidity(CERTValidity *v)
161 if (v && v->arena) {
162 PORT_FreeArena(v->arena, PR_FALSE);
164 return;
167 char *
168 CERT_UTCTime2FormattedAscii (int64 utcTime, char *format)
170 PRExplodedTime printableTime;
171 char *timeString;
173 /* Converse time to local time and decompose it into components */
174 PR_ExplodeTime(utcTime, PR_LocalTimeParameters, &printableTime);
176 timeString = (char *)PORT_Alloc(100);
178 if ( timeString ) {
179 PR_FormatTime( timeString, 100, format, &printableTime );
182 return (timeString);
185 char *CERT_GenTime2FormattedAscii (int64 genTime, char *format)
187 PRExplodedTime printableTime;
188 char *timeString;
190 /* Decompose time into components */
191 PR_ExplodeTime(genTime, PR_GMTParameters, &printableTime);
193 timeString = (char *)PORT_Alloc(100);
195 if ( timeString ) {
196 PR_FormatTime( timeString, 100, format, &printableTime );
199 return (timeString);
203 /* convert DER utc time to ascii time string, The format of the time string
204 depends on the input "format"
206 static char *
207 DecodeUTCTime2FormattedAscii (SECItem *utcTimeDER, char *format)
209 int64 utcTime;
210 int rv;
212 rv = DER_UTCTimeToTime(&utcTime, utcTimeDER);
213 if (rv) {
214 return(NULL);
216 return (CERT_UTCTime2FormattedAscii (utcTime, format));
219 /* convert DER utc time to ascii time string, The format of the time string
220 depends on the input "format"
222 static char *
223 DecodeGeneralizedTime2FormattedAscii (SECItem *generalizedTimeDER, char *format)
225 PRTime generalizedTime;
226 int rv;
228 rv = DER_GeneralizedTimeToTime(&generalizedTime, generalizedTimeDER);
229 if (rv) {
230 return(NULL);
232 return (CERT_GeneralizedTime2FormattedAscii (generalizedTime, format));
235 /* decode a SECItem containing either a SEC_ASN1_GENERALIZED_TIME
236 or a SEC_ASN1_UTC_TIME */
238 SECStatus DER_DecodeTimeChoice(PRTime* output, const SECItem* input)
240 switch (input->type) {
241 case siGeneralizedTime:
242 return DER_GeneralizedTimeToTime(output, input);
244 case siUTCTime:
245 return DER_UTCTimeToTime(output, input);
247 default:
248 PORT_SetError(SEC_ERROR_INVALID_ARGS);
249 PORT_Assert(0);
250 return SECFailure;
254 /* encode a PRTime to an ASN.1 DER SECItem containing either a
255 SEC_ASN1_GENERALIZED_TIME or a SEC_ASN1_UTC_TIME */
257 SECStatus DER_EncodeTimeChoice(PRArenaPool* arena, SECItem* output, PRTime input)
259 if (LL_CMP(input, >, January1st2050)) {
260 return DER_TimeToGeneralizedTimeArena(arena, output, input);
261 } else {
262 return DER_TimeToUTCTimeArena(arena, output, input);