1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "CTSerialization.h"
8 #include "CTTestUtils.h"
9 #include "gtest/gtest.h"
16 class CTSerializationTest
: public ::testing::Test
{
18 void SetUp() override
{
19 mTestDigitallySigned
= GetTestDigitallySigned();
20 mTestSignatureData
= GetTestDigitallySignedData();
24 Buffer mTestDigitallySigned
;
25 Buffer mTestSignatureData
;
28 TEST_F(CTSerializationTest
, DecodesDigitallySigned
) {
29 Input digitallySigned
= InputForBuffer(mTestDigitallySigned
);
30 Reader
digitallySignedReader(digitallySigned
);
32 DigitallySigned parsed
;
33 ASSERT_EQ(Success
, DecodeDigitallySigned(digitallySignedReader
, parsed
));
34 EXPECT_TRUE(digitallySignedReader
.AtEnd());
36 EXPECT_EQ(DigitallySigned::HashAlgorithm::SHA256
, parsed
.hashAlgorithm
);
37 EXPECT_EQ(DigitallySigned::SignatureAlgorithm::ECDSA
,
38 parsed
.signatureAlgorithm
);
39 EXPECT_EQ(mTestSignatureData
, parsed
.signatureData
);
42 TEST_F(CTSerializationTest
, FailsToDecodePartialDigitallySigned
) {
44 ASSERT_EQ(Success
, partial
.Init(mTestDigitallySigned
.data(),
45 mTestDigitallySigned
.size() - 5));
46 Reader
partialReader(partial
);
48 DigitallySigned parsed
;
50 EXPECT_NE(Success
, DecodeDigitallySigned(partialReader
, parsed
));
53 TEST_F(CTSerializationTest
, EncodesDigitallySigned
) {
54 DigitallySigned digitallySigned
;
55 digitallySigned
.hashAlgorithm
= DigitallySigned::HashAlgorithm::SHA256
;
56 digitallySigned
.signatureAlgorithm
=
57 DigitallySigned::SignatureAlgorithm::ECDSA
;
58 digitallySigned
.signatureData
= mTestSignatureData
;
62 ASSERT_EQ(Success
, EncodeDigitallySigned(digitallySigned
, encoded
));
63 EXPECT_EQ(mTestDigitallySigned
, encoded
);
66 TEST_F(CTSerializationTest
, EncodesLogEntryForX509Cert
) {
68 GetX509CertLogEntry(entry
);
71 ASSERT_EQ(Success
, EncodeLogEntry(entry
, encoded
));
72 EXPECT_EQ((718U + 5U), encoded
.size());
73 // First two bytes are log entry type. Next, length:
74 // Length is 718 which is 512 + 206, which is { 0, ..., 2, 206 }.
75 Buffer expectedPrefix
= {0, 0, 0, 2, 206};
77 encodedPrefix
.assign(encoded
.begin(), encoded
.begin() + 5);
78 EXPECT_EQ(expectedPrefix
, encodedPrefix
);
81 TEST_F(CTSerializationTest
, EncodesLogEntryForPrecert
) {
83 GetPrecertLogEntry(entry
);
86 ASSERT_EQ(Success
, EncodeLogEntry(entry
, encoded
));
87 // log entry type + issuer key + length + tbsCertificate
88 EXPECT_EQ((2U + 32U + 3U + entry
.tbsCertificate
.size()), encoded
.size());
90 // First two bytes are log entry type.
91 Buffer expectedPrefix
= {0, 1};
93 encodedPrefix
.assign(encoded
.begin(), encoded
.begin() + 2);
94 EXPECT_EQ(expectedPrefix
, encodedPrefix
);
96 // Next is the issuer key (32 bytes).
97 Buffer encodedKeyHash
;
98 encodedKeyHash
.assign(encoded
.begin() + 2, encoded
.begin() + 2 + 32);
99 EXPECT_EQ(GetDefaultIssuerKeyHash(), encodedKeyHash
);
102 TEST_F(CTSerializationTest
, EncodesV1SCTSignedData
) {
103 uint64_t timestamp
= UINT64_C(0x139fe353cf5);
104 const uint8_t DUMMY_BYTES
[] = {0x61, 0x62, 0x63}; // abc
105 Input
dummyEntry(DUMMY_BYTES
);
106 Input emptyExtensions
;
108 ASSERT_EQ(Success
, EncodeV1SCTSignedData(timestamp
, dummyEntry
,
109 emptyExtensions
, encoded
));
110 EXPECT_EQ((size_t)15, encoded
.size());
112 Buffer expectedBuffer
= {
114 0x00, // signature type
115 0x00, 0x00, 0x01, 0x39, 0xFE, 0x35, 0x3C, 0xF5, // timestamp
116 0x61, 0x62, 0x63, // log signature
117 0x00, 0x00 // extensions (empty)
119 EXPECT_EQ(expectedBuffer
, encoded
);
122 TEST_F(CTSerializationTest
, DecodesSCTList
) {
123 // Two items in the list: "abc", "def"
124 const uint8_t ENCODED
[] = {0x00, 0x0a, 0x00, 0x03, 0x61, 0x62,
125 0x63, 0x00, 0x03, 0x64, 0x65, 0x66};
126 const uint8_t DECODED_1
[] = {0x61, 0x62, 0x63};
127 const uint8_t DECODED_2
[] = {0x64, 0x65, 0x66};
130 ASSERT_EQ(Success
, DecodeSCTList(Input(ENCODED
), listReader
));
133 ASSERT_EQ(Success
, ReadSCTListItem(listReader
, decoded1
));
136 ASSERT_EQ(Success
, ReadSCTListItem(listReader
, decoded2
));
138 EXPECT_TRUE(listReader
.AtEnd());
139 EXPECT_TRUE(InputsAreEqual(decoded1
, Input(DECODED_1
)));
140 EXPECT_TRUE(InputsAreEqual(decoded2
, Input(DECODED_2
)));
143 TEST_F(CTSerializationTest
, FailsDecodingInvalidSCTList
) {
144 // A list with one item that's too short (the second one)
145 const uint8_t ENCODED
[] = {0x00, 0x0a, 0x00, 0x03, 0x61, 0x62,
146 0x63, 0x00, 0x05, 0x64, 0x65, 0x66};
149 ASSERT_EQ(Success
, DecodeSCTList(Input(ENCODED
), listReader
));
151 EXPECT_EQ(Success
, ReadSCTListItem(listReader
, decoded1
));
153 EXPECT_NE(Success
, ReadSCTListItem(listReader
, decoded2
));
156 TEST_F(CTSerializationTest
, EncodesSCTList
) {
157 const uint8_t SCT_1
[] = {0x61, 0x62, 0x63};
158 const uint8_t SCT_2
[] = {0x64, 0x65, 0x66};
160 std::vector
<Input
> list
;
161 list
.push_back(Input(SCT_1
));
162 list
.push_back(Input(SCT_2
));
165 ASSERT_EQ(Success
, EncodeSCTList(list
, encodedList
));
168 ASSERT_EQ(Success
, DecodeSCTList(InputForBuffer(encodedList
), listReader
));
171 ASSERT_EQ(Success
, ReadSCTListItem(listReader
, decoded1
));
172 EXPECT_TRUE(InputsAreEqual(decoded1
, Input(SCT_1
)));
175 ASSERT_EQ(Success
, ReadSCTListItem(listReader
, decoded2
));
176 EXPECT_TRUE(InputsAreEqual(decoded2
, Input(SCT_2
)));
178 EXPECT_TRUE(listReader
.AtEnd());
181 TEST_F(CTSerializationTest
, DecodesSignedCertificateTimestamp
) {
182 Buffer encodedSctBuffer
= GetTestSignedCertificateTimestamp();
183 Input encodedSctInput
= InputForBuffer(encodedSctBuffer
);
184 Reader
encodedSctReader(encodedSctInput
);
186 SignedCertificateTimestamp sct
;
187 ASSERT_EQ(Success
, DecodeSignedCertificateTimestamp(encodedSctReader
, sct
));
188 EXPECT_EQ(SignedCertificateTimestamp::Version::V1
, sct
.version
);
189 EXPECT_EQ(GetTestPublicKeyId(), sct
.logId
);
190 const uint64_t expectedTime
= 1365181456089;
191 EXPECT_EQ(expectedTime
, sct
.timestamp
);
192 const size_t expectedSignatureLength
= 71;
193 EXPECT_EQ(expectedSignatureLength
, sct
.signature
.signatureData
.size());
194 EXPECT_TRUE(sct
.extensions
.empty());
197 TEST_F(CTSerializationTest
, FailsDecodingInvalidSignedCertificateTimestamp
) {
198 SignedCertificateTimestamp sct
;
201 const uint8_t INVALID_VERSION_BYTES
[] = {0x02, 0x00};
202 Input
invalidVersionSctInput(INVALID_VERSION_BYTES
);
203 Reader
invalidVersionSctReader(invalidVersionSctInput
);
204 EXPECT_EQ(pkix::Result::ERROR_BAD_DER
,
205 DecodeSignedCertificateTimestamp(invalidVersionSctReader
, sct
));
207 // Valid version, invalid length (missing data)
208 const uint8_t INVALID_LENGTH_BYTES
[] = {0x00, 0x0a, 0x0b, 0x0c};
209 Input
invalidLengthSctInput(INVALID_LENGTH_BYTES
);
210 Reader
invalidLengthSctReader(invalidLengthSctInput
);
211 EXPECT_EQ(pkix::Result::ERROR_BAD_DER
,
212 DecodeSignedCertificateTimestamp(invalidLengthSctReader
, sct
));
216 } // namespace mozilla