summaryrefslogtreecommitdiffstats
path: root/chrome/nacl/nacl_validation_query.h
blob: 6e4230e1918346b531350ee32c7024e19502be6f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_NACL_NACL_VALIDATION_QUERY_H_
#define CHROME_NACL_NACL_VALIDATION_QUERY_H_

#include <string>

#include "base/basictypes.h"
#include "base/string_piece.h"
#include "crypto/hmac.h"

struct NaClValidationCache;
class NaClValidationDB;
class NaClValidationQuery;

class NaClValidationQueryContext {
 public:
  NaClValidationQueryContext(NaClValidationDB* db,
                             const std::string& profile_key,
                             const std::string& nacl_version);

  NaClValidationQuery* CreateQuery();

 private:
  NaClValidationDB* db_;

  // A key used by HMAC that is specific to this installation of Chrome.
  std::string profile_key_;

  // Bytes indicating the "version" of the validator being used.  This is used
  // to implicitly invalidate the cache - changing the version will change the
  // hashes that are produced.
  std::string nacl_version_;
};

class NaClValidationQuery {
 public:
  // SHA256 digest size.
  static const int kDigestLength = 32;

  NaClValidationQuery(NaClValidationDB* db, const std::string& profile_key);

  void AddData(const char* data, size_t length);
  void AddData(const unsigned char* data, size_t length);
  void AddData(const base::StringPiece& data);

  int QueryKnownToValidate();

  void SetKnownToValidate();

 private:
  enum QueryState {
    READY,
    GET_CALLED,
    SET_CALLED
  };

  // The HMAC interface currently does not support incremental signing.  To work
  // around this, each piece of data is signed and the signature is added to a
  // buffer.  If there is not enough space in the buffer to accommodate new
  // data, the buffer contents are signed and the new signature replaces the
  // contents of the buffer.  CompressBuffer performs this operation.  In
  // affect, a hash tree is constructed to emulate incremental signing.
  void CompressBuffer();

  // Track the state of the query to detect suspicious method calls.
  QueryState state_;

  crypto::HMAC hasher_;
  NaClValidationDB* db_;

  // The size of buffer_ is a somewhat arbitrary choice.  It needs to be at
  // at least kDigestLength * 2, but it can be arbitrarily large.  In practice
  // there are 4 calls to AddData (version, architechture, cpu features, and
  // code), so 4 times digest length means the buffer will not need to be
  // compressed as an intermediate step in the expected use cases.
  char buffer_[kDigestLength * 4];
  int buffer_length_;

  DISALLOW_COPY_AND_ASSIGN(NaClValidationQuery);
};

// Create a validation cache interface for use by sel_ldr.
struct NaClValidationCache* CreateValidationCache(
    NaClValidationDB* db, const std::string& profile_key,
    const std::string& nacl_version);

#endif  // CHROME_NACL_NACL_VALIDATION_QUERY_H_