1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/cert/ct_log_response_parser.h"
9 #include "base/base64.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/time/time.h"
12 #include "net/cert/ct_serialization.h"
13 #include "net/cert/signed_tree_head.h"
14 #include "testing/gtest/include/gtest/gtest.h"
20 std::string
CreateSignedTreeHeadJsonString(std::string sha256_root_hash
,
21 std::string tree_head_signature
) {
22 std::string sth_json
= "{\"tree_size\":2903698,\"timestamp\":1395761621447";
24 if (!sha256_root_hash
.empty()) {
25 sth_json
+= base::StringPrintf(",\"sha256_root_hash\":\"%s\"",
26 sha256_root_hash
.c_str());
28 if (!tree_head_signature
.empty()) {
29 sth_json
+= base::StringPrintf(",\"tree_head_signature\":\"%s\"",
30 tree_head_signature
.c_str());
37 const char kSHA256RootHash
[] = "/WHFMgXtI/umKKuACJIN0Bb73TcILm9WkeU6qszvoAo=";
39 const char kTreeHeadSignature
[] =
40 "BAMARzBFAiAB+IIYrkRsZDW0/6TzPgR+aJ26twCQ1JDTwq/"
41 "mpinCjAIhAKDXdXMtqbvQ42r9dBIwV5RM/KpEzNQdIhXHesd9HPv3";
43 TEST(CTLogResponseParserTest
, ParsesValidJsonSTH
) {
44 std::string sample_sth
=
45 CreateSignedTreeHeadJsonString(kSHA256RootHash
, kTreeHeadSignature
);
46 SignedTreeHead tree_head
;
47 EXPECT_TRUE(FillSignedTreeHead(sample_sth
, &tree_head
));
49 base::Time expected_timestamp
=
50 base::Time::UnixEpoch() +
51 base::TimeDelta::FromMilliseconds(1395761621447);
53 ASSERT_EQ(SignedTreeHead::V1
, tree_head
.version
);
54 ASSERT_EQ(expected_timestamp
, tree_head
.timestamp
);
55 ASSERT_EQ(2903698u, tree_head
.tree_size
);
57 // Copy the field from the SignedTreeHead because it's not null terminated
58 // there and ASSERT_STREQ expects null-terminated strings.
59 char actual_hash
[kSthRootHashLength
+ 1];
60 memcpy(actual_hash
, tree_head
.sha256_root_hash
, kSthRootHashLength
);
61 actual_hash
[kSthRootHashLength
] = '\0';
62 std::string expected_sha256_root_hash
;
63 base::Base64Decode(kSHA256RootHash
, &expected_sha256_root_hash
);
64 ASSERT_STREQ(expected_sha256_root_hash
.c_str(), actual_hash
);
66 std::string tree_head_signature
;
67 base::Base64Decode(kTreeHeadSignature
, &tree_head_signature
);
68 base::StringPiece
sp(tree_head_signature
);
69 DigitallySigned expected_signature
;
70 ASSERT_TRUE(DecodeDigitallySigned(&sp
, &expected_signature
));
72 ASSERT_EQ(tree_head
.signature
.hash_algorithm
,
73 expected_signature
.hash_algorithm
);
74 ASSERT_EQ(tree_head
.signature
.signature_algorithm
,
75 expected_signature
.signature_algorithm
);
76 ASSERT_EQ(tree_head
.signature
.signature_data
,
77 expected_signature
.signature_data
);
80 TEST(CTLogResponseParserTest
, FailsToParseMissingFields
) {
81 std::string missing_signature_sth
=
82 CreateSignedTreeHeadJsonString(kSHA256RootHash
, "");
84 SignedTreeHead tree_head
;
85 ASSERT_FALSE(FillSignedTreeHead(missing_signature_sth
, &tree_head
));
87 std::string missing_root_hash_sth
=
88 CreateSignedTreeHeadJsonString("", kTreeHeadSignature
);
89 ASSERT_FALSE(FillSignedTreeHead(missing_root_hash_sth
, &tree_head
));
92 TEST(CTLogResponseParserTest
, FailsToParseIncorrectLengthRootHash
) {
93 SignedTreeHead tree_head
;
95 std::string too_long_hash
= CreateSignedTreeHeadJsonString(
96 kSHA256RootHash
, "/WHFMgXtI/umKKuACJIN0Bb73TcILm9WkeU6qszvoArK\n");
97 ASSERT_FALSE(FillSignedTreeHead(too_long_hash
, &tree_head
));
99 std::string too_short_hash
= CreateSignedTreeHeadJsonString(
100 kSHA256RootHash
, "/WHFMgXtI/umKKuACJIN0Bb73TcILm9WkeU6qszvoA==\n");
101 ASSERT_FALSE(FillSignedTreeHead(too_short_hash
, &tree_head
));