// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include "base/macros.h" #include "net/der/parse_values.h" #include "testing/gtest/include/gtest/gtest.h" namespace net { namespace der { namespace test { namespace { template Input FromStringLiteral(const char(&data)[N]) { // Strings are null-terminated. The null terminating byte shouldn't be // included in the Input, so the size is N - 1 instead of N. return Input(reinterpret_cast(data), N - 1); } } // namespace TEST(ParseValuesTest, ParseBool) { uint8_t buf[] = {0xFF, 0x00}; Input value(buf, 1); bool out; EXPECT_TRUE(ParseBool(value, &out)); EXPECT_TRUE(out); buf[0] = 0; EXPECT_TRUE(ParseBool(value, &out)); EXPECT_FALSE(out); buf[0] = 1; EXPECT_FALSE(ParseBool(value, &out)); EXPECT_TRUE(ParseBoolRelaxed(value, &out)); EXPECT_TRUE(out); buf[0] = 0xFF; value = Input(buf, 2); EXPECT_FALSE(ParseBool(value, &out)); value = Input(buf, 0); EXPECT_FALSE(ParseBool(value, &out)); } TEST(ParseValuesTest, ParseTimes) { GeneralizedTime out; EXPECT_TRUE(ParseUTCTime(FromStringLiteral("140218161200Z"), &out)); // DER-encoded UTCTime must end with 'Z'. EXPECT_FALSE(ParseUTCTime(FromStringLiteral("140218161200X"), &out)); // Check that a negative number (-4 in this case) doesn't get parsed as // a 2-digit number. EXPECT_FALSE(ParseUTCTime(FromStringLiteral("-40218161200Z"), &out)); // Check that numbers with a leading 0 don't get parsed in octal by making // the second digit an invalid octal digit (e.g. 09). EXPECT_TRUE(ParseUTCTime(FromStringLiteral("090218161200Z"), &out)); // Check that the length is validated. EXPECT_FALSE(ParseUTCTime(FromStringLiteral("140218161200"), &out)); EXPECT_FALSE(ParseUTCTime(FromStringLiteral("140218161200Z0"), &out)); EXPECT_FALSE(ParseUTCTimeRelaxed(FromStringLiteral("140218161200"), &out)); EXPECT_FALSE(ParseUTCTimeRelaxed(FromStringLiteral("140218161200Z0"), &out)); // Check strictness of UTCTime parsers. EXPECT_FALSE(ParseUTCTime(FromStringLiteral("1402181612Z"), &out)); EXPECT_TRUE(ParseUTCTimeRelaxed(FromStringLiteral("1402181612Z"), &out)); // Check that the time ends in Z. EXPECT_FALSE(ParseUTCTimeRelaxed(FromStringLiteral("1402181612Z0"), &out)); // Check format of GeneralizedTime. // Leap seconds are allowed. EXPECT_TRUE(ParseGeneralizedTime(FromStringLiteral("20140218161260Z"), &out)); // But nothing larger than a leap second. EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20140218161261Z"), &out)); // Minutes only go up to 59. EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20140218166000Z"), &out)); // Hours only go up to 23. EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20140218240000Z"), &out)); // The 0th day of a month is invalid. EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20140200161200Z"), &out)); // The 0th month is invalid. EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20140018161200Z"), &out)); // Months greater than 12 are invalid. EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20141318161200Z"), &out)); // Some months have 31 days. EXPECT_TRUE(ParseGeneralizedTime(FromStringLiteral("20140131000000Z"), &out)); // September has only 30 days. EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20140931000000Z"), &out)); // February has only 28 days... EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20140229000000Z"), &out)); // ... unless it's a leap year. EXPECT_TRUE(ParseGeneralizedTime(FromStringLiteral("20160229000000Z"), &out)); // There aren't any leap days in years divisible by 100... EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("21000229000000Z"), &out)); // ...unless it's also divisible by 400. EXPECT_TRUE(ParseGeneralizedTime(FromStringLiteral("20000229000000Z"), &out)); // Check more perverse invalid inputs. // Check that trailing null bytes are not ignored. EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20001231010203Z\0"), &out)); // Check what happens when a null byte is in the middle of the input. EXPECT_FALSE(ParseGeneralizedTime(FromStringLiteral( "200\0" "1231010203Z"), &out)); // The year can't be in hex. EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("0x201231000000Z"), &out)); // The last byte must be 'Z'. EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20001231000000X"), &out)); // Check that the length is validated. EXPECT_FALSE(ParseGeneralizedTime(FromStringLiteral("20140218161200"), &out)); EXPECT_FALSE( ParseGeneralizedTime(FromStringLiteral("20140218161200Z0"), &out)); } TEST(ParseValuesTest, TimesCompare) { GeneralizedTime time1; GeneralizedTime time2; GeneralizedTime time3; ASSERT_TRUE( ParseGeneralizedTime(FromStringLiteral("20140218161200Z"), &time1)); ASSERT_TRUE(ParseUTCTime(FromStringLiteral("150218161200Z"), &time2)); ASSERT_TRUE( ParseGeneralizedTime(FromStringLiteral("20160218161200Z"), &time3)); EXPECT_TRUE(time1 < time2); EXPECT_TRUE(time2 < time3); EXPECT_TRUE(time1 < time3); } struct Uint64TestData { bool should_pass; const uint8_t input[9]; size_t length; uint64_t expected_value; }; const Uint64TestData kUint64TestData[] = { {true, {0x00}, 1, 0}, {true, {0x01}, 1, 1}, {false, {0xFF}, 1, 0}, {true, {0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 8, INT64_MAX}, {false, {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 8, 0}, {false, {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, 9, 0}, {false, {0x00, 0x01}, 2, 1}, {false, {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09}, 9, 0}, {false, {0}, 0, 0}, }; TEST(ParseValuesTest, ParseUint64) { for (size_t i = 0; i < arraysize(kUint64TestData); i++) { Uint64TestData test_case = kUint64TestData[i]; SCOPED_TRACE(i); uint64_t result; EXPECT_EQ(test_case.should_pass, ParseUint64(Input(test_case.input, test_case.length), &result)); if (test_case.should_pass) EXPECT_EQ(test_case.expected_value, result); } } } // namespace test } // namespace der } // namespace net