1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file. 4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#ifndef EXTENSIONS_BROWSER_VERIFIED_CONTENTS_H_ 6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#define EXTENSIONS_BROWSER_VERIFIED_CONTENTS_H_ 7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 8010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <map> 9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <string> 10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include <vector> 11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/files/file_path.h" 13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/version.h" 14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace extensions { 16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// This class encapsulates the data in a "verified_contents.json" file 18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// generated by the webstore for a .crx file. That data includes a set of 19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// signed expected hashes of file content which can be used to check for 20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// corruption of extension files on local disk. 21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class VerifiedContents { 22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public: 23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // This function fixes up a string in base64url encoding to be in standard 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // base64. 25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // 26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // The JSON signing spec we're following uses "base64url" encoding (RFC 4648 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // section 5 without padding). The slight differences from regular base64 28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // encoding are: 29cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // 1. uses '_' instead of '/' 30cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // 2. uses '-' instead of '+' 31cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // 3. omits trailing '=' padding 32cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) static bool FixupBase64Encoding(std::string* input); 33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 34010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Note: the public_key must remain valid for the lifetime of this object. 35010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) VerifiedContents(const uint8* public_key, int public_key_size); 36010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) ~VerifiedContents(); 37010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 38010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Returns true if we successfully parsed the verified_contents.json file at 39010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // |path| and validated the enclosed signature. The 40010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // |ignore_invalid_signature| argument can be set to make this still succeed 41010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // if the contents of the file were parsed successfully but the signature did 42010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // not validate. (Use with caution!) 43010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool InitFrom(const base::FilePath& path, bool ignore_invalid_signature); 44010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 45010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int block_size() const { return block_size_; } 46010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& extension_id() const { return extension_id_; } 47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const base::Version& version() const { return version_; } 48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool HasTreeHashRoot(const base::FilePath& relative_path) const; 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool TreeHashRootEquals(const base::FilePath& relative_path, 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string& expected) const; 53010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 54010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // If InitFrom has not been called yet, or was used in "ignore invalid 55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // signature" mode, this can return false. 56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool valid_signature() { return valid_signature_; } 57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private: 59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Returns the base64url-decoded "payload" field from the json at |path|, if 60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // the signature was valid (or ignore_invalid_signature was set to true). 61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool GetPayload(const base::FilePath& path, 62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string* payload, 63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool ignore_invalid_signature); 64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The |protected_value| and |payload| arguments should be base64url encoded 66010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // strings, and |signature_bytes| should be a byte array. See comments in the 67010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // .cc file on GetPayload for where these come from in the overall input 68010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // file. 69010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool VerifySignature(const std::string& protected_value, 70010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& payload, 71010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const std::string& signature_bytes); 72010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 73010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The public key we should use for signature verification. 74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const uint8* public_key_; 75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) const int public_key_size_; 76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Indicates whether the signature was successfully validated or not. 78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) bool valid_signature_; 79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // The block size used for computing the treehash root hashes. 81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) int block_size_; 82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Information about which extension these signed hashes are for. 84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) std::string extension_id_; 85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) base::Version version_; 86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The expected treehash root hashes for each file, lower cased so we can do 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // case-insensitive lookups. 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // We use a multi-map here so that we can do fast lookups of paths from 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // requests on case-insensitive systems (windows, mac) where the request path 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // might not have the exact right capitalization, but not break 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // case-sensitive systems (linux, chromeos). TODO(asargent) - we should give 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // developers client-side warnings in each of those cases, and have the 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // webstore reject the cases they can statically detect. See crbug.com/29941 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci typedef std::multimap<base::FilePath::StringType, std::string> RootHashes; 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RootHashes root_hashes_; 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DISALLOW_COPY_AND_ASSIGN(VerifiedContents); 100010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}; 101010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 102010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)} // namespace extensions 103010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) 104010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif // EXTENSIONS_BROWSER_VERIFIED_CONTENTS_H_ 105