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
14struct NaClFileToken;
15struct NaClValidationCache;
16class NaClValidationDB;
17class NaClValidationQuery;
18
19class 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
42class 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.
90struct 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