2 * Copyright 1999-2016 The OpenSSL Project Authors. All Rights Reserved.
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
11 * This is an implementation of the ASN1 Time structure which is:
14 * generalTime GeneralizedTime }
19 #include "internal/cryptlib.h"
20 #include <openssl/asn1t.h>
21 #include "asn1_locl.h"
23 IMPLEMENT_ASN1_MSTRING(ASN1_TIME
, B_ASN1_TIME
)
25 IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME
)
27 ASN1_TIME
*ASN1_TIME_set(ASN1_TIME
*s
, time_t t
)
29 return ASN1_TIME_adj(s
, t
, 0, 0);
32 ASN1_TIME
*ASN1_TIME_adj(ASN1_TIME
*s
, time_t t
,
33 int offset_day
, long offset_sec
)
38 ts
= OPENSSL_gmtime(&t
, &data
);
40 ASN1err(ASN1_F_ASN1_TIME_ADJ
, ASN1_R_ERROR_GETTING_TIME
);
43 if (offset_day
|| offset_sec
) {
44 if (!OPENSSL_gmtime_adj(ts
, offset_day
, offset_sec
))
47 if ((ts
->tm_year
>= 50) && (ts
->tm_year
< 150))
48 return ASN1_UTCTIME_adj(s
, t
, offset_day
, offset_sec
);
49 return ASN1_GENERALIZEDTIME_adj(s
, t
, offset_day
, offset_sec
);
52 int ASN1_TIME_check(const ASN1_TIME
*t
)
54 if (t
->type
== V_ASN1_GENERALIZEDTIME
)
55 return ASN1_GENERALIZEDTIME_check(t
);
56 else if (t
->type
== V_ASN1_UTCTIME
)
57 return ASN1_UTCTIME_check(t
);
61 /* Convert an ASN1_TIME structure to GeneralizedTime */
62 ASN1_GENERALIZEDTIME
*ASN1_TIME_to_generalizedtime(const ASN1_TIME
*t
,
63 ASN1_GENERALIZEDTIME
**out
)
65 ASN1_GENERALIZEDTIME
*ret
= NULL
;
69 if (!ASN1_TIME_check(t
))
72 if (out
== NULL
|| *out
== NULL
) {
73 if ((ret
= ASN1_GENERALIZEDTIME_new()) == NULL
)
78 /* If already GeneralizedTime just copy across */
79 if (t
->type
== V_ASN1_GENERALIZEDTIME
) {
80 if (!ASN1_STRING_set(ret
, t
->data
, t
->length
))
86 if (!ASN1_STRING_set(ret
, NULL
, t
->length
+ 2))
88 /* ASN1_STRING_set() allocated 'len + 1' bytes. */
89 newlen
= t
->length
+ 2 + 1;
90 str
= (char *)ret
->data
;
91 /* Work out the century and prepend */
92 if (t
->data
[0] >= '5')
93 OPENSSL_strlcpy(str
, "19", newlen
);
95 OPENSSL_strlcpy(str
, "20", newlen
);
97 OPENSSL_strlcat(str
, (const char *)t
->data
, newlen
);
100 if (out
!= NULL
&& *out
== NULL
)
105 if (out
== NULL
|| *out
!= ret
)
106 ASN1_GENERALIZEDTIME_free(ret
);
111 int ASN1_TIME_set_string(ASN1_TIME
*s
, const char *str
)
115 t
.length
= strlen(str
);
116 t
.data
= (unsigned char *)str
;
119 t
.type
= V_ASN1_UTCTIME
;
121 if (!ASN1_TIME_check(&t
)) {
122 t
.type
= V_ASN1_GENERALIZEDTIME
;
123 if (!ASN1_TIME_check(&t
))
127 if (s
&& !ASN1_STRING_copy((ASN1_STRING
*)s
, (ASN1_STRING
*)&t
))
133 int ASN1_TIME_to_tm(const ASN1_TIME
*s
, struct tm
*tm
)
139 memset(tm
, 0, sizeof(*tm
));
140 if (OPENSSL_gmtime(&now_t
, tm
))
145 if (s
->type
== V_ASN1_UTCTIME
) {
146 memset(tm
, 0, sizeof(*tm
));
147 return asn1_utctime_to_tm(tm
, s
);
149 if (s
->type
== V_ASN1_GENERALIZEDTIME
) {
150 memset(tm
, 0, sizeof(*tm
));
151 return asn1_generalizedtime_to_tm(tm
, s
);
157 int ASN1_TIME_diff(int *pday
, int *psec
,
158 const ASN1_TIME
*from
, const ASN1_TIME
*to
)
160 struct tm tm_from
, tm_to
;
162 if (!ASN1_TIME_to_tm(from
, &tm_from
))
164 if (!ASN1_TIME_to_tm(to
, &tm_to
))
166 return OPENSSL_gmtime_diff(pday
, psec
, &tm_from
, &tm_to
);
169 int ASN1_TIME_print(BIO
*bp
, const ASN1_TIME
*tm
)
171 if (tm
->type
== V_ASN1_UTCTIME
)
172 return ASN1_UTCTIME_print(bp
, tm
);
173 if (tm
->type
== V_ASN1_GENERALIZEDTIME
)
174 return ASN1_GENERALIZEDTIME_print(bp
, tm
);
175 BIO_write(bp
, "Bad time value", 14);