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 <string> 6#include <vector> 7 8#include "base/base64.h" 9#include "base/files/file_path.h" 10#include "base/files/file_util.h" 11#include "base/path_service.h" 12#include "base/stl_util.h" 13#include "extensions/browser/verified_contents.h" 14#include "extensions/common/extension.h" 15#include "extensions/common/extension_paths.h" 16#include "testing/gtest/include/gtest/gtest.h" 17 18namespace extensions { 19 20namespace { 21 22std::string DecodeBase64Url(const std::string& encoded) { 23 std::string fixed_up_base64 = encoded; 24 if (!VerifiedContents::FixupBase64Encoding(&fixed_up_base64)) 25 return std::string(); 26 std::string decoded; 27 if (!base::Base64Decode(fixed_up_base64, &decoded)) 28 return std::string(); 29 return decoded; 30} 31 32bool GetPublicKey(const base::FilePath& path, std::string* public_key) { 33 std::string public_key_pem; 34 if (!base::ReadFileToString(path, &public_key_pem)) 35 return false; 36 if (!Extension::ParsePEMKeyBytes(public_key_pem, public_key)) 37 return false; 38 return true; 39} 40 41} // namespace 42 43TEST(VerifiedContents, Simple) { 44 // Figure out our test data directory. 45 base::FilePath path; 46 PathService::Get(DIR_TEST_DATA, &path); 47 path = path.AppendASCII("content_verifier/"); 48 49 // Initialize the VerifiedContents object. 50 std::string public_key; 51 ASSERT_TRUE(GetPublicKey(path.AppendASCII("public_key.pem"), &public_key)); 52 VerifiedContents contents(reinterpret_cast<const uint8*>(public_key.data()), 53 public_key.size()); 54 base::FilePath verified_contents_path = 55 path.AppendASCII("verified_contents.json"); 56 57 ASSERT_TRUE(contents.InitFrom(verified_contents_path, false)); 58 59 // Make sure we get expected values. 60 EXPECT_EQ(contents.block_size(), 4096); 61 EXPECT_EQ(contents.extension_id(), "abcdefghijklmnopabcdefghijklmnop"); 62 EXPECT_EQ("1.2.3", contents.version().GetString()); 63 64 EXPECT_TRUE(contents.TreeHashRootEquals( 65 base::FilePath::FromUTF8Unsafe("manifest.json"), 66 DecodeBase64Url("-vyyIIn7iSCzg7X3ICUI5wZa3tG7w7vyiCckxZdJGfs"))); 67 68 EXPECT_TRUE(contents.TreeHashRootEquals( 69 base::FilePath::FromUTF8Unsafe("background.js"), 70 DecodeBase64Url("txHiG5KQvNoPOSH5FbQo9Zb5gJ23j3oFB0Ru9DOnziw"))); 71 72 base::FilePath foo_bar_html = 73 base::FilePath(FILE_PATH_LITERAL("foo")).AppendASCII("bar.html"); 74 EXPECT_FALSE(foo_bar_html.IsAbsolute()); 75 EXPECT_TRUE(contents.TreeHashRootEquals( 76 foo_bar_html, 77 DecodeBase64Url("L37LFbT_hmtxRL7AfGZN9YTpW6yoz_ZiQ1opLJn1NZU"))); 78 79 base::FilePath nonexistent = base::FilePath::FromUTF8Unsafe("nonexistent"); 80 EXPECT_FALSE(contents.HasTreeHashRoot(nonexistent)); 81 82 EXPECT_TRUE(contents.TreeHashRootEquals( 83 base::FilePath::FromUTF8Unsafe("lowercase.html"), 84 DecodeBase64Url("HpLotLGCmmOdKYvGQmD3OkXMKGs458dbanY4WcfAZI0"))); 85 EXPECT_TRUE(contents.TreeHashRootEquals( 86 base::FilePath::FromUTF8Unsafe("Lowercase.Html"), 87 DecodeBase64Url("HpLotLGCmmOdKYvGQmD3OkXMKGs458dbanY4WcfAZI0"))); 88 EXPECT_TRUE(contents.TreeHashRootEquals( 89 base::FilePath::FromUTF8Unsafe("LOWERCASE.HTML"), 90 DecodeBase64Url("HpLotLGCmmOdKYvGQmD3OkXMKGs458dbanY4WcfAZI0"))); 91 92 EXPECT_TRUE(contents.TreeHashRootEquals( 93 base::FilePath::FromUTF8Unsafe("ALLCAPS.HTML"), 94 DecodeBase64Url("bl-eV8ENowvtw6P14D4X1EP0mlcMoG-_aOx5o9C1364"))); 95 EXPECT_TRUE(contents.TreeHashRootEquals( 96 base::FilePath::FromUTF8Unsafe("AllCaps.Html"), 97 DecodeBase64Url("bl-eV8ENowvtw6P14D4X1EP0mlcMoG-_aOx5o9C1364"))); 98 EXPECT_TRUE(contents.TreeHashRootEquals( 99 base::FilePath::FromUTF8Unsafe("allcaps.html"), 100 DecodeBase64Url("bl-eV8ENowvtw6P14D4X1EP0mlcMoG-_aOx5o9C1364"))); 101 102 EXPECT_TRUE(contents.TreeHashRootEquals( 103 base::FilePath::FromUTF8Unsafe("MixedCase.Html"), 104 DecodeBase64Url("zEAO9FwciigMNy3NtU2XNb-dS5TQMmVNx0T9h7WvXbQ"))); 105 EXPECT_TRUE(contents.TreeHashRootEquals( 106 base::FilePath::FromUTF8Unsafe("MIXEDCASE.HTML"), 107 DecodeBase64Url("zEAO9FwciigMNy3NtU2XNb-dS5TQMmVNx0T9h7WvXbQ"))); 108 EXPECT_TRUE(contents.TreeHashRootEquals( 109 base::FilePath::FromUTF8Unsafe("mixedcase.html"), 110 DecodeBase64Url("zEAO9FwciigMNy3NtU2XNb-dS5TQMmVNx0T9h7WvXbQ"))); 111 EXPECT_TRUE(contents.TreeHashRootEquals( 112 base::FilePath::FromUTF8Unsafe("mIxedcAse.Html"), 113 DecodeBase64Url("zEAO9FwciigMNy3NtU2XNb-dS5TQMmVNx0T9h7WvXbQ"))); 114 115 EXPECT_TRUE(contents.TreeHashRootEquals( 116 base::FilePath::FromUTF8Unsafe("mIxedcAse.Html"), 117 DecodeBase64Url("nKRqUcJg1_QZWAeCb4uFd5ouC0McuGavKp8TFDRqBgg"))); 118 EXPECT_TRUE(contents.TreeHashRootEquals( 119 base::FilePath::FromUTF8Unsafe("MIXEDCASE.HTML"), 120 DecodeBase64Url("nKRqUcJg1_QZWAeCb4uFd5ouC0McuGavKp8TFDRqBgg"))); 121 EXPECT_TRUE(contents.TreeHashRootEquals( 122 base::FilePath::FromUTF8Unsafe("mixedcase.html"), 123 DecodeBase64Url("nKRqUcJg1_QZWAeCb4uFd5ouC0McuGavKp8TFDRqBgg"))); 124 EXPECT_TRUE(contents.TreeHashRootEquals( 125 base::FilePath::FromUTF8Unsafe("MixedCase.Html"), 126 DecodeBase64Url("nKRqUcJg1_QZWAeCb4uFd5ouC0McuGavKp8TFDRqBgg"))); 127} 128 129} // namespace extensions 130