1 // Copyright 2021 The Chromium Authors. All rights reserved.
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 "quiche_platform_impl/quiche_time_utils_impl.h"
6 
7 #include "openssl/time.h"
8 
9 namespace quiche {
10 
11 // Chrome converts broken out UTC times for certificates to unix times using
12 // the BoringSSL routines.
QuicheUtcDateTimeToUnixSecondsImpl(int year,int month,int day,int hour,int minute,int second)13 std::optional<int64_t> QuicheUtcDateTimeToUnixSecondsImpl(int year, int month,
14                                                           int day, int hour,
15                                                           int minute,
16                                                           int second) {
17   struct tm tmp_tm;
18   tmp_tm.tm_year = year - 1900;
19   tmp_tm.tm_mon = month - 1;
20   tmp_tm.tm_mday = day;
21   tmp_tm.tm_hour = hour;
22   tmp_tm.tm_min = minute;
23   tmp_tm.tm_sec = second;
24   // BoringSSL POSIX time, like POSIX itself, does not support leap seconds.
25   bool leap_second = false;
26   if (tmp_tm.tm_sec == 60) {
27     tmp_tm.tm_sec = 59;
28     leap_second = true;
29   }
30   int64_t result;
31   if (!OPENSSL_tm_to_posix(&tmp_tm, &result)) {
32     return std::nullopt;
33   }
34   // Our desired behaviour is to return the following second for a leap second
35   // assuming it is a valid time.
36   if (leap_second) {
37     if (!OPENSSL_posix_to_tm(result + 1, &tmp_tm)) {
38       return std::nullopt;
39     }
40     result++;
41   }
42   return result;
43 }
44 
45 }  // namespace quiche
46