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/json/json_reader.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/time/time.h"
13 #include "base/values.h"
14 #include "net/cert/ct_serialization.h"
15 #include "net/cert/signed_tree_head.h"
16 #include "net/test/ct_test_util.h"
17 #include "testing/gtest/include/gtest/gtest.h"
24 scoped_ptr
<base::Value
> ParseJson(const std::string
& json
) {
25 base::JSONReader json_reader
;
26 return json_reader
.Read(json
).Pass();
30 TEST(CTLogResponseParserTest
, ParsesValidJsonSTH
) {
31 scoped_ptr
<base::Value
> sample_sth_json
= ParseJson(GetSampleSTHAsJson());
32 SignedTreeHead tree_head
;
33 EXPECT_TRUE(FillSignedTreeHead(*sample_sth_json
.get(), &tree_head
));
35 SignedTreeHead sample_sth
;
36 GetSampleSignedTreeHead(&sample_sth
);
38 ASSERT_EQ(SignedTreeHead::V1
, tree_head
.version
);
39 ASSERT_EQ(sample_sth
.timestamp
, tree_head
.timestamp
);
40 ASSERT_EQ(sample_sth
.tree_size
, tree_head
.tree_size
);
42 // Copy the field from the SignedTreeHead because it's not null terminated
43 // there and ASSERT_STREQ expects null-terminated strings.
44 char actual_hash
[kSthRootHashLength
+ 1];
45 memcpy(actual_hash
, tree_head
.sha256_root_hash
, kSthRootHashLength
);
46 actual_hash
[kSthRootHashLength
] = '\0';
47 std::string expected_sha256_root_hash
= GetSampleSTHSHA256RootHash();
48 ASSERT_STREQ(expected_sha256_root_hash
.c_str(), actual_hash
);
50 const DigitallySigned
& expected_signature(sample_sth
.signature
);
52 ASSERT_EQ(tree_head
.signature
.hash_algorithm
,
53 expected_signature
.hash_algorithm
);
54 ASSERT_EQ(tree_head
.signature
.signature_algorithm
,
55 expected_signature
.signature_algorithm
);
56 ASSERT_EQ(tree_head
.signature
.signature_data
,
57 expected_signature
.signature_data
);
60 TEST(CTLogResponseParserTest
, FailsToParseMissingFields
) {
61 scoped_ptr
<base::Value
> missing_signature_sth
= ParseJson(
62 CreateSignedTreeHeadJsonString(1 /* tree_size */, 123456u /* timestamp */,
63 GetSampleSTHSHA256RootHash(), ""));
65 SignedTreeHead tree_head
;
66 ASSERT_FALSE(FillSignedTreeHead(*missing_signature_sth
.get(), &tree_head
));
68 scoped_ptr
<base::Value
> missing_root_hash_sth
= ParseJson(
69 CreateSignedTreeHeadJsonString(1 /* tree_size */, 123456u /* timestamp */,
70 "", GetSampleSTHTreeHeadSignature()));
71 ASSERT_FALSE(FillSignedTreeHead(*missing_root_hash_sth
.get(), &tree_head
));
74 TEST(CTLogResponseParserTest
, FailsToParseIncorrectLengthRootHash
) {
75 SignedTreeHead tree_head
;
77 std::string too_long_hash
;
79 base::StringPiece("/WHFMgXtI/umKKuACJIN0Bb73TcILm9WkeU6qszvoArK\n"),
81 scoped_ptr
<base::Value
> too_long_hash_json
=
82 ParseJson(CreateSignedTreeHeadJsonString(
83 1 /* tree_size */, 123456u /* timestamp */,
84 GetSampleSTHSHA256RootHash(), too_long_hash
));
85 ASSERT_FALSE(FillSignedTreeHead(*too_long_hash_json
.get(), &tree_head
));
87 std::string too_short_hash
;
89 base::StringPiece("/WHFMgXtI/umKKuACJIN0Bb73TcILm9WkeU6qszvoA==\n"),
91 scoped_ptr
<base::Value
> too_short_hash_json
=
92 ParseJson(CreateSignedTreeHeadJsonString(
93 1 /* tree_size */, 123456u /* timestamp */,
94 GetSampleSTHSHA256RootHash(), too_short_hash
));
95 ASSERT_FALSE(FillSignedTreeHead(*too_short_hash_json
.get(), &tree_head
));