Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge BoringSSL through 20c93abd47726624ab3e479466078f7e63f081f7 #2264

Merged
merged 44 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6855f30
Remove unused files from pki
davidben Jan 30, 2024
56d3ad9
Require SSE2 when targetting 32-bit x86
davidben Jan 27, 2024
608becc
Fix strict aliasing issues with DES_cblock
davidben Jan 20, 2024
10a2132
Create a new NameConstraints constructor that takes in an already con…
hubertchao Feb 1, 2024
79123ca
Ensure additions in this call can't overflow.
Feb 3, 2024
34b51fa
Avoid conversion overflow from struct tm.
Feb 6, 2024
8ff5add
Tighten up the warning about RSAES-PKCS1-v1_5
davidben Feb 8, 2024
fbb4133
Add SSL_get0_chain method
gredner Feb 8, 2024
5dd15f3
Expose OPENSSL_timegm in posix_time.h
Feb 8, 2024
10605c0
Minor formatting fixes
davidben Feb 9, 2024
71c5896
Add functions to convert from Span<const uint8> and std::string_view
davidben Jan 30, 2024
c39e6cd
Use uint64_t for num_read and num_write in BIO
davidben Feb 10, 2024
324db64
Allow the delegate to indicate it wishes to accept PreCertificates
Jan 25, 2024
b1d34cb
Add public API for a certificate.
Nov 23, 2023
80b08df
Don't assume that Fiat assembly is available on Windows.
Feb 13, 2024
58a318e
Make ContainsError look only for Errors, not Warnings.
Feb 13, 2024
48b8146
Move signature_verify_cache.h to openssl/pki as public api
Dec 12, 2023
8049f26
Remove unused include in now public header
davidben Feb 14, 2024
38d17d3
Mark ASN1_STRFLAGS_* and XN_FLAG_* with the right type
davidben Feb 14, 2024
ba5eb62
Add X509_STORE_get1_objects
davidben Jan 25, 2024
5a1a5fb
Remove X509_TRUST_DEFAULT
davidben Dec 26, 2023
1b08502
Unexport most of X509_TRUST and X509_PURPOSE and simplify
davidben Dec 26, 2023
8e6a26d
Merge X509_PURPOSE/X509_TRUST IDs and indices
davidben Dec 26, 2023
a028a23
Document X509_V_FLAG_*
davidben Dec 26, 2023
cb47fdc
Switch to bindgen's static inline support
davidben Feb 14, 2024
22c5477
Include verify_unittest files in PKI_TEST_DATA
agl Feb 14, 2024
9c20a89
Guard C++ headers.
agl Feb 14, 2024
d7f5e18
Work around bindgen bug around constants
davidben Feb 14, 2024
2a5db68
Remove pki/tag.h
davidben Feb 7, 2024
0568c2c
Rewrite the warning about X509_AUX
davidben Dec 28, 2023
c528061
Allow a C++ runtime dependency in libssl
davidben Feb 15, 2024
46ff4f7
Unexport DIST_POINT_set_dpname
davidben Jan 1, 2024
ea003bd
Add x509.h to doc.config
davidben Jan 25, 2024
23824fa
bssl-crypto: remove unused code.
Feb 16, 2024
99e8c6e
Add a no-op OPENSSL_INIT_NO_ATEXIT
davidben Feb 16, 2024
da3b372
Don't report libpki headers as part of libcrypto
davidben Feb 18, 2024
48b0edf
Update delegated credentials to the final RFC
davidben Feb 11, 2024
20c93ab
Remove OPENSSL_IA32_SSE2 checks in x86 perlasm
davidben Jan 27, 2024
5ab7e72
ignore BoringSSL 6855f30.
briansmith Jan 21, 2025
5895ed0
Skip BoringSSL 56d3ad9.
briansmith Jan 21, 2025
4033766
Ignore BoringSSL 608becc..b1d34cb.
briansmith Jan 21, 2025
990b092
Merge BoringSSL 80b08df: Don't assume that Fiat assembly is available…
briansmith Jan 21, 2025
7fb4201
Ignore BoringSSL 58a318e..48b0edf.
briansmith Jan 21, 2025
ee7f382
Merge BoringSSL 20c93ab: Remove OPENSSL_IA32_SSE2 checks in x86 perlasm.
briansmith Jan 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Avoid conversion overflow from struct tm.
See discussion in
https://boringssl-review.googlesource.com/c/boringssl/+/65967/comment/4b0fb2a6_78bfab3a/

struct tm is defined with tm_ values as all ints.

Conversion inside this code is all bounds checked around valid
times and can't overflow, but because struct tm uses 1 based months
and 1900 based years, we need to modify the input values when
converting a struct tm.

Rather than do awkward bounds checks, just accept an int64_t on
input and we don't have to care.

OPENSSL_gmtime_adj gains checks to ensure the cumulative days
and seconds values passed in may not overflow.

While we are here we also ensure that OPENSSL_gmtime_adj does
not modify the output struct tm in the failure case.

Also while we are here, just make the offset_seconds value of
OPENSSL_gmtime_adj an int64_t - because long was never the
correct type.

Add tests for all this.

Change-Id: I40ac019c4274b5388c97736cf85cede951d8b7ae
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/66047
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
Auto-Submit: Bob Beck <bbe@google.com>
  • Loading branch information
Bob Beck authored and Boringssl LUCI CQ committed Feb 7, 2024
commit 34b51faf3a58fe36e3ab1db99a2a441d0f69c754
85 changes: 83 additions & 2 deletions crypto/asn1/asn1_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1162,8 +1162,8 @@ TEST(ASN1Test, AdjTime) {
struct tm tm1, tm2;
int days, secs;

OPENSSL_posix_to_tm(0, &tm1);
OPENSSL_posix_to_tm(0, &tm2);
EXPECT_TRUE(OPENSSL_posix_to_tm(0, &tm1));
EXPECT_TRUE(OPENSSL_posix_to_tm(0, &tm2));
// Test values that are too large and should be rejected.
EXPECT_FALSE(OPENSSL_gmtime_adj(&tm1, INT_MIN, INT_MIN));
EXPECT_FALSE(OPENSSL_gmtime_adj(&tm1, INT_MAX, INT_MAX));
Expand Down Expand Up @@ -2475,6 +2475,87 @@ TEST(ASN1Test, LargeString) {
#endif
}

static auto TimeToTuple(const tm &t) {
return std::make_tuple(t.tm_year, t.tm_mon, t.tm_mday, t.tm_hour, t.tm_min,
t.tm_sec);
}

TEST(ASN1Test, TimeOverflow) {
// Input time is out of range and may overflow internal calculations to shift
// |tm_year| and |tm_mon| to a more normal value.
tm overflow_year = {};
overflow_year.tm_year = INT_MAX - 1899;
overflow_year.tm_mday = 1;
tm overflow_month = {};
overflow_month.tm_mon = INT_MAX;
overflow_month.tm_mday = 1;
int64_t posix_u64;
EXPECT_FALSE(OPENSSL_tm_to_posix(&overflow_year, &posix_u64));
EXPECT_FALSE(OPENSSL_tm_to_posix(&overflow_month, &posix_u64));
time_t posix;
EXPECT_FALSE(OPENSSL_timegm(&overflow_year, &posix));
EXPECT_FALSE(OPENSSL_timegm(&overflow_month, &posix));
EXPECT_FALSE(
OPENSSL_gmtime_adj(&overflow_year, /*offset_day=*/0, /*offset_sec=*/0));
EXPECT_FALSE(
OPENSSL_gmtime_adj(&overflow_month, /*offset_day=*/0, /*offset_sec=*/0));
int days, secs;
EXPECT_FALSE(
OPENSSL_gmtime_diff(&days, &secs, &overflow_year, &overflow_year));
EXPECT_FALSE(
OPENSSL_gmtime_diff(&days, &secs, &overflow_month, &overflow_month));

// Input time is in range, but even adding one second puts it out of range.
tm max_time = {};
max_time.tm_year = 9999 - 1900;
max_time.tm_mon = 12 - 1;
max_time.tm_mday = 31;
max_time.tm_hour = 23;
max_time.tm_min = 59;
max_time.tm_sec = 59;
tm copy = max_time;
EXPECT_TRUE(OPENSSL_gmtime_adj(&copy, /*offset_day=*/0, /*offset_sec=*/0));
EXPECT_EQ(TimeToTuple(copy), TimeToTuple(max_time));
EXPECT_FALSE(OPENSSL_gmtime_adj(&copy, /*offset_day=*/0, /*offset_sec=*/1));

// Likewise for the earliest representable time.
tm min_time = {};
min_time.tm_year = 0 - 1900;
min_time.tm_mon = 1 - 1;
min_time.tm_mday = 1;
min_time.tm_hour = 0;
min_time.tm_min = 0;
min_time.tm_sec = 0;
copy = min_time;
EXPECT_TRUE(OPENSSL_gmtime_adj(&copy, /*offset_day=*/0, /*offset_sec=*/0));
EXPECT_EQ(TimeToTuple(copy), TimeToTuple(min_time));
EXPECT_FALSE(OPENSSL_gmtime_adj(&copy, /*offset_day=*/0, /*offset_sec=*/-1));

// Test we can offset between the minimum and maximum times.
const int64_t kValidTimeRange = 315569519999;
copy = min_time;
EXPECT_TRUE(OPENSSL_gmtime_adj(&copy, /*offset_day=*/0, kValidTimeRange));
EXPECT_EQ(TimeToTuple(copy), TimeToTuple(max_time));
EXPECT_TRUE(OPENSSL_gmtime_adj(&copy, /*offset_day=*/0, -kValidTimeRange));
EXPECT_EQ(TimeToTuple(copy), TimeToTuple(min_time));

// The second offset may even exceed kValidTimeRange if it is canceled out by
// offset_day.
EXPECT_TRUE(OPENSSL_gmtime_adj(&copy, /*offset_day=*/-1,
kValidTimeRange + 24 * 3600));
EXPECT_EQ(TimeToTuple(copy), TimeToTuple(max_time));
EXPECT_TRUE(OPENSSL_gmtime_adj(&copy, /*offset_day=*/1,
-kValidTimeRange - 24 * 3600));
EXPECT_EQ(TimeToTuple(copy), TimeToTuple(min_time));

// Make sure the internal calculations for |OPENSSL_gmtime_adj| stay in
// bounds.
copy = max_time;
EXPECT_FALSE(OPENSSL_gmtime_adj(&copy, INT_MAX, LONG_MAX));
copy = min_time;
EXPECT_FALSE(OPENSSL_gmtime_adj(&copy, INT_MIN, LONG_MIN));
}

// The ASN.1 macros do not work on Windows shared library builds, where usage of
// |OPENSSL_EXPORT| is a bit stricter.
#if !defined(OPENSSL_WINDOWS) || !defined(BORINGSSL_SHARED_LIBRARY)
Expand Down
2 changes: 1 addition & 1 deletion crypto/asn1/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ OPENSSL_EXPORT int OPENSSL_timegm(const struct tm *tm, time_t *out);
// must be in the range of year 0000 to 9999 both before and after the update or
// a failure will be returned.
OPENSSL_EXPORT int OPENSSL_gmtime_adj(struct tm *tm, int offset_day,
long offset_sec);
int64_t offset_sec);

// OPENSSL_gmtime_diff calculates the difference between |from| and |to|. It
// returns one, and outputs the difference as a number of days and seconds in
Expand Down
94 changes: 50 additions & 44 deletions crypto/asn1/posix_time.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
#include "internal.h"

#define SECS_PER_HOUR (60 * 60)
#define SECS_PER_DAY (24 * SECS_PER_HOUR)
#define SECS_PER_DAY (INT64_C(24) * SECS_PER_HOUR)


// Is a year/month/day combination valid, in the range from year 0000
// to 9999?
static int is_valid_date(int year, int month, int day) {
static int is_valid_date(int64_t year, int64_t month, int64_t day) {
if (day < 1 || month < 1 || year < 0 || year > 9999) {
return 0;
}
Expand Down Expand Up @@ -62,25 +62,30 @@ static int is_valid_date(int year, int month, int day) {

// Is a time valid? Leap seconds of 60 are not considered valid, as
// the POSIX time in seconds does not include them.
static int is_valid_time(int hours, int minutes, int seconds) {
static int is_valid_time(int64_t hours, int64_t minutes, int64_t seconds) {
if (hours < 0 || minutes < 0 || seconds < 0 || hours > 23 || minutes > 59 ||
seconds > 59) {
return 0;
}
return 1;
}

// Is a int64 time representing a time within our expected range?
static int is_valid_epoch_time(int64_t time) {
// 0000-01-01 00:00:00 UTC to 9999-12-31 23:59:59 UTC
return (int64_t)-62167219200 <= time && time <= (int64_t)253402300799;
// 0000-01-01 00:00:00 UTC
#define MIN_POSIX_TIME INT64_C(-62167219200)
// 9999-12-31 23:59:59 UTC
#define MAX_POSIX_TIME INT64_C(253402300799)

// Is an int64 time within our expected range?
static int is_valid_posix_time(int64_t time) {
return MIN_POSIX_TIME <= time && time <= MAX_POSIX_TIME;
}

// Inspired by algorithms presented in
// https://howardhinnant.github.io/date_algorithms.html
// (Public Domain)
static int posix_time_from_utc(int year, int month, int day, int hours,
int minutes, int seconds, int64_t *out_time) {
static int posix_time_from_utc(int64_t year, int64_t month, int64_t day,
int64_t hours, int64_t minutes, int64_t seconds,
int64_t *out_time) {
if (!is_valid_date(year, month, day) ||
!is_valid_time(hours, minutes, seconds)) {
return 0;
Expand Down Expand Up @@ -108,7 +113,7 @@ static int posix_time_from_utc(int year, int month, int day, int hours,
static int utc_from_posix_time(int64_t time, int *out_year, int *out_month,
int *out_day, int *out_hours, int *out_minutes,
int *out_seconds) {
if (!is_valid_epoch_time(time)) {
if (!is_valid_posix_time(time)) {
return 0;
}
int64_t days = time / SECS_PER_DAY;
Expand Down Expand Up @@ -143,24 +148,21 @@ static int utc_from_posix_time(int64_t time, int *out_year, int *out_month,
}

int OPENSSL_tm_to_posix(const struct tm *tm, int64_t *out) {
// Ensure the additions below do not overflow.
if (tm->tm_year > 9999 || tm->tm_mon > 12) {
return 0;
}

return posix_time_from_utc(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, out);
return posix_time_from_utc(tm->tm_year + INT64_C(1900),
tm->tm_mon + INT64_C(1), tm->tm_mday, tm->tm_hour,
tm->tm_min, tm->tm_sec, out);
}

int OPENSSL_posix_to_tm(int64_t time, struct tm *out_tm) {
memset(out_tm, 0, sizeof(struct tm));
if (!utc_from_posix_time(time, &out_tm->tm_year, &out_tm->tm_mon,
&out_tm->tm_mday, &out_tm->tm_hour, &out_tm->tm_min,
&out_tm->tm_sec)) {
struct tm tmp_tm = {0};
if (!utc_from_posix_time(time, &tmp_tm.tm_year, &tmp_tm.tm_mon,
&tmp_tm.tm_mday, &tmp_tm.tm_hour, &tmp_tm.tm_min,
&tmp_tm.tm_sec)) {
return 0;
}
out_tm->tm_year -= 1900;
out_tm->tm_mon -= 1;
tmp_tm.tm_year -= 1900;
tmp_tm.tm_mon -= 1;
*out_tm = tmp_tm;

return 1;
}
Expand Down Expand Up @@ -192,43 +194,47 @@ struct tm *OPENSSL_gmtime(const time_t *time, struct tm *out_tm) {
return out_tm;
}

int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) {
int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, int64_t offset_sec) {
int64_t posix_time;
if (!posix_time_from_utc(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
tm->tm_hour, tm->tm_min, tm->tm_sec, &posix_time)) {
if (!OPENSSL_tm_to_posix(tm, &posix_time)) {
return 0;
}
static_assert(INT_MAX <= INT64_MAX / SECS_PER_DAY,
"day offset in seconds cannot overflow");
static_assert(MAX_POSIX_TIME <= INT64_MAX - INT_MAX * SECS_PER_DAY,
"addition cannot overflow");
static_assert(MIN_POSIX_TIME >= INT64_MIN - INT_MIN * SECS_PER_DAY,
"addition cannot underflow");
posix_time += offset_day * SECS_PER_DAY;
if (posix_time > 0 && offset_sec > INT64_MAX - posix_time) {
return 0;
}
if (!utc_from_posix_time(
posix_time + (int64_t)off_day * SECS_PER_DAY + offset_sec,
&tm->tm_year, &tm->tm_mon, &tm->tm_mday, &tm->tm_hour, &tm->tm_min,
&tm->tm_sec)) {
if (posix_time < 0 && offset_sec < INT64_MIN - posix_time) {
return 0;
}
posix_time += offset_sec;

if (!OPENSSL_posix_to_tm(posix_time, tm)) {
return 0;
}
tm->tm_year -= 1900;
tm->tm_mon -= 1;

return 1;
}

int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from,
const struct tm *to) {
int64_t time_to;
if (!posix_time_from_utc(to->tm_year + 1900, to->tm_mon + 1, to->tm_mday,
to->tm_hour, to->tm_min, to->tm_sec, &time_to)) {
return 0;
}
int64_t time_from;
if (!posix_time_from_utc(from->tm_year + 1900, from->tm_mon + 1,
from->tm_mday, from->tm_hour, from->tm_min,
from->tm_sec, &time_from)) {
int64_t time_to, time_from;
if (!OPENSSL_tm_to_posix(to, &time_to) ||
!OPENSSL_tm_to_posix(from, &time_from)) {
return 0;
}
// Times are in range, so these calculations can not overflow.
static_assert(SECS_PER_DAY <= INT_MAX, "seconds per day does not fit in int");
static_assert((MAX_POSIX_TIME - MIN_POSIX_TIME) / SECS_PER_DAY <= INT_MAX,
"range of valid POSIX times, in days, does not fit in int");
int64_t timediff = time_to - time_from;
int64_t daydiff = timediff / SECS_PER_DAY;
timediff %= SECS_PER_DAY;
if (daydiff > INT_MAX || daydiff < INT_MIN) {
return 0;
}
*out_secs = (int)timediff;
*out_days = (int)daydiff;
return 1;
Expand Down