LibCrypto: Don't crash in ASN1::parse_utc_time on missing 'Z'

The underlying reason is an unconditional call to consume(), even if
there is no reason to expect that the string continues.

This crash was discovered by OSS-Fuzz:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=42354
This bug exists since the code was first written in April 2021:
13abbc5ea8
This commit is contained in:
Ben Wiederhake 2022-09-11 21:39:29 +02:00 committed by Andreas Kling
parent 29261809ef
commit 0ca41d2813
Notes: sideshowbarker 2024-07-17 10:05:47 +09:00
2 changed files with 21 additions and 23 deletions

View file

@ -57,10 +57,9 @@ TEST_CASE(test_utc_missing_z)
// YYMMDDhhmm[ss]
// We don't actually need to parse this correctly; rejecting these inputs is fine.
// This test just makes sure that we don't crash.
// FIXME: This currently crashes
// (void)Crypto::ASN1::parse_utc_time("010101010101"sv);
// (void)Crypto::ASN1::parse_utc_time("010203040506"sv);
// (void)Crypto::ASN1::parse_utc_time("020406081012"sv);
// (void)Crypto::ASN1::parse_utc_time("0204060810"sv);
// (void)Crypto::ASN1::parse_utc_time("220911220000"sv);
(void)Crypto::ASN1::parse_utc_time("010101010101"sv);
(void)Crypto::ASN1::parse_utc_time("010203040506"sv);
(void)Crypto::ASN1::parse_utc_time("020406081012"sv);
(void)Crypto::ASN1::parse_utc_time("0204060810"sv);
(void)Crypto::ASN1::parse_utc_time("220911220000"sv);
}

View file

@ -84,26 +84,25 @@ Optional<Core::DateTime> parse_utc_time(StringView time)
auto minute = lexer.consume(2).to_uint();
Optional<unsigned> seconds, offset_hours, offset_minutes;
[[maybe_unused]] bool negative_offset = false;
if (!lexer.next_is('Z')) {
if (!lexer.next_is(is_any_of("+-"sv))) {
seconds = lexer.consume(2).to_uint();
if (!seconds.has_value()) {
return {};
}
}
if (lexer.next_is(is_any_of("+-"sv))) {
negative_offset = lexer.consume() == '-';
offset_hours = lexer.consume(2).to_uint();
offset_minutes = lexer.consume(2).to_uint();
if (!offset_hours.has_value() || !offset_minutes.has_value()) {
return {};
}
} else {
lexer.consume();
if (lexer.next_is(is_any_of("0123456789"sv))) {
seconds = lexer.consume(2).to_uint();
if (!seconds.has_value()) {
return {};
}
}
if (lexer.next_is('Z')) {
lexer.consume();
} else if (lexer.next_is(is_any_of("+-"sv))) {
negative_offset = lexer.consume() == '-';
offset_hours = lexer.consume(2).to_uint();
offset_minutes = lexer.consume(2).to_uint();
if (!offset_hours.has_value() || !offset_minutes.has_value()) {
return {};
}
} else {
lexer.consume();
return {};
}
if (!year_in_century.has_value() || !month.has_value() || !day.has_value() || !hour.has_value() || !minute.has_value()) {