1 /* gztime.c --- Convertion functions for GeneralizedTime.
2 * Copyright (C) 2002-2013 Simon Josefsson
3 *
4 * This file is part of Shishi.
5 *
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
20 *
21 */
22
23 #include "internal.h"
24
25 /* Get xtime. */
26 #include "utils.h"
27
28 /**
29 * shishi_generalize_time:
30 * @handle: shishi handle as allocated by shishi_init().
31 * @t: C time to convert.
32 *
33 * Convert C time to KerberosTime. The string must not be deallocate
34 * by caller.
35 *
36 * Return value: Return a KerberosTime time string corresponding to C time t.
37 **/
38 const char *
shishi_generalize_time(Shishi * handle,time_t t)39 shishi_generalize_time (Shishi * handle, time_t t)
40 {
41 struct tm *tm;
42
43 tm = gmtime (&t);
44 strftime (handle->gztime_buf, sizeof (handle->gztime_buf),
45 "%Y%m%d%H%M%SZ", tm);
46
47 return handle->gztime_buf;
48 }
49
50 /**
51 * shishi_generalize_now:
52 * @handle: shishi handle as allocated by shishi_init().
53 *
54 * Convert current time to KerberosTime. The string must not be
55 * deallocate by caller.
56 *
57 * Return value: Return a KerberosTime time string corresponding to
58 * current time.
59 **/
60 const char *
shishi_generalize_now(Shishi * handle)61 shishi_generalize_now (Shishi * handle)
62 {
63 time_t t = xtime (NULL);
64
65 return shishi_generalize_time (handle, t);
66 }
67
68 /**
69 * shishi_generalize_ctime:
70 * @handle: shishi handle as allocated by shishi_init().
71 * @t: KerberosTime to convert.
72 *
73 * Convert KerberosTime to C time.
74 *
75 * Return value: Returns C time corresponding to KerberosTime t.
76 **/
77 time_t
shishi_generalize_ctime(Shishi * handle,const char * t)78 shishi_generalize_ctime (Shishi * handle, const char *t)
79 {
80 struct tm tm;
81 time_t ct;
82
83 memset (&tm, 0, sizeof (tm));
84
85 sscanf (t, "%4u%2u%2u%2u%2u%2uZ",
86 &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
87 &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
88 tm.tm_year -= 1900;
89 tm.tm_mon--;
90
91 ct = timegm (&tm);
92
93 return ct;
94 }
95
96 /**
97 * shishi_time:
98 * @handle: shishi handle as allocated by shishi_init().
99 * @node: ASN.1 node to get time from.
100 * @field: Name of field in ASN.1 node to get time from.
101 * @t: newly allocated output array with zero terminated time string.
102 *
103 * Extract time from ASN.1 structure.
104 *
105 * Return value: Returns SHISHI_OK iff successful.
106 **/
107 int
shishi_time(Shishi * handle,Shishi_asn1 node,const char * field,char ** t)108 shishi_time (Shishi * handle, Shishi_asn1 node, const char *field, char **t)
109 {
110 size_t len;
111 int res;
112
113 len = SHISHI_GENERALIZEDTIME_LENGTH + 1;
114 *t = xmalloc (len);
115
116 res = shishi_asn1_read_inline (handle, node, field, *t, &len);
117 if (res != SHISHI_OK)
118 return res;
119
120 if (len <= SHISHI_GENERALIZEDTIME_LENGTH)
121 {
122 shishi_error_printf (handle, "Read time too short (%s)", *t);
123 return SHISHI_ASN1_ERROR;
124 }
125
126 (*t)[SHISHI_GENERALIZEDTIME_LENGTH] = '\0';
127
128 return SHISHI_OK;
129 }
130
131 /**
132 * shishi_ctime:
133 * @handle: shishi handle as allocated by shishi_init().
134 * @node: ASN.1 variable to read field from.
135 * @field: name of field in @node to read.
136 * @t: pointer to time field to set.
137 *
138 * Extract time from ASN.1 structure.
139 *
140 * Return value: Returns SHISHI_OK if successful,
141 * SHISHI_ASN1_NO_ELEMENT if the element do not exist,
142 * SHISHI_ASN1_NO_VALUE if the field has no value, ot
143 * SHISHI_ASN1_ERROR otherwise.
144 **/
145 int
shishi_ctime(Shishi * handle,Shishi_asn1 node,const char * field,time_t * t)146 shishi_ctime (Shishi * handle, Shishi_asn1 node, const char *field,
147 time_t * t)
148 {
149 char str[SHISHI_GENERALIZEDTIME_LENGTH + 1];
150 size_t len = sizeof (str);
151 int rc;
152
153 rc = shishi_asn1_read_inline (handle, node, field, str, &len);
154 if (rc != SHISHI_OK)
155 return rc;
156
157 *t = shishi_generalize_ctime (handle, str);
158
159 return SHISHI_OK;
160 }
161