• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "net/cert/ct_log_response_parser.h"
6 
7 #include <string>
8 
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"
15 
16 namespace net {
17 
18 namespace ct {
19 
CreateSignedTreeHeadJsonString(std::string sha256_root_hash,std::string tree_head_signature)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";
23 
24   if (!sha256_root_hash.empty()) {
25     sth_json += base::StringPrintf(",\"sha256_root_hash\":\"%s\"",
26                                    sha256_root_hash.c_str());
27   }
28   if (!tree_head_signature.empty()) {
29     sth_json += base::StringPrintf(",\"tree_head_signature\":\"%s\"",
30                                    tree_head_signature.c_str());
31   }
32 
33   sth_json += "}";
34   return sth_json;
35 }
36 
37 const char kSHA256RootHash[] = "/WHFMgXtI/umKKuACJIN0Bb73TcILm9WkeU6qszvoAo=";
38 
39 const char kTreeHeadSignature[] =
40     "BAMARzBFAiAB+IIYrkRsZDW0/6TzPgR+aJ26twCQ1JDTwq/"
41     "mpinCjAIhAKDXdXMtqbvQ42r9dBIwV5RM/KpEzNQdIhXHesd9HPv3";
42 
TEST(CTLogResponseParserTest,ParsesValidJsonSTH)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));
48 
49   base::Time expected_timestamp =
50       base::Time::UnixEpoch() +
51       base::TimeDelta::FromMilliseconds(1395761621447);
52 
53   ASSERT_EQ(SignedTreeHead::V1, tree_head.version);
54   ASSERT_EQ(expected_timestamp, tree_head.timestamp);
55   ASSERT_EQ(2903698u, tree_head.tree_size);
56 
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);
65 
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));
71 
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);
78 }
79 
TEST(CTLogResponseParserTest,FailsToParseMissingFields)80 TEST(CTLogResponseParserTest, FailsToParseMissingFields) {
81   std::string missing_signature_sth =
82       CreateSignedTreeHeadJsonString(kSHA256RootHash, "");
83 
84   SignedTreeHead tree_head;
85   ASSERT_FALSE(FillSignedTreeHead(missing_signature_sth, &tree_head));
86 
87   std::string missing_root_hash_sth =
88       CreateSignedTreeHeadJsonString("", kTreeHeadSignature);
89   ASSERT_FALSE(FillSignedTreeHead(missing_root_hash_sth, &tree_head));
90 }
91 
TEST(CTLogResponseParserTest,FailsToParseIncorrectLengthRootHash)92 TEST(CTLogResponseParserTest, FailsToParseIncorrectLengthRootHash) {
93   SignedTreeHead tree_head;
94 
95   std::string too_long_hash = CreateSignedTreeHeadJsonString(
96       kSHA256RootHash, "/WHFMgXtI/umKKuACJIN0Bb73TcILm9WkeU6qszvoArK\n");
97   ASSERT_FALSE(FillSignedTreeHead(too_long_hash, &tree_head));
98 
99   std::string too_short_hash = CreateSignedTreeHeadJsonString(
100       kSHA256RootHash, "/WHFMgXtI/umKKuACJIN0Bb73TcILm9WkeU6qszvoA==\n");
101   ASSERT_FALSE(FillSignedTreeHead(too_short_hash, &tree_head));
102 }
103 
104 }  // namespace ct
105 
106 }  // namespace net
107