123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #include "CTSerialization.h"
- #include "CTTestUtils.h"
- #include "gtest/gtest.h"
- #include "mozilla/Move.h"
- namespace mozilla { namespace ct {
- using namespace pkix;
- class CTSerializationTest : public ::testing::Test
- {
- public:
- void SetUp() override
- {
- mTestDigitallySigned = GetTestDigitallySigned();
- mTestSignatureData = GetTestDigitallySignedData();
- }
- protected:
- Buffer mTestDigitallySigned;
- Buffer mTestSignatureData;
- };
- TEST_F(CTSerializationTest, DecodesDigitallySigned)
- {
- Input digitallySigned = InputForBuffer(mTestDigitallySigned);
- Reader digitallySignedReader(digitallySigned);
- DigitallySigned parsed;
- ASSERT_EQ(Success,
- DecodeDigitallySigned(digitallySignedReader, parsed));
- EXPECT_TRUE(digitallySignedReader.AtEnd());
- EXPECT_EQ(DigitallySigned::HashAlgorithm::SHA256,
- parsed.hashAlgorithm);
- EXPECT_EQ(DigitallySigned::SignatureAlgorithm::ECDSA,
- parsed.signatureAlgorithm);
- EXPECT_EQ(mTestSignatureData, parsed.signatureData);
- }
- TEST_F(CTSerializationTest, FailsToDecodePartialDigitallySigned)
- {
- Input partial;
- ASSERT_EQ(Success,
- partial.Init(mTestDigitallySigned.begin(),
- mTestDigitallySigned.length() - 5));
- Reader partialReader(partial);
- DigitallySigned parsed;
- EXPECT_NE(Success, DecodeDigitallySigned(partialReader, parsed));
- }
- TEST_F(CTSerializationTest, EncodesDigitallySigned)
- {
- DigitallySigned digitallySigned;
- digitallySigned.hashAlgorithm =
- DigitallySigned::HashAlgorithm::SHA256;
- digitallySigned.signatureAlgorithm =
- DigitallySigned::SignatureAlgorithm::ECDSA;
- digitallySigned.signatureData = cloneBuffer(mTestSignatureData);
- Buffer encoded;
- ASSERT_EQ(Success, EncodeDigitallySigned(digitallySigned, encoded));
- EXPECT_EQ(mTestDigitallySigned, encoded);
- }
- TEST_F(CTSerializationTest, EncodesLogEntryForX509Cert)
- {
- LogEntry entry;
- GetX509CertLogEntry(entry);
- Buffer encoded;
- ASSERT_EQ(Success, EncodeLogEntry(entry, encoded));
- EXPECT_EQ((718U + 5U), encoded.length());
- // First two bytes are log entry type. Next, length:
- // Length is 718 which is 512 + 206, which is 0x2ce
- Buffer expectedPrefix;
- MOZ_RELEASE_ASSERT(expectedPrefix.append("\0\0\0\x2\xCE", 5));
- Buffer encodedPrefix;
- MOZ_RELEASE_ASSERT(encodedPrefix.
- append(encoded.begin(), encoded.begin() + 5));
- EXPECT_EQ(expectedPrefix, encodedPrefix);
- }
- TEST_F(CTSerializationTest, EncodesLogEntryForPrecert)
- {
- LogEntry entry;
- GetPrecertLogEntry(entry);
- Buffer encoded;
- ASSERT_EQ(Success, EncodeLogEntry(entry, encoded));
- // log entry type + issuer key + length + tbsCertificate
- EXPECT_EQ((2U + 32U + 3U + entry.tbsCertificate.length()), encoded.length());
- // First two bytes are log entry type.
- Buffer expectedPrefix;
- MOZ_RELEASE_ASSERT(expectedPrefix.append("\0\x1", 2));
- Buffer encodedPrefix;
- MOZ_RELEASE_ASSERT(encodedPrefix.
- append(encoded.begin(), encoded.begin() + 2));
- EXPECT_EQ(expectedPrefix, encodedPrefix);
- // Next is the issuer key (32 bytes).
- Buffer encodedKeyHash;
- MOZ_RELEASE_ASSERT(encodedKeyHash.
- append(encoded.begin() + 2, encoded.begin() + 2 + 32));
- EXPECT_EQ(GetDefaultIssuerKeyHash(), encodedKeyHash);
- }
- TEST_F(CTSerializationTest, EncodesV1SCTSignedData)
- {
- uint64_t timestamp = UINT64_C(0x139fe353cf5);
- const uint8_t DUMMY_BYTES[] = { 0x61, 0x62, 0x63 }; // abc
- Input dummyEntry(DUMMY_BYTES);
- Input emptyExtensions;
- Buffer encoded;
- ASSERT_EQ(Success, EncodeV1SCTSignedData(
- timestamp, dummyEntry, emptyExtensions, encoded));
- EXPECT_EQ((size_t) 15, encoded.length());
- const uint8_t EXPECTED_BYTES[] = {
- 0x00, // version
- 0x00, // signature type
- 0x00, 0x00, 0x01, 0x39, 0xFE, 0x35, 0x3C, 0xF5, // timestamp
- 0x61, 0x62, 0x63, // log signature
- 0x00, 0x00 // extensions (empty)
- };
- Buffer expectedBuffer;
- MOZ_RELEASE_ASSERT(
- expectedBuffer.append(EXPECTED_BYTES, sizeof(EXPECTED_BYTES)));
- EXPECT_EQ(expectedBuffer, encoded);
- }
- TEST_F(CTSerializationTest, DecodesSCTList)
- {
- // Two items in the list: "abc", "def"
- const uint8_t ENCODED[] = {
- 0x00, 0x0a, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00, 0x03, 0x64, 0x65, 0x66
- };
- const uint8_t DECODED_1[] = { 0x61, 0x62, 0x63 };
- const uint8_t DECODED_2[] = { 0x64, 0x65, 0x66 };
- Reader listReader;
- ASSERT_EQ(Success, DecodeSCTList(Input(ENCODED), listReader));
- Input decoded1;
- ASSERT_EQ(Success, ReadSCTListItem(listReader, decoded1));
- Input decoded2;
- ASSERT_EQ(Success, ReadSCTListItem(listReader, decoded2));
- EXPECT_TRUE(listReader.AtEnd());
- EXPECT_TRUE(InputsAreEqual(decoded1, Input(DECODED_1)));
- EXPECT_TRUE(InputsAreEqual(decoded2, Input(DECODED_2)));
- }
- TEST_F(CTSerializationTest, FailsDecodingInvalidSCTList)
- {
- // A list with one item that's too short (the second one)
- const uint8_t ENCODED[] = {
- 0x00, 0x0a, 0x00, 0x03, 0x61, 0x62, 0x63, 0x00, 0x05, 0x64, 0x65, 0x66
- };
- Reader listReader;
- ASSERT_EQ(Success, DecodeSCTList(Input(ENCODED), listReader));
- Input decoded1;
- EXPECT_EQ(Success, ReadSCTListItem(listReader, decoded1));
- Input decoded2;
- EXPECT_NE(Success, ReadSCTListItem(listReader, decoded2));
- }
- TEST_F(CTSerializationTest, EncodesSCTList)
- {
- const uint8_t SCT_1[] = { 0x61, 0x62, 0x63 };
- const uint8_t SCT_2[] = { 0x64, 0x65, 0x66 };
- Vector<Input> list;
- ASSERT_TRUE(list.append(Move(Input(SCT_1))));
- ASSERT_TRUE(list.append(Move(Input(SCT_2))));
- Buffer encodedList;
- ASSERT_EQ(Success, EncodeSCTList(list, encodedList));
- Reader listReader;
- ASSERT_EQ(Success, DecodeSCTList(InputForBuffer(encodedList), listReader));
- Input decoded1;
- ASSERT_EQ(Success, ReadSCTListItem(listReader, decoded1));
- EXPECT_TRUE(InputsAreEqual(decoded1, Input(SCT_1)));
- Input decoded2;
- ASSERT_EQ(Success, ReadSCTListItem(listReader, decoded2));
- EXPECT_TRUE(InputsAreEqual(decoded2, Input(SCT_2)));
- EXPECT_TRUE(listReader.AtEnd());
- }
- TEST_F(CTSerializationTest, DecodesSignedCertificateTimestamp)
- {
- Buffer encodedSctBuffer = GetTestSignedCertificateTimestamp();
- Input encodedSctInput = InputForBuffer(encodedSctBuffer);
- Reader encodedSctReader(encodedSctInput);
- SignedCertificateTimestamp sct;
- ASSERT_EQ(Success,
- DecodeSignedCertificateTimestamp(encodedSctReader, sct));
- EXPECT_EQ(SignedCertificateTimestamp::Version::V1, sct.version);
- EXPECT_EQ(GetTestPublicKeyId(), sct.logId);
- const uint64_t expectedTime = 1365181456089;
- EXPECT_EQ(expectedTime, sct.timestamp);
- const size_t expectedSignatureLength = 71;
- EXPECT_EQ(expectedSignatureLength, sct.signature.signatureData.length());
- EXPECT_TRUE(sct.extensions.empty());
- }
- TEST_F(CTSerializationTest, FailsDecodingInvalidSignedCertificateTimestamp)
- {
- SignedCertificateTimestamp sct;
- // Invalid version
- const uint8_t INVALID_VERSION_BYTES[] = { 0x02, 0x00 };
- Input invalidVersionSctInput(INVALID_VERSION_BYTES);
- Reader invalidVersionSctReader(invalidVersionSctInput);
- EXPECT_EQ(Result::ERROR_BAD_DER,
- DecodeSignedCertificateTimestamp(invalidVersionSctReader, sct));
- // Valid version, invalid length (missing data)
- const uint8_t INVALID_LENGTH_BYTES[] = { 0x00, 0x0a, 0x0b, 0x0c };
- Input invalidLengthSctInput(INVALID_LENGTH_BYTES);
- Reader invalidLengthSctReader(invalidLengthSctInput);
- EXPECT_EQ(Result::ERROR_BAD_DER,
- DecodeSignedCertificateTimestamp(invalidLengthSctReader, sct));
- }
- TEST_F(CTSerializationTest, EncodesValidSignedTreeHead)
- {
- SignedTreeHead signedTreeHead;
- GetSampleSignedTreeHead(signedTreeHead);
- Buffer encoded;
- ASSERT_EQ(Success,
- EncodeTreeHeadSignature(signedTreeHead, encoded));
- // Expected size is 50 bytes:
- // Byte 0 is version, byte 1 is signature type
- // Bytes 2-9 are timestamp
- // Bytes 10-17 are tree size
- // Bytes 18-49 are sha256 root hash
- ASSERT_EQ(50u, encoded.length());
- const uint8_t EXPECTED_BYTES_PREFIX[] = {
- 0x00, // version
- 0x01, // signature type
- 0x00, 0x00, 0x01, 0x45, 0x3c, 0x5f, 0xb8, 0x35, // timestamp
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15 // tree size
- // sha256 root hash should follow
- };
- Buffer expectedBuffer;
- MOZ_RELEASE_ASSERT(expectedBuffer.append(EXPECTED_BYTES_PREFIX, 18));
- Buffer hash = GetSampleSTHSHA256RootHash();
- MOZ_RELEASE_ASSERT(expectedBuffer.append(hash.begin(), hash.length()));
- EXPECT_EQ(expectedBuffer, encoded);
- }
- } } // namespace mozilla::ct
|