Line data Source code
1 : /* time.c - UTCTime and GeneralizedTime helper
2 : * Copyright (C) 2001, 2003, 2005, 2012 g10 Code GmbH
3 : *
4 : * This file is part of KSBA.
5 : *
6 : * KSBA is free software; you can redistribute it and/or modify
7 : * it under the terms of either
8 : *
9 : * - the GNU Lesser General Public License as published by the Free
10 : * Software Foundation; either version 3 of the License, or (at
11 : * your option) any later version.
12 : *
13 : * or
14 : *
15 : * - the GNU General Public License as published by the Free
16 : * Software Foundation; either version 2 of the License, or (at
17 : * your option) any later version.
18 : *
19 : * or both in parallel, as here.
20 : *
21 : * KSBA is distributed in the hope that it will be useful, but WITHOUT
22 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23 : * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
24 : * License for more details.
25 : *
26 : * You should have received a copies of the GNU General Public License
27 : * and the GNU Lesser General Public License along with this program;
28 : * if not, see <http://www.gnu.org/licenses/>.
29 : */
30 :
31 : #include <config.h>
32 : #include <stdio.h>
33 : #include <stdlib.h>
34 : #include <string.h>
35 : #include <time.h>
36 : #include <assert.h>
37 :
38 : #include "util.h"
39 : #include "convert.h"
40 :
41 :
42 : /* Converts an UTCTime or GeneralizedTime to ISO format. Sets the
43 : returns string to empty on error and returns the error code. The
44 : function figures automagically the right format. fixme: Currently
45 : we only zupport Zulu time and no timezone which is sufficient for
46 : DER encoding. It IS_UTCTIME is true, the function assumes that the
47 : time is in UTCTime and thus allows to parse UTCTimes without
48 : seconds (which is legal ASN.1; however Gutmann claims that the
49 : rules changed in 1996 to always require seconds; OTOH, Dubuisson's
50 : reference book from 2001 doesn't say so). */
51 : gpg_error_t
52 18 : _ksba_asntime_to_iso (const char *buffer, size_t length, int is_utctime,
53 : ksba_isotime_t timebuf)
54 : {
55 : const char *s;
56 : size_t n;
57 : int year;
58 :
59 18 : *timebuf = 0;
60 18 : for (s=buffer, n=0; n < length && digitp (s); n++, s++)
61 : ;
62 18 : if (is_utctime)
63 : {
64 18 : if ((n != 10 && n != 12) || *s != 'Z')
65 0 : return gpg_error (GPG_ERR_INV_TIME);
66 : }
67 0 : else if ((n != 12 && n != 14) || *s != 'Z')
68 0 : return gpg_error (GPG_ERR_INV_TIME);
69 :
70 18 : s = buffer;
71 18 : if (n==12 || n == 10 ) /* UTCTime with or without seconds. */
72 : {
73 18 : year = atoi_2 (s);
74 18 : timebuf[0] = year < 50? '2': '1';
75 18 : timebuf[1] = year < 50? '0': '9';
76 18 : memcpy (timebuf+2, s, 6);
77 18 : s += 6;
78 : }
79 : else
80 : {
81 0 : memcpy (timebuf, s, 8);
82 0 : s += 8;
83 : }
84 18 : timebuf[8] = 'T';
85 18 : if (n == 10) /* UTCTime w/0 seconds. */
86 : {
87 0 : memcpy (timebuf+9, s, 4);
88 0 : timebuf[13] = timebuf[14] = '0';
89 : }
90 : else
91 : {
92 18 : memcpy (timebuf+9, s, 6);
93 : }
94 18 : timebuf[15] = 0;
95 :
96 18 : return 0;
97 : }
98 :
99 :
100 : /* Return 0 if ATIME has the proper format (e.g. "19660205T131415"). */
101 : gpg_error_t
102 12 : _ksba_assert_time_format (const ksba_isotime_t atime)
103 : {
104 : int i;
105 : const char *s;
106 :
107 12 : if (!*atime)
108 0 : return gpg_error (GPG_ERR_NO_VALUE);
109 :
110 108 : for (s=atime, i=0; i < 8; i++, s++)
111 96 : if (!digitp (s))
112 0 : return gpg_error (GPG_ERR_BUG);
113 12 : if (*s != 'T')
114 0 : return gpg_error (GPG_ERR_BUG);
115 84 : for (s++, i=9; i < 15; i++, s++)
116 72 : if (!digitp (s))
117 0 : return gpg_error (GPG_ERR_BUG);
118 12 : if (*s)
119 0 : return gpg_error (GPG_ERR_BUG);
120 12 : return 0;
121 : }
122 :
123 :
124 : /* Copy ISO time S to D. This is a function so that we can detect
125 : faulty time formats. */
126 : void
127 12 : _ksba_copy_time (ksba_isotime_t d, const ksba_isotime_t s)
128 : {
129 12 : if (!*s)
130 0 : memset (d, 0, 16);
131 12 : else if ( _ksba_assert_time_format (s) )
132 : {
133 0 : fprintf (stderr, "BUG: invalid isotime buffer\n");
134 0 : abort ();
135 : }
136 : else
137 12 : strcpy (d, s);
138 12 : }
139 :
140 :
141 : /* Compare the time strings A and B. Return 0 if they show the very
142 : same time, return 1 if A is newer than B and -1 if A is older than
143 : B. */
144 : int
145 0 : _ksba_cmp_time (const ksba_isotime_t a, const ksba_isotime_t b)
146 : {
147 0 : return strcmp (a, b);
148 : }
149 :
150 : /* Fill the TIMEBUF with the current time (UTC of course). */
151 : void
152 0 : _ksba_current_time (ksba_isotime_t timebuf)
153 : {
154 0 : time_t epoch = time (NULL);
155 : struct tm *tp;
156 : #ifdef HAVE_GMTIME_R
157 : struct tm tmbuf;
158 :
159 0 : tp = gmtime_r ( &epoch, &tmbuf);
160 : #else
161 : tp = gmtime ( &epoch );
162 : #endif
163 0 : sprintf (timebuf,"%04d%02d%02dT%02d%02d%02d",
164 0 : 1900 + tp->tm_year, tp->tm_mon+1, tp->tm_mday,
165 : tp->tm_hour, tp->tm_min, tp->tm_sec);
166 0 : }
|