Home | History | Annotate | Download | only in loader
      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 COMPONENTS_NACL_LOADER_NACL_VALIDATION_QUERY_H_
      6 #define COMPONENTS_NACL_LOADER_NACL_VALIDATION_QUERY_H_
      7 
      8 #include <string>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/strings/string_piece.h"
     12 #include "crypto/hmac.h"
     13 
     14 struct NaClFileToken;
     15 struct NaClValidationCache;
     16 class NaClValidationDB;
     17 class NaClValidationQuery;
     18 
     19 class NaClValidationQueryContext {
     20  public:
     21   NaClValidationQueryContext(NaClValidationDB* db,
     22                              const std::string& profile_key,
     23                              const std::string& nacl_version);
     24 
     25   NaClValidationQuery* CreateQuery();
     26 
     27   bool ResolveFileToken(struct NaClFileToken* file_token, int32* fd,
     28                         std::string* path);
     29 
     30  private:
     31   NaClValidationDB* db_;
     32 
     33   // A key used by HMAC that is specific to this installation of Chrome.
     34   std::string profile_key_;
     35 
     36   // Bytes indicating the "version" of the validator being used.  This is used
     37   // to implicitly invalidate the cache - changing the version will change the
     38   // hashes that are produced.
     39   std::string nacl_version_;
     40 };
     41 
     42 class NaClValidationQuery {
     43  public:
     44   // SHA256 digest size.
     45   static const size_t kDigestLength = 32;
     46 
     47   NaClValidationQuery(NaClValidationDB* db, const std::string& profile_key);
     48 
     49   void AddData(const char* data, size_t length);
     50   void AddData(const unsigned char* data, size_t length);
     51   void AddData(const base::StringPiece& data);
     52 
     53   int QueryKnownToValidate();
     54 
     55   void SetKnownToValidate();
     56 
     57  private:
     58   enum QueryState {
     59     READY,
     60     GET_CALLED,
     61     SET_CALLED
     62   };
     63 
     64   // The HMAC interface currently does not support incremental signing.  To work
     65   // around this, each piece of data is signed and the signature is added to a
     66   // buffer.  If there is not enough space in the buffer to accommodate new
     67   // data, the buffer contents are signed and the new signature replaces the
     68   // contents of the buffer.  CompressBuffer performs this operation.  In
     69   // affect, a hash tree is constructed to emulate incremental signing.
     70   void CompressBuffer();
     71 
     72   // Track the state of the query to detect suspicious method calls.
     73   QueryState state_;
     74 
     75   crypto::HMAC hasher_;
     76   NaClValidationDB* db_;
     77 
     78   // The size of buffer_ is a somewhat arbitrary choice.  It needs to be at
     79   // at least kDigestLength * 2, but it can be arbitrarily large.  In practice
     80   // there are 4 calls to AddData (version, architechture, cpu features, and
     81   // code), so 4 times digest length means the buffer will not need to be
     82   // compressed as an intermediate step in the expected use cases.
     83   char buffer_[kDigestLength * 4];
     84   size_t buffer_length_;
     85 
     86   DISALLOW_COPY_AND_ASSIGN(NaClValidationQuery);
     87 };
     88 
     89 // Create a validation cache interface for use by sel_ldr.
     90 struct NaClValidationCache* CreateValidationCache(
     91     NaClValidationDB* db, const std::string& profile_key,
     92     const std::string& nacl_version);
     93 
     94 #endif  // COMPONENTS_NACL_LOADER_NACL_VALIDATION_QUERY_H_
     95