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