• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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