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