CTSerializationTest.cpp (11096B)
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/. */ 6 7 #include "CTSerialization.h" 8 #include "CTTestUtils.h" 9 #include "gtest/gtest.h" 10 11 namespace mozilla { 12 namespace ct { 13 14 using namespace pkix; 15 16 class CTSerializationTest : public ::testing::Test { 17 public: 18 void SetUp() override { 19 mTestDigitallySigned = GetTestDigitallySigned(); 20 mTestSignatureData = GetTestDigitallySignedData(); 21 } 22 23 protected: 24 Buffer mTestDigitallySigned; 25 Buffer mTestSignatureData; 26 }; 27 28 TEST_F(CTSerializationTest, DecodesDigitallySigned) { 29 Input digitallySigned = InputForBuffer(mTestDigitallySigned); 30 Reader digitallySignedReader(digitallySigned); 31 32 DigitallySigned parsed; 33 ASSERT_EQ(Success, DecodeDigitallySigned(digitallySignedReader, parsed)); 34 EXPECT_TRUE(digitallySignedReader.AtEnd()); 35 36 EXPECT_EQ(DigitallySigned::HashAlgorithm::SHA256, parsed.hashAlgorithm); 37 EXPECT_EQ(DigitallySigned::SignatureAlgorithm::ECDSA, 38 parsed.signatureAlgorithm); 39 EXPECT_EQ(mTestSignatureData, parsed.signatureData); 40 } 41 42 TEST_F(CTSerializationTest, FailsToDecodePartialDigitallySigned) { 43 Input partial; 44 ASSERT_EQ(Success, partial.Init(mTestDigitallySigned.data(), 45 mTestDigitallySigned.size() - 5)); 46 Reader partialReader(partial); 47 48 DigitallySigned parsed; 49 50 EXPECT_NE(Success, DecodeDigitallySigned(partialReader, parsed)); 51 } 52 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; 59 60 Buffer encoded; 61 62 ASSERT_EQ(Success, EncodeDigitallySigned(digitallySigned, encoded)); 63 EXPECT_EQ(mTestDigitallySigned, encoded); 64 } 65 66 TEST_F(CTSerializationTest, EncodesLogEntryForX509Cert) { 67 LogEntry entry; 68 GetX509CertLogEntry(entry); 69 70 Buffer encoded; 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}; 76 Buffer encodedPrefix; 77 encodedPrefix.assign(encoded.begin(), encoded.begin() + 5); 78 EXPECT_EQ(expectedPrefix, encodedPrefix); 79 } 80 81 TEST_F(CTSerializationTest, EncodesLogEntryForPrecert) { 82 LogEntry entry; 83 GetPrecertLogEntry(entry); 84 85 Buffer encoded; 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()); 89 90 // First two bytes are log entry type. 91 Buffer expectedPrefix = {0, 1}; 92 Buffer encodedPrefix; 93 encodedPrefix.assign(encoded.begin(), encoded.begin() + 2); 94 EXPECT_EQ(expectedPrefix, encodedPrefix); 95 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); 100 } 101 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; 107 Buffer encoded; 108 ASSERT_EQ(Success, EncodeV1SCTSignedData(timestamp, dummyEntry, 109 emptyExtensions, encoded)); 110 EXPECT_EQ((size_t)15, encoded.size()); 111 112 Buffer expectedBuffer = { 113 0x00, // version 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) 118 }; 119 EXPECT_EQ(expectedBuffer, encoded); 120 } 121 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}; 128 129 Reader listReader; 130 ASSERT_EQ(Success, DecodeSCTList(Input(ENCODED), listReader)); 131 132 Input decoded1; 133 ASSERT_EQ(Success, ReadSCTListItem(listReader, decoded1)); 134 135 Input decoded2; 136 ASSERT_EQ(Success, ReadSCTListItem(listReader, decoded2)); 137 138 EXPECT_TRUE(listReader.AtEnd()); 139 EXPECT_TRUE(InputsAreEqual(decoded1, Input(DECODED_1))); 140 EXPECT_TRUE(InputsAreEqual(decoded2, Input(DECODED_2))); 141 } 142 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}; 147 148 Reader listReader; 149 ASSERT_EQ(Success, DecodeSCTList(Input(ENCODED), listReader)); 150 Input decoded1; 151 EXPECT_EQ(Success, ReadSCTListItem(listReader, decoded1)); 152 Input decoded2; 153 EXPECT_NE(Success, ReadSCTListItem(listReader, decoded2)); 154 } 155 156 TEST_F(CTSerializationTest, EncodesSCTList) { 157 const uint8_t SCT_1[] = {0x61, 0x62, 0x63}; 158 const uint8_t SCT_2[] = {0x64, 0x65, 0x66}; 159 160 std::vector<Input> list; 161 list.push_back(Input(SCT_1)); 162 list.push_back(Input(SCT_2)); 163 164 Buffer encodedList; 165 ASSERT_EQ(Success, EncodeSCTList(list, encodedList)); 166 167 Reader listReader; 168 ASSERT_EQ(Success, DecodeSCTList(InputForBuffer(encodedList), listReader)); 169 170 Input decoded1; 171 ASSERT_EQ(Success, ReadSCTListItem(listReader, decoded1)); 172 EXPECT_TRUE(InputsAreEqual(decoded1, Input(SCT_1))); 173 174 Input decoded2; 175 ASSERT_EQ(Success, ReadSCTListItem(listReader, decoded2)); 176 EXPECT_TRUE(InputsAreEqual(decoded2, Input(SCT_2))); 177 178 EXPECT_TRUE(listReader.AtEnd()); 179 } 180 181 TEST_F(CTSerializationTest, DecodesSignedCertificateTimestamp) { 182 Buffer encodedSctBuffer = GetTestSignedCertificateTimestamp(); 183 Input encodedSctInput = InputForBuffer(encodedSctBuffer); 184 Reader encodedSctReader(encodedSctInput); 185 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()); 195 EXPECT_TRUE(sct.leafIndex.isNothing()); 196 } 197 198 TEST_F(CTSerializationTest, 199 DecodesSignedCertificateTimestampWithLeafIndexExtension) { 200 Buffer encodedSctBuffer = 201 GetTestSignedCertificateTimestampWithLeafIndexExtension(); 202 Input encodedSctInput = InputForBuffer(encodedSctBuffer); 203 Reader encodedSctReader(encodedSctInput); 204 205 SignedCertificateTimestamp sct; 206 ASSERT_EQ(Success, DecodeSignedCertificateTimestamp(encodedSctReader, sct)); 207 EXPECT_EQ(SignedCertificateTimestamp::Version::V1, sct.version); 208 EXPECT_EQ(GetTestPublicKeyId(), sct.logId); 209 const uint64_t expectedTime = 1365181456089; 210 EXPECT_EQ(expectedTime, sct.timestamp); 211 const size_t expectedSignatureLength = 71; 212 EXPECT_EQ(expectedSignatureLength, sct.signature.signatureData.size()); 213 EXPECT_FALSE(sct.extensions.empty()); 214 ASSERT_TRUE(sct.leafIndex.isSome()); 215 EXPECT_EQ(sct.leafIndex.value(), 52U); 216 } 217 218 TEST_F(CTSerializationTest, 219 FailsDecodingSignedCertificateTimestampWithTwoLeafIndexExtensions) { 220 Buffer encodedSctBuffer = 221 GetTestSignedCertificateTimestampWithTwoLeafIndexExtensions(); 222 Input encodedSctInput = InputForBuffer(encodedSctBuffer); 223 Reader encodedSctReader(encodedSctInput); 224 225 SignedCertificateTimestamp sct; 226 ASSERT_EQ(Result::ERROR_EXTENSION_VALUE_INVALID, 227 DecodeSignedCertificateTimestamp(encodedSctReader, sct)); 228 } 229 230 TEST_F(CTSerializationTest, 231 DecodesSignedCertificateTimestampWithUnknownExtension) { 232 Buffer encodedSctBuffer = 233 GetTestSignedCertificateTimestampWithUnknownExtension(); 234 Input encodedSctInput = InputForBuffer(encodedSctBuffer); 235 Reader encodedSctReader(encodedSctInput); 236 237 SignedCertificateTimestamp sct; 238 ASSERT_EQ(Success, DecodeSignedCertificateTimestamp(encodedSctReader, sct)); 239 EXPECT_EQ(SignedCertificateTimestamp::Version::V1, sct.version); 240 EXPECT_EQ(GetTestPublicKeyId(), sct.logId); 241 const uint64_t expectedTime = 1365181456089; 242 EXPECT_EQ(expectedTime, sct.timestamp); 243 const size_t expectedSignatureLength = 71; 244 EXPECT_EQ(expectedSignatureLength, sct.signature.signatureData.size()); 245 EXPECT_FALSE(sct.extensions.empty()); 246 EXPECT_TRUE(sct.leafIndex.isNothing()); 247 } 248 249 TEST_F(CTSerializationTest, 250 DecodesSignedCertificateTimestampWithUnknownAndLeafIndexExtensions) { 251 Buffer encodedSctBuffer = 252 GetTestSignedCertificateTimestampWithUnknownAndLeafIndexExtensions(); 253 Input encodedSctInput = InputForBuffer(encodedSctBuffer); 254 Reader encodedSctReader(encodedSctInput); 255 256 SignedCertificateTimestamp sct; 257 ASSERT_EQ(Success, DecodeSignedCertificateTimestamp(encodedSctReader, sct)); 258 EXPECT_EQ(SignedCertificateTimestamp::Version::V1, sct.version); 259 EXPECT_EQ(GetTestPublicKeyId(), sct.logId); 260 const uint64_t expectedTime = 1365181456089; 261 EXPECT_EQ(expectedTime, sct.timestamp); 262 const size_t expectedSignatureLength = 71; 263 EXPECT_EQ(expectedSignatureLength, sct.signature.signatureData.size()); 264 EXPECT_FALSE(sct.extensions.empty()); 265 ASSERT_TRUE(sct.leafIndex.isSome()); 266 EXPECT_EQ(sct.leafIndex.value(), 81U); 267 } 268 269 TEST_F(CTSerializationTest, 270 FailsDecodingSignedCertificateTimestampWithTooShortExtension) { 271 Buffer encodedSctBuffer = 272 GetTestSignedCertificateTimestampWithTooShortExtension(); 273 Input encodedSctInput = InputForBuffer(encodedSctBuffer); 274 Reader encodedSctReader(encodedSctInput); 275 276 SignedCertificateTimestamp sct; 277 ASSERT_EQ(Result::ERROR_BAD_DER, 278 DecodeSignedCertificateTimestamp(encodedSctReader, sct)); 279 } 280 281 TEST_F(CTSerializationTest, FailsDecodingInvalidSignedCertificateTimestamp) { 282 SignedCertificateTimestamp sct; 283 284 // Invalid version 285 const uint8_t INVALID_VERSION_BYTES[] = {0x02, 0x00}; 286 Input invalidVersionSctInput(INVALID_VERSION_BYTES); 287 Reader invalidVersionSctReader(invalidVersionSctInput); 288 EXPECT_EQ(pkix::Result::ERROR_BAD_DER, 289 DecodeSignedCertificateTimestamp(invalidVersionSctReader, sct)); 290 291 // Valid version, invalid length (missing data) 292 const uint8_t INVALID_LENGTH_BYTES[] = {0x00, 0x0a, 0x0b, 0x0c}; 293 Input invalidLengthSctInput(INVALID_LENGTH_BYTES); 294 Reader invalidLengthSctReader(invalidLengthSctInput); 295 EXPECT_EQ(pkix::Result::ERROR_BAD_DER, 296 DecodeSignedCertificateTimestamp(invalidLengthSctReader, sct)); 297 } 298 299 } // namespace ct 300 } // namespace mozilla