virtual_fido_device.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. // Copyright 2018 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. #ifndef DEVICE_FIDO_VIRTUAL_FIDO_DEVICE_H_
  5. #define DEVICE_FIDO_VIRTUAL_FIDO_DEVICE_H_
  6. #include <stdint.h>
  7. #include <map>
  8. #include <memory>
  9. #include <string>
  10. #include <utility>
  11. #include <vector>
  12. #include "base/component_export.h"
  13. #include "base/containers/span.h"
  14. #include "base/memory/scoped_refptr.h"
  15. #include "device/fido/fido_constants.h"
  16. #include "device/fido/fido_device.h"
  17. #include "device/fido/fido_parsing_utils.h"
  18. #include "device/fido/large_blob.h"
  19. #include "device/fido/public_key_credential_descriptor.h"
  20. #include "device/fido/public_key_credential_rp_entity.h"
  21. #include "device/fido/public_key_credential_user_entity.h"
  22. #include "net/cert/x509_util.h"
  23. #include "third_party/abseil-cpp/absl/types/optional.h"
  24. #include "third_party/boringssl/src/include/openssl/base.h"
  25. namespace crypto {
  26. class ECPrivateKey;
  27. }
  28. namespace device {
  29. struct PublicKey;
  30. constexpr size_t kMaxPinRetries = 8;
  31. constexpr size_t kMaxUvRetries = 5;
  32. class COMPONENT_EXPORT(DEVICE_FIDO) VirtualFidoDevice : public FidoDevice {
  33. public:
  34. // PrivateKey abstracts over the private key types supported by the virtual
  35. // authenticator.
  36. class COMPONENT_EXPORT(DEVICE_FIDO) PrivateKey {
  37. public:
  38. // FromPKCS8 attempts to parse |pkcs8_private_key| as an ASN.1, DER, PKCS#8
  39. // private key of a supported type and returns a |PrivateKey| instance
  40. // representing that key.
  41. static absl::optional<std::unique_ptr<PrivateKey>> FromPKCS8(
  42. base::span<const uint8_t> pkcs8_private_key);
  43. // FreshP256Key returns a randomly generated P-256 PrivateKey.
  44. static std::unique_ptr<PrivateKey> FreshP256Key();
  45. // FreshRSAKey returns a randomly generated RSA PrivateKey.
  46. static std::unique_ptr<PrivateKey> FreshRSAKey();
  47. // FreshEd25519Key returns a randomly generated Ed25519 PrivateKey.
  48. static std::unique_ptr<PrivateKey> FreshEd25519Key();
  49. // FreshInvalidForTestingKey returns a dummy |PrivateKey| with a special
  50. // algorithm number that is used to test that unknown public keys are
  51. // handled correctly.
  52. static std::unique_ptr<PrivateKey> FreshInvalidForTestingKey();
  53. virtual ~PrivateKey();
  54. // Sign returns a signature over |message|.
  55. virtual std::vector<uint8_t> Sign(base::span<const uint8_t> message) = 0;
  56. // GetX962PublicKey returns the elliptic-curve public key encoded in X9.62
  57. // format. Only elliptic-curve based private keys can be represented in this
  58. // format and calling this function on other types of keys will crash.
  59. virtual std::vector<uint8_t> GetX962PublicKey() const;
  60. // GetPKCS8PrivateKey returns the private key encoded in ASN.1, DER, PKCS#8
  61. // format.
  62. virtual std::vector<uint8_t> GetPKCS8PrivateKey() const = 0;
  63. virtual std::unique_ptr<PublicKey> GetPublicKey() const = 0;
  64. };
  65. // Encapsulates information corresponding to one registered key on the virtual
  66. // authenticator device.
  67. struct COMPONENT_EXPORT(DEVICE_FIDO) RegistrationData {
  68. RegistrationData();
  69. explicit RegistrationData(const std::string& rp_id);
  70. RegistrationData(
  71. std::unique_ptr<PrivateKey> private_key,
  72. base::span<const uint8_t, kRpIdHashLength> application_parameter,
  73. uint32_t counter);
  74. RegistrationData(RegistrationData&& data);
  75. RegistrationData& operator=(RegistrationData&& other);
  76. RegistrationData(const RegistrationData&) = delete;
  77. RegistrationData& operator=(const RegistrationData&) = delete;
  78. ~RegistrationData();
  79. std::unique_ptr<PrivateKey> private_key = PrivateKey::FreshP256Key();
  80. std::array<uint8_t, kRpIdHashLength> application_parameter;
  81. uint32_t counter = 0;
  82. bool is_resident = false;
  83. // is_u2f is true if the credential was created via a U2F interface.
  84. bool is_u2f = false;
  85. device::CredProtect protection = device::CredProtect::kUVOptional;
  86. // user is only valid if |is_resident| is true.
  87. absl::optional<device::PublicKeyCredentialUserEntity> user;
  88. // rp is only valid if |is_resident| is true.
  89. absl::optional<device::PublicKeyCredentialRpEntity> rp;
  90. // hmac_key is present iff the credential has the hmac_secret extension
  91. // enabled. The first element of the pair is the HMAC key for non-UV, and
  92. // the second for when UV is used.
  93. absl::optional<std::pair<std::array<uint8_t, 32>, std::array<uint8_t, 32>>>
  94. hmac_key;
  95. absl::optional<std::array<uint8_t, 32>> large_blob_key;
  96. absl::optional<std::vector<uint8_t>> cred_blob;
  97. };
  98. // Stores the state of the device. Since |U2fDevice| objects only persist for
  99. // the lifetime of a single request, keeping state in an external object is
  100. // necessary in order to provide continuity between requests.
  101. class COMPONENT_EXPORT(DEVICE_FIDO) State : public base::RefCounted<State> {
  102. public:
  103. using RegistrationsMap = std::map<std::vector<uint8_t>,
  104. RegistrationData,
  105. fido_parsing_utils::RangeLess>;
  106. using SimulatePressCallback =
  107. base::RepeatingCallback<bool(VirtualFidoDevice*)>;
  108. State();
  109. State(const State&) = delete;
  110. State& operator=(const State&) = delete;
  111. // The common name in the attestation certificate.
  112. std::string attestation_cert_common_name;
  113. // The common name in the attestation certificate if individual attestation
  114. // is requested.
  115. std::string individual_attestation_cert_common_name;
  116. // Registered keys. Keyed on key handle (a.k.a. "credential ID").
  117. RegistrationsMap registrations;
  118. // If set, this callback is called whenever a "press" is required. Returning
  119. // `true` will simulate a press and continue the request, returning `false`
  120. // simulates the user not pressing the device and leaves the request idle.
  121. SimulatePressCallback simulate_press_callback;
  122. // If true, causes the response from the device to be invalid.
  123. bool simulate_invalid_response = false;
  124. // If true, return a packed self-attestation rather than a generated
  125. // certificate. This only has an effect for a CTAP2 device as
  126. // self-attestation is not defined for CTAP1.
  127. bool self_attestation = false;
  128. // Only valid if |self_attestation| is true. Causes the AAGUID to be non-
  129. // zero, in violation of the rules for self-attestation.
  130. bool non_zero_aaguid_with_self_attestation = false;
  131. // u2f_invalid_signature causes the signature in an assertion response to be
  132. // invalid. (U2F only.)
  133. bool u2f_invalid_signature = false;
  134. // u2f_invalid_public_key causes the public key in a registration response
  135. // to be invalid. (U2F only.)
  136. bool u2f_invalid_public_key = false;
  137. // Number of PIN retries remaining.
  138. int pin_retries = kMaxPinRetries;
  139. // The number of failed PIN attempts since the token was "inserted".
  140. int pin_retries_since_insertion = 0;
  141. // True if the token is soft-locked due to too many failed PIN attempts
  142. // since "insertion".
  143. bool soft_locked = false;
  144. // The PIN for the device, or an empty string if no PIN is set.
  145. std::string pin;
  146. // The elliptic-curve key. (Not expected to be set externally.)
  147. bssl::UniquePtr<EC_KEY> ecdh_key;
  148. // The random PIN token that is returned as a placeholder for the PIN
  149. // itself.
  150. uint8_t pin_token[32];
  151. // The permissions parameter for |pin_token|.
  152. uint8_t pin_uv_token_permissions = 0;
  153. // The permissions RPID for |pin_token|.
  154. absl::optional<std::string> pin_uv_token_rpid;
  155. // If true, fail all PinUvAuthToken requests until a new PIN is set.
  156. bool force_pin_change = false;
  157. // The minimum PIN length as unicode code points.
  158. uint32_t min_pin_length = kMinPinLength;
  159. // Number of internal UV retries remaining.
  160. int uv_retries = kMaxUvRetries;
  161. // Whether a device with internal-UV support has fingerprints enrolled.
  162. bool fingerprints_enrolled = false;
  163. // Whether a device with bio enrollment support has been provisioned.
  164. bool bio_enrollment_provisioned = false;
  165. // Current template ID being enrolled, if any.
  166. absl::optional<uint8_t> bio_current_template_id;
  167. // Number of remaining samples in current enrollment.
  168. uint8_t bio_remaining_samples = 4;
  169. // Backing storage for enrollments and their friendly names.
  170. std::map<uint8_t, std::string> bio_templates;
  171. // Whether the next authenticatorBioEnrollment command with a
  172. // enrollCaptureNextSample subCommand should return a
  173. // CTAP2_ENROLL_FEEDBACK_TOO_HIGH response. Will be reset to false upon
  174. // returning the error.
  175. bool bio_enrollment_next_sample_error = false;
  176. // Whether the next authenticatorBioEnrollment command with a
  177. // enrollCaptureNextSample subCommand should return a
  178. // CTAP2_ENROLL_FEEDBACK_NO_USER_ACTIVITY response. Will be reset to false
  179. // upon returning the error.
  180. bool bio_enrollment_next_sample_timeout = false;
  181. // allow_list_history contains the allow_list values that have been seen in
  182. // assertion requests. This is for tests to confirm that the expected
  183. // sequence of requests was sent.
  184. std::vector<std::vector<PublicKeyCredentialDescriptor>> allow_list_history;
  185. // exclude_list_history contains the exclude_list values that have been seen
  186. // in registration requests. This is for tests to confirm that the expected
  187. // sequence of requests was sent.
  188. std::vector<std::vector<PublicKeyCredentialDescriptor>>
  189. exclude_list_history;
  190. // |cancel_response_code| is the response code the authenticator will return
  191. // when cancelling a pending request. Normally authenticators return
  192. // CTAP2_ERR_KEEP_ALIVE_CANCEL, but some authenticators incorrectly return
  193. // other codes.
  194. CtapDeviceResponseCode cancel_response_code =
  195. CtapDeviceResponseCode::kCtap2ErrKeepAliveCancel;
  196. // The large-blob array.
  197. std::vector<uint8_t> large_blob;
  198. FidoTransportProtocol transport =
  199. FidoTransportProtocol::kUsbHumanInterfaceDevice;
  200. // transact_callback contains the outstanding callback in the event that
  201. // |simulate_press_callback| returned false. This can be used to inject a
  202. // response after simulating an unsatisfied touch for CTAP2 authenticators.
  203. FidoDevice::DeviceCallback transact_callback;
  204. // device_id_override can be used to inject a return value for `GetId()` in
  205. // unit tests where a stable device identifier is required.
  206. absl::optional<std::string> device_id_override;
  207. // Adds a new credential to the authenticator. Returns true on success,
  208. // false if there already exists a credential with the given ID.
  209. bool InjectRegistration(base::span<const uint8_t> credential_id,
  210. RegistrationData registration);
  211. // Adds a registration for the specified credential ID with the application
  212. // parameter set to be valid for the given relying party ID (which would
  213. // typically be a domain, e.g. "example.com").
  214. //
  215. // Returns true on success. Will fail if there already exists a credential
  216. // with the given ID or if private-key generation fails.
  217. bool InjectRegistration(base::span<const uint8_t> credential_id,
  218. const std::string& relying_party_id);
  219. // Adds a resident credential with the specified values.
  220. // Returns false if there already exists a resident credential for the same
  221. // (RP ID, user ID) pair, or for the same credential ID. Otherwise returns
  222. // true.
  223. bool InjectResidentKey(base::span<const uint8_t> credential_id,
  224. device::PublicKeyCredentialRpEntity rp,
  225. device::PublicKeyCredentialUserEntity user,
  226. int32_t signature_counter,
  227. std::unique_ptr<PrivateKey> private_key);
  228. // Adds a resident credential with the specified values, creating a new
  229. // private key.
  230. // Returns false if there already exists a resident credential for the same
  231. // (RP ID, user ID) pair, or for the same credential ID. Otherwise returns
  232. // true.
  233. bool InjectResidentKey(base::span<const uint8_t> credential_id,
  234. device::PublicKeyCredentialRpEntity rp,
  235. device::PublicKeyCredentialUserEntity user);
  236. // Version of InjectResidentKey that takes values for constructing an RP and
  237. // user entity.
  238. bool InjectResidentKey(base::span<const uint8_t> credential_id,
  239. const std::string& relying_party_id,
  240. base::span<const uint8_t> user_id,
  241. absl::optional<std::string> user_name,
  242. absl::optional<std::string> user_display_name);
  243. // Returns the large blob associated with the credential, if any.
  244. absl::optional<LargeBlob> GetLargeBlob(const RegistrationData& credential);
  245. // Injects a large blob for the credential. If the credential already has an
  246. // associated large blob, replaces it. If the |large_blob| is malformed,
  247. // completely replaces its contents.
  248. void InjectLargeBlob(RegistrationData* credential, LargeBlob blob);
  249. // Clears all large blobs resetting |large_blob| to its default value.
  250. void ClearLargeBlobs();
  251. private:
  252. friend class base::RefCounted<State>;
  253. ~State();
  254. };
  255. // Constructs an object with ephemeral state. In order to have the state of
  256. // the device persist between operations, use the constructor that takes a
  257. // scoped_refptr<State>.
  258. VirtualFidoDevice();
  259. // Constructs an object that will read from, and write to, |state|.
  260. explicit VirtualFidoDevice(scoped_refptr<State> state);
  261. VirtualFidoDevice(const VirtualFidoDevice&) = delete;
  262. VirtualFidoDevice& operator=(const VirtualFidoDevice&) = delete;
  263. ~VirtualFidoDevice() override;
  264. State* mutable_state() const { return state_.get(); }
  265. // FidoDevice:
  266. std::string GetId() const override;
  267. protected:
  268. static std::vector<uint8_t> GetAttestationKey();
  269. scoped_refptr<State> NewReferenceToState() const { return state_; }
  270. static bool Sign(crypto::ECPrivateKey* private_key,
  271. base::span<const uint8_t> sign_buffer,
  272. std::vector<uint8_t>* signature);
  273. // Constructs certificate encoded in X.509 format to be used for packed
  274. // attestation statement and FIDO-U2F attestation statement.
  275. // https://w3c.github.io/webauthn/#defined-attestation-formats
  276. absl::optional<std::vector<uint8_t>> GenerateAttestationCertificate(
  277. bool individual_attestation_requested,
  278. bool include_transports) const;
  279. void StoreNewKey(base::span<const uint8_t> key_handle,
  280. VirtualFidoDevice::RegistrationData registration_data);
  281. RegistrationData* FindRegistrationData(
  282. base::span<const uint8_t> key_handle,
  283. base::span<const uint8_t, kRpIdHashLength> application_parameter);
  284. // Simulates flashing the device for a press and potentially receiving one.
  285. // Returns true if the "user" pressed the device (and the request must
  286. // continue) or false if the user didn't, and the request must be dropped.
  287. // Internally calls |state_->simulate_press_callback|, so |this| may be
  288. // destroyed after calling this method, in which case it will return false.
  289. bool SimulatePress();
  290. // FidoDevice:
  291. void TryWink(base::OnceClosure cb) override;
  292. FidoTransportProtocol DeviceTransport() const override;
  293. private:
  294. static std::string MakeVirtualFidoDeviceId();
  295. const std::string id_ = MakeVirtualFidoDeviceId();
  296. scoped_refptr<State> state_ = base::MakeRefCounted<State>();
  297. };
  298. } // namespace device
  299. #endif // DEVICE_FIDO_VIRTUAL_FIDO_DEVICE_H_