• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "encode_values.h"
6 
7 #include "parse_values.h"
8 
9 #include <openssl/posix_time.h>
10 
11 BSSL_NAMESPACE_BEGIN
12 namespace der {
13 
14 namespace {
15 
WriteFourDigit(uint16_t value,uint8_t out[4])16 bool WriteFourDigit(uint16_t value, uint8_t out[4]) {
17   if (value >= 10000) {
18     return false;
19   }
20   out[3] = '0' + (value % 10);
21   value /= 10;
22   out[2] = '0' + (value % 10);
23   value /= 10;
24   out[1] = '0' + (value % 10);
25   value /= 10;
26   out[0] = '0' + value;
27   return true;
28 }
29 
WriteTwoDigit(uint8_t value,uint8_t out[2])30 bool WriteTwoDigit(uint8_t value, uint8_t out[2]) {
31   if (value >= 100) {
32     return false;
33   }
34   out[0] = '0' + (value / 10);
35   out[1] = '0' + (value % 10);
36   return true;
37 }
38 
39 }  // namespace
40 
EncodePosixTimeAsGeneralizedTime(int64_t posix_time,GeneralizedTime * generalized_time)41 bool EncodePosixTimeAsGeneralizedTime(int64_t posix_time,
42                                       GeneralizedTime *generalized_time) {
43   struct tm tmp_tm;
44   if (!OPENSSL_posix_to_tm(posix_time, &tmp_tm)) {
45     return false;
46   }
47 
48   generalized_time->year = tmp_tm.tm_year + 1900;
49   generalized_time->month = tmp_tm.tm_mon + 1;
50   generalized_time->day = tmp_tm.tm_mday;
51   generalized_time->hours = tmp_tm.tm_hour;
52   generalized_time->minutes = tmp_tm.tm_min;
53   generalized_time->seconds = tmp_tm.tm_sec;
54   return true;
55 }
56 
GeneralizedTimeToPosixTime(const der::GeneralizedTime & generalized,int64_t * result)57 bool GeneralizedTimeToPosixTime(const der::GeneralizedTime &generalized,
58                                 int64_t *result) {
59   struct tm tmp_tm;
60   tmp_tm.tm_year = generalized.year - 1900;
61   tmp_tm.tm_mon = generalized.month - 1;
62   tmp_tm.tm_mday = generalized.day;
63   tmp_tm.tm_hour = generalized.hours;
64   tmp_tm.tm_min = generalized.minutes;
65   tmp_tm.tm_sec = generalized.seconds;
66   // BoringSSL POSIX time, like POSIX itself, does not support leap seconds.
67   // Collapse to previous second.
68   if (tmp_tm.tm_sec == 60) {
69     tmp_tm.tm_sec = 59;
70   }
71   return OPENSSL_tm_to_posix(&tmp_tm, result);
72 }
73 
EncodeGeneralizedTime(const GeneralizedTime & time,uint8_t out[kGeneralizedTimeLength])74 bool EncodeGeneralizedTime(const GeneralizedTime &time,
75                            uint8_t out[kGeneralizedTimeLength]) {
76   if (!WriteFourDigit(time.year, out) || !WriteTwoDigit(time.month, out + 4) ||
77       !WriteTwoDigit(time.day, out + 6) ||
78       !WriteTwoDigit(time.hours, out + 8) ||
79       !WriteTwoDigit(time.minutes, out + 10) ||
80       !WriteTwoDigit(time.seconds, out + 12)) {
81     return false;
82   }
83   out[14] = 'Z';
84   return true;
85 }
86 
EncodeUTCTime(const GeneralizedTime & time,uint8_t out[kUTCTimeLength])87 bool EncodeUTCTime(const GeneralizedTime &time, uint8_t out[kUTCTimeLength]) {
88   if (!time.InUTCTimeRange()) {
89     return false;
90   }
91 
92   uint16_t year = time.year - 1900;
93   if (year >= 100) {
94     year -= 100;
95   }
96 
97   if (!WriteTwoDigit(year, out) || !WriteTwoDigit(time.month, out + 2) ||
98       !WriteTwoDigit(time.day, out + 4) ||
99       !WriteTwoDigit(time.hours, out + 6) ||
100       !WriteTwoDigit(time.minutes, out + 8) ||
101       !WriteTwoDigit(time.seconds, out + 10)) {
102     return false;
103   }
104   out[12] = 'Z';
105   return true;
106 }
107 
108 }  // namespace der
109 BSSL_NAMESPACE_END
110