Home | History | Annotate | Download | only in extensions
      1 // Copyright 2013 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 #ifndef CHROME_BROWSER_EXTENSIONS_INSTALL_SIGNER_H_
      6 #define CHROME_BROWSER_EXTENSIONS_INSTALL_SIGNER_H_
      7 
      8 #include <set>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/callback.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "extensions/common/extension.h"
     16 
     17 namespace base {
     18 class DictionaryValue;
     19 }
     20 
     21 namespace net {
     22 class URLFetcher;
     23 class URLRequestContextGetter;
     24 }
     25 
     26 namespace extensions {
     27 
     28 // This represents a list of ids signed with a private key using an algorithm
     29 // that includes some salt bytes.
     30 struct InstallSignature {
     31   // The set of ids that have been signed.
     32   ExtensionIdSet ids;
     33 
     34   // Both of these are just arrays of bytes, NOT base64-encoded.
     35   std::string salt;
     36   std::string signature;
     37 
     38   // The date that the signature should expire, in YYYY-MM-DD format.
     39   std::string expire_date;
     40 
     41   // The time this signature was obtained from the server. Note that this
     42   // is computed locally and *not* signed by the server key.
     43   base::Time timestamp;
     44 
     45   // The set of ids that the server indicated were invalid (ie not signed).
     46   // Note that this is computed locally and *not* signed by the signature.
     47   ExtensionIdSet invalid_ids;
     48 
     49   InstallSignature();
     50   ~InstallSignature();
     51 
     52   // Helper methods for serialization to/from a base::DictionaryValue.
     53   void ToValue(base::DictionaryValue* value) const;
     54 
     55   static scoped_ptr<InstallSignature> FromValue(
     56       const base::DictionaryValue& value);
     57 };
     58 
     59 // Objects of this class encapsulate an operation to get a signature proving
     60 // that a set of ids are hosted in the webstore.
     61 class InstallSigner {
     62  public:
     63   typedef base::Callback<void(scoped_ptr<InstallSignature>)> SignatureCallback;
     64 
     65   // IMPORTANT NOTE: It is possible that only some, but not all, of the entries
     66   // in |ids| will be successfully signed by the backend. Callers should always
     67   // check the set of ids in the InstallSignature passed to their callback, as
     68   // it may contain only a subset of the ids they passed in.
     69   InstallSigner(net::URLRequestContextGetter* context_getter,
     70                 const ExtensionIdSet& ids);
     71   ~InstallSigner();
     72 
     73   // Returns a set of ids that are forced to be considered not from webstore,
     74   // e.g. by a command line flag used for testing.
     75   static ExtensionIdSet GetForcedNotFromWebstore();
     76 
     77   // Begins the process of fetching a signature from the backend. This should
     78   // only be called once! If you want to get another signature, make another
     79   // instance of this class.
     80   void GetSignature(const SignatureCallback& callback);
     81 
     82   // Returns whether the signature in InstallSignature is properly signed with a
     83   // known public key.
     84   static bool VerifySignature(const InstallSignature& signature);
     85 
     86  private:
     87   // A very simple delegate just used to call ourself back when a url fetch is
     88   // complete.
     89   class FetcherDelegate;
     90 
     91   // A helper function that calls |callback_| with an indication that an error
     92   // happened (currently done by passing an empty pointer).
     93   void ReportErrorViaCallback();
     94 
     95   // Called when |url_fetcher_| has returned a result to parse the response,
     96   // and then call HandleSignatureResult with structured data.
     97   void ParseFetchResponse();
     98 
     99   // Handles the result from a backend fetch.
    100   void HandleSignatureResult(const std::string& signature,
    101                              const std::string& expire_date,
    102                              const ExtensionIdSet& invalid_ids);
    103 
    104   // The final callback for when we're done.
    105   SignatureCallback callback_;
    106 
    107   // The current set of ids we're trying to verify. This may contain fewer ids
    108   // than we started with.
    109   ExtensionIdSet ids_;
    110 
    111   // An array of random bytes used as an input to hash with the machine id,
    112   // which will need to be persisted in the eventual InstallSignature we get.
    113   std::string salt_;
    114 
    115   // These are used to make the call to a backend server for a signature.
    116   net::URLRequestContextGetter* context_getter_;
    117   scoped_ptr<net::URLFetcher> url_fetcher_;
    118   scoped_ptr<FetcherDelegate> delegate_;
    119 
    120   // The time the request to the server was started.
    121   base::Time request_start_time_;
    122 
    123   DISALLOW_COPY_AND_ASSIGN(InstallSigner);
    124 };
    125 
    126 }  // namespace extensions
    127 
    128 #endif  // CHROME_BROWSER_EXTENSIONS_INSTALL_SIGNER_H_
    129