• 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/time.h>
10 
11 namespace bssl::der {
12 
13 namespace {
14 
WriteFourDigit(uint16_t value,uint8_t out[4])15 bool WriteFourDigit(uint16_t value, uint8_t out[4]) {
16   if (value >= 10000)
17     return false;
18   out[3] = '0' + (value % 10);
19   value /= 10;
20   out[2] = '0' + (value % 10);
21   value /= 10;
22   out[1] = '0' + (value % 10);
23   value /= 10;
24   out[0] = '0' + value;
25   return true;
26 }
27 
WriteTwoDigit(uint8_t value,uint8_t out[2])28 bool WriteTwoDigit(uint8_t value, uint8_t out[2]) {
29   if (value >= 100)
30     return false;
31   out[0] = '0' + (value / 10);
32   out[1] = '0' + (value % 10);
33   return true;
34 }
35 
36 }  // namespace
37 
EncodePosixTimeAsGeneralizedTime(int64_t posix_time,GeneralizedTime * generalized_time)38 bool EncodePosixTimeAsGeneralizedTime(int64_t posix_time,
39                                       GeneralizedTime* generalized_time) {
40   struct tm tmp_tm;
41   if (!OPENSSL_posix_to_tm(posix_time, &tmp_tm)) {
42     return false;
43   }
44 
45   generalized_time->year = tmp_tm.tm_year + 1900;
46   generalized_time->month = tmp_tm.tm_mon + 1;
47   generalized_time->day = tmp_tm.tm_mday;
48   generalized_time->hours = tmp_tm.tm_hour;
49   generalized_time->minutes = tmp_tm.tm_min;
50   generalized_time->seconds = tmp_tm.tm_sec;
51   return true;
52 }
53 
GeneralizedTimeToPosixTime(const der::GeneralizedTime & generalized,int64_t * result)54 bool GeneralizedTimeToPosixTime(const der::GeneralizedTime& generalized,
55                                 int64_t* result) {
56   struct tm tmp_tm;
57   tmp_tm.tm_year = generalized.year - 1900;
58   tmp_tm.tm_mon = generalized.month - 1;
59   tmp_tm.tm_mday = generalized.day;
60   tmp_tm.tm_hour = generalized.hours;
61   tmp_tm.tm_min = generalized.minutes;
62   tmp_tm.tm_sec = generalized.seconds;
63   // BoringSSL POSIX time, like POSIX itself, does not support leap seconds.
64   // Collapse to previous second.
65   if (tmp_tm.tm_sec == 60) {
66     tmp_tm.tm_sec = 59;
67   }
68   return OPENSSL_tm_to_posix(&tmp_tm, result);
69 }
70 
EncodeGeneralizedTime(const GeneralizedTime & time,uint8_t out[kGeneralizedTimeLength])71 bool EncodeGeneralizedTime(const GeneralizedTime& time,
72                            uint8_t out[kGeneralizedTimeLength]) {
73   if (!WriteFourDigit(time.year, out) || !WriteTwoDigit(time.month, out + 4) ||
74       !WriteTwoDigit(time.day, out + 6) ||
75       !WriteTwoDigit(time.hours, out + 8) ||
76       !WriteTwoDigit(time.minutes, out + 10) ||
77       !WriteTwoDigit(time.seconds, out + 12)) {
78     return false;
79   }
80   out[14] = 'Z';
81   return true;
82 }
83 
EncodeUTCTime(const GeneralizedTime & time,uint8_t out[kUTCTimeLength])84 bool EncodeUTCTime(const GeneralizedTime& time, uint8_t out[kUTCTimeLength]) {
85   if (!time.InUTCTimeRange())
86     return false;
87 
88   uint16_t year = time.year - 1900;
89   if (year >= 100)
90     year -= 100;
91 
92   if (!WriteTwoDigit(year, out) || !WriteTwoDigit(time.month, out + 2) ||
93       !WriteTwoDigit(time.day, out + 4) ||
94       !WriteTwoDigit(time.hours, out + 6) ||
95       !WriteTwoDigit(time.minutes, out + 8) ||
96       !WriteTwoDigit(time.seconds, out + 10)) {
97     return false;
98   }
99   out[12] = 'Z';
100   return true;
101 }
102 
103 }  // namespace bssl::der
104