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