]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/asn1/a_utctm.c
2a864180e3e9a12525669602acbdad23f290cfd2
[thirdparty/openssl.git] / crypto / asn1 / a_utctm.c
1 /*
2 * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <stdio.h>
11 #include <time.h>
12 #include "internal/cryptlib.h"
13 #include <openssl/asn1.h>
14 #include "asn1_locl.h"
15
16 int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
17 {
18 /* wrapper around ans1_time_to_tm */
19 if (d->type != V_ASN1_UTCTIME)
20 return 0;
21 return asn1_time_to_tm(tm, d);
22 }
23
24 int ASN1_UTCTIME_check(const ASN1_UTCTIME *d)
25 {
26 return asn1_utctime_to_tm(NULL, d);
27 }
28
29 int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
30 {
31 ASN1_UTCTIME t;
32
33 t.type = V_ASN1_UTCTIME;
34 t.length = strlen(str);
35 t.data = (unsigned char *)str;
36 t.flags = 0;
37
38 if (ASN1_UTCTIME_check(&t)) {
39 if (s != NULL) {
40 if (!ASN1_STRING_set((ASN1_STRING *)s, str, t.length))
41 return 0;
42 s->type = V_ASN1_UTCTIME;
43 }
44 return 1;
45 }
46 return 0;
47 }
48
49 ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
50 {
51 return ASN1_UTCTIME_adj(s, t, 0, 0);
52 }
53
54 ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
55 int offset_day, long offset_sec)
56 {
57 char *p;
58 struct tm *ts;
59 struct tm data;
60 const size_t len = 20;
61 int free_s = 0;
62
63 if (s == NULL) {
64 s = ASN1_UTCTIME_new();
65 if (s == NULL)
66 goto err;
67 free_s = 1;
68 }
69
70 ts = OPENSSL_gmtime(&t, &data);
71 if (ts == NULL)
72 goto err;
73
74 if (offset_day || offset_sec) {
75 if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
76 goto err;
77 }
78
79 if ((ts->tm_year < 50) || (ts->tm_year >= 150))
80 goto err;
81
82 p = (char *)s->data;
83 if ((p == NULL) || ((size_t)s->length < len)) {
84 p = OPENSSL_malloc(len);
85 if (p == NULL) {
86 ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE);
87 goto err;
88 }
89 OPENSSL_free(s->data);
90 s->data = (unsigned char *)p;
91 }
92
93 s->length = BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ",
94 ts->tm_year % 100, ts->tm_mon + 1, ts->tm_mday,
95 ts->tm_hour, ts->tm_min, ts->tm_sec);
96 s->type = V_ASN1_UTCTIME;
97 #ifdef CHARSET_EBCDIC_not
98 ebcdic2ascii(s->data, s->data, s->length);
99 #endif
100 return s;
101 err:
102 if (free_s)
103 ASN1_UTCTIME_free(s);
104 return NULL;
105 }
106
107 int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
108 {
109 struct tm stm, ttm;
110 int day, sec;
111
112 if (!asn1_utctime_to_tm(&stm, s))
113 return -2;
114
115 if (!OPENSSL_gmtime(&t, &ttm))
116 return -2;
117
118 if (!OPENSSL_gmtime_diff(&day, &sec, &ttm, &stm))
119 return -2;
120
121 if (day > 0)
122 return 1;
123 if (day < 0)
124 return -1;
125 if (sec > 0)
126 return 1;
127 if (sec < 0)
128 return -1;
129 return 0;
130 }
131
132 int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
133 {
134 const char *v;
135 int gmt = 0;
136 int i;
137 int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
138
139 i = tm->length;
140 v = (const char *)tm->data;
141
142 if (i < 10)
143 goto err;
144 if (v[i - 1] == 'Z')
145 gmt = 1;
146 for (i = 0; i < 10; i++)
147 if ((v[i] > '9') || (v[i] < '0'))
148 goto err;
149 y = (v[0] - '0') * 10 + (v[1] - '0');
150 if (y < 50)
151 y += 100;
152 M = (v[2] - '0') * 10 + (v[3] - '0');
153 if ((M > 12) || (M < 1))
154 goto err;
155 d = (v[4] - '0') * 10 + (v[5] - '0');
156 h = (v[6] - '0') * 10 + (v[7] - '0');
157 m = (v[8] - '0') * 10 + (v[9] - '0');
158 if (tm->length >= 12 &&
159 (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
160 s = (v[10] - '0') * 10 + (v[11] - '0');
161
162 if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
163 _asn1_mon[M - 1], d, h, m, s, y + 1900,
164 (gmt) ? " GMT" : "") <= 0)
165 return 0;
166 return 1;
167 err:
168 BIO_write(bp, "Bad time value", 14);
169 return 0;
170 }