Imported Upstream version 1.6.1
[platform/upstream/libksba.git] / src / time.c
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 _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   *timebuf = 0;
60   for (s=buffer, n=0; n < length && digitp (s); n++, s++)
61     ;
62   if (is_utctime)
63     {
64       if ((n != 10 && n != 12) || *s != 'Z')
65         return gpg_error (GPG_ERR_INV_TIME);
66     }
67   else if ((n != 12 && n != 14) || *s != 'Z')
68     return gpg_error (GPG_ERR_INV_TIME);
69
70   s = buffer;
71   if (n==12 || n == 10 ) /* UTCTime with or without seconds. */
72     {
73       year = atoi_2 (s);
74       timebuf[0] = year < 50? '2': '1';
75       timebuf[1] = year < 50? '0': '9';
76       memcpy (timebuf+2, s, 6);
77       s += 6;
78     }
79   else
80     {
81       memcpy (timebuf, s, 8);
82       s += 8;
83     }
84   timebuf[8] = 'T';
85   if (n == 10) /* UTCTime w/0 seconds. */
86     {
87       memcpy (timebuf+9, s, 4);
88       timebuf[13] = timebuf[14] = '0';
89     }
90   else
91     {
92       memcpy (timebuf+9, s, 6);
93     }
94   timebuf[15] = 0;
95
96   return 0;
97 }
98
99
100 /* Return 0 if ATIME has the proper format (e.g. "19660205T131415"). */
101 gpg_error_t
102 _ksba_assert_time_format (const ksba_isotime_t atime)
103 {
104   int i;
105   const char *s;
106
107   if (!*atime)
108     return gpg_error (GPG_ERR_NO_VALUE);
109
110   for (s=atime, i=0; i < 8; i++, s++)
111     if (!digitp (s))
112       return gpg_error (GPG_ERR_BUG);
113   if (*s != 'T')
114       return gpg_error (GPG_ERR_BUG);
115   for (s++, i=9; i < 15; i++, s++)
116     if (!digitp (s))
117       return gpg_error (GPG_ERR_BUG);
118   if (*s)
119       return gpg_error (GPG_ERR_BUG);
120   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 _ksba_copy_time (ksba_isotime_t d, const ksba_isotime_t s)
128 {
129   if (!*s)
130     memset (d, 0, 16);
131   else if ( _ksba_assert_time_format (s) )
132     {
133       fprintf (stderr, "BUG: invalid isotime buffer\n");
134       abort ();
135     }
136   else
137     strcpy (d, s);
138 }
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 _ksba_cmp_time (const ksba_isotime_t a, const ksba_isotime_t b)
146 {
147   return strcmp (a, b);
148 }
149
150 /* Fill the TIMEBUF with the current time (UTC of course). */
151 int
152 _ksba_current_time (ksba_isotime_t timebuf)
153 {
154   time_t epoch = time (NULL);
155   struct tm *tp;
156 #ifdef HAVE_GMTIME_R
157   struct tm tmbuf;
158
159   tp = gmtime_r ( &epoch, &tmbuf);
160 #else
161   tp = gmtime ( &epoch );
162 #endif
163   return snprintf (timebuf, sizeof (ksba_isotime_t),
164                    "%04d%02d%02dT%02d%02d%02d",
165                    1900 + tp->tm_year, tp->tm_mon+1, tp->tm_mday,
166                    tp->tm_hour, tp->tm_min, tp->tm_sec);
167 }