98c80f3e4a541ebd74d0928a86d748e1b4862184
[platform/core/security/cert-svc.git] / vcore / src / vcore / TimeConversion.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 #include <vcore/TimeConversion.h>
17
18 #include <string.h>
19
20 #include <dpl/log/log.h>
21 #include <dpl/assert.h>
22
23 namespace ValidationCore {
24
25 int asn1TimeToTimeT(ASN1_TIME *t, time_t *res)
26 {
27     struct tm tm;
28     int offset;
29
30     (*res) = 0;
31     if (!ASN1_TIME_check(t)) {
32         return -1;
33     }
34
35     memset(&tm, 0, sizeof(tm));
36
37 #define g2(p) (((p)[0] - '0') * 10 + (p)[1] - '0')
38     if (t->type == V_ASN1_UTCTIME) {
39         Assert(t->length > 12);
40
41         /*   this code is copied from OpenSSL asn1/a_utctm.c file */
42         tm.tm_year = g2(t->data);
43         if (tm.tm_year < 50) {
44             tm.tm_year += 100;
45         }
46         tm.tm_mon = g2(t->data + 2) - 1;
47         tm.tm_mday = g2(t->data + 4);
48         tm.tm_hour = g2(t->data + 6);
49         tm.tm_min = g2(t->data + 8);
50         tm.tm_sec = g2(t->data + 10);
51         if (t->data[12] == 'Z') {
52             offset = 0;
53         } else {
54             Assert(t->length > 16);
55
56             offset = g2(t->data + 13) * 60 + g2(t->data + 15);
57             if (t->data[12] == '-') {
58                 offset = -offset;
59             }
60         }
61         tm.tm_isdst = -1;
62     } else {
63         Assert(t->length > 14);
64
65         tm.tm_year = g2(t->data) * 100 + g2(t->data + 2);
66         tm.tm_mon = g2(t->data + 4) - 1;
67         tm.tm_mday = g2(t->data + 6);
68         tm.tm_hour = g2(t->data + 8);
69         tm.tm_min = g2(t->data + 10);
70         tm.tm_sec = g2(t->data + 12);
71         if (t->data[14] == 'Z') {
72             offset = 0;
73         } else {
74             Assert(t->length > 18);
75
76             offset = g2(t->data + 15) * 60 + g2(t->data + 17);
77             if (t->data[14] == '-') {
78                 offset = -offset;
79             }
80         }
81         tm.tm_isdst = -1;
82     }
83 #undef g2
84     (*res) = timegm(&tm) - offset * 60;
85     return 0;
86 }
87
88 int asn1GeneralizedTimeToTimeT(ASN1_GENERALIZEDTIME *tm, time_t *res)
89 {
90     /*
91      * This code is based on following assumption:
92      * from openssl/a_gentm.c:
93      * GENERALIZEDTIME is similar to UTCTIME except the year is
94      * represented as YYYY. This stuff treats everything as a two digit
95      * field so make first two fields 00 to 99
96      */
97     const int DATE_BUFFER_LENGTH = 15; // YYYYMMDDHHMMSSZ
98
99     if (NULL == res || NULL == tm) {
100         LogError("NULL pointer");
101         return -1;
102     }
103
104     if (DATE_BUFFER_LENGTH != tm->length || NULL == tm->data) {
105         LogError("Invalid ASN1_GENERALIZEDTIME");
106         return -1;
107     }
108
109     struct tm time_s;
110     if (sscanf ((char*)tm->data,
111                 "%4d%2d%2d%2d%2d%2d",
112                 &time_s.tm_year,
113                 &time_s.tm_mon,
114                 &time_s.tm_mday,
115                 &time_s.tm_hour,
116                 &time_s.tm_min,
117                 &time_s.tm_sec) < 6)
118     {
119         LogError("Could not extract time data from ASN1_GENERALIZEDTIME");
120         return -1;
121     }
122
123     time_s.tm_year -= 1900;
124     time_s.tm_mon -= 1;
125     time_s.tm_isdst = 0;   // UTC
126     time_s.tm_gmtoff = 0;  // UTC
127     time_s.tm_zone = NULL; // UTC
128
129     *res = mktime(&time_s);
130
131     return 0;
132 }
133
134 } // namespace ValidationCore
135