File: tpm_challenge_key.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (142 lines) | stat: -rw-r--r-- 5,909 bytes parent folder | download | duplicates (5)
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_ASH_ATTESTATION_TPM_CHALLENGE_KEY_H_
#define CHROME_BROWSER_ASH_ATTESTATION_TPM_CHALLENGE_KEY_H_

#include <memory>
#include <optional>
#include <string>

#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "chrome/browser/ash/attestation/tpm_challenge_key_result.h"
#include "chrome/browser/ash/attestation/tpm_challenge_key_subtle.h"
#include "chromeos/ash/components/dbus/attestation/attestation_ca.pb.h"
#include "chromeos/ash/components/dbus/attestation/keystore.pb.h"
#include "chromeos/ash/components/dbus/constants/attestation_constants.h"

class Profile;
class AttestationFlow;

namespace ash {
namespace attestation {

// Prefix for naming machine keys used for SignedPublicKeyAndChallenge when
// challenging the EMK with register=true.
inline constexpr char kEnterpriseMachineKeyForSpkacPrefix[] =
    "attest-ent-machine-";

//========================= TpmChallengeKeyFactory =============================

class TpmChallengeKey;

class TpmChallengeKeyFactory final {
 public:
  static std::unique_ptr<TpmChallengeKey> Create();
  static void SetForTesting(std::unique_ptr<TpmChallengeKey> next_result);

 private:
  static TpmChallengeKey* next_result_for_testing_;
};

//=========================== TpmChallengeKey ==================================

// Asynchronously runs the flow to challenge a key in the caller context. This
// is a wrapper around TpmChallengeKeySubtle with an easier-to-use interface.
// TpmChallengeKeySubtle can be used directly to get more control over main
// steps to build the response.
class TpmChallengeKey {
 public:
  TpmChallengeKey(const TpmChallengeKey&) = delete;
  TpmChallengeKey& operator=(const TpmChallengeKey&) = delete;
  virtual ~TpmChallengeKey() = default;

  // Should be called only once for every instance. |TpmChallengeKey| object
  // should live as long as response from |BuildResponse| function via
  // |callback| is expected. On destruction it stops challenge process and
  // silently discards callback.
  // The response consists of up to two parts: 1) a response to the challenge
  // and optionally 2) an SPKAC. They can be generated using different keys:
  // A) ENTERPRISE_MACHINE && !register_key
  // => 1) Stable device key + 2) Empty
  // B) ENTERPRISE_MACHINE && register_key
  // => 1) Stable device key + 2) Key(key_name)
  // C) ENTERPRISE_USER && !register_key
  // => 1) Key(key_name) + 2) Empty
  // D) ENTERPRISE_USER && register_key
  // => 1) Key(key_name) + 2) Key(key_name)
  // E) DEVICE_TRUST_CONNECTOR && !register_key
  // => 1) Key(key_name) + 2) Empty
  // In case B) |key_name| cannot be empty. In case C), D) some default name
  // will be used if |key_name| is empty.
  // When using DEVICE_TRUST_CONNECTOR, `register_key` is not supported and
  // `key_name` cannot be empty.
  // The response can also contain |signals| which consist of a set of
  // information about the device that is given to the IdP after the challenge
  // response has been verified. These signals can be used as input to an AuthN
  // decision. Signals are collected in a dictionary and are JSON stringified.
  // The signals are optional since they can be null when no signals are set on
  // the response, empty when no signals were collected (i.e empty signals
  // dictionary), or non empty. More information on signals collection can be
  // found in the |SignalsService|.

  virtual void BuildResponse(::attestation::VerifiedAccessFlow flow_type,
                             Profile* profile,
                             TpmChallengeKeyCallback callback,
                             const std::string& challenge,
                             bool register_key,
                             ::attestation::KeyType key_crypto_type,
                             const std::string& key_name,
                             const std::optional<std::string>& signals) = 0;

 protected:
  // Use TpmChallengeKeyFactory for creation.
  TpmChallengeKey() = default;
};

//=========================== TpmChallengeKeyImpl ==============================

class TpmChallengeKeyImpl final : public TpmChallengeKey {
 public:
  // Use TpmChallengeKeyFactory for creation.
  TpmChallengeKeyImpl();
  // Use only for testing.
  explicit TpmChallengeKeyImpl(
      AttestationFlow* attestation_flow_for_testing,
      MachineCertificateUploader* certificate_uploader_for_testing);
  TpmChallengeKeyImpl(const TpmChallengeKeyImpl&) = delete;
  TpmChallengeKeyImpl& operator=(const TpmChallengeKeyImpl&) = delete;
  ~TpmChallengeKeyImpl() override;

  // TpmChallengeKey
  void BuildResponse(::attestation::VerifiedAccessFlow flow_type,
                     Profile* profile,
                     TpmChallengeKeyCallback callback,
                     const std::string& challenge,
                     bool register_key,
                     ::attestation::KeyType key_crypto_type,
                     const std::string& key_name,
                     const std::optional<std::string>& signals) override;

 private:
  void OnPrepareKeyDone(const TpmChallengeKeyResult& prepare_key_result);
  void OnSignChallengeDone(const TpmChallengeKeyResult& sign_challenge_result);
  void OnRegisterKeyDone(const TpmChallengeKeyResult& challenge_response,
                         const TpmChallengeKeyResult& register_key_result);

  bool register_key_ = false;
  std::string challenge_;
  TpmChallengeKeyResult challenge_response_;
  TpmChallengeKeyCallback callback_;
  std::unique_ptr<TpmChallengeKeySubtle> tpm_challenge_key_subtle_;

  SEQUENCE_CHECKER(sequence_checker_);
  base::WeakPtrFactory<TpmChallengeKeyImpl> weak_factory_{this};
};

}  // namespace attestation
}  // namespace ash

#endif  // CHROME_BROWSER_ASH_ATTESTATION_TPM_CHALLENGE_KEY_H_