1 // Copyright 2017 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 DEVICE_FIDO_AUTHENTICATOR_DATA_H_
6 #define DEVICE_FIDO_AUTHENTICATOR_DATA_H_
7 
8 #include <stdint.h>
9 
10 #include <array>
11 #include <string>
12 #include <vector>
13 
14 #include "base/component_export.h"
15 #include "base/containers/span.h"
16 #include "base/macros.h"
17 #include "base/numerics/safe_conversions.h"
18 #include "base/optional.h"
19 #include "components/cbor/values.h"
20 #include "device/fido/attested_credential_data.h"
21 #include "device/fido/fido_constants.h"
22 
23 namespace device {
24 
25 // https://www.w3.org/TR/2017/WD-webauthn-20170505/#sec-authenticator-data.
COMPONENT_EXPORT(DEVICE_FIDO)26 class COMPONENT_EXPORT(DEVICE_FIDO) AuthenticatorData {
27  public:
28   enum class Flag : uint8_t {
29     kTestOfUserPresence = 1u << 0,
30     kTestOfUserVerification = 1u << 2,
31     kAttestation = 1u << 6,
32     kExtensionDataIncluded = 1u << 7,
33   };
34 
35   static base::Optional<AuthenticatorData> DecodeAuthenticatorData(
36       base::span<const uint8_t> auth_data);
37 
38   //  The attested credential |data| must be specified iff |flags| have
39   //  kAttestation set; and |extensions| must be specified iff |flags| have
40   //  kExtensionDataIncluded set.
41   AuthenticatorData(
42       base::span<const uint8_t, kRpIdHashLength> application_parameter,
43       uint8_t flags,
44       base::span<const uint8_t, kSignCounterLength> counter,
45       base::Optional<AttestedCredentialData> data,
46       base::Optional<cbor::Value> extensions = base::nullopt);
47 
48   // Moveable.
49   AuthenticatorData(AuthenticatorData&& other);
50   AuthenticatorData& operator=(AuthenticatorData&& other);
51 
52   ~AuthenticatorData();
53 
54   // Replaces device AAGUID in attested credential data section with zeros.
55   // https://w3c.github.io/webauthn/#attested-credential-data
56   void DeleteDeviceAaguid();
57 
58   // Produces a byte array consisting of:
59   // * hash(relying_party_id / appid)
60   // * flags
61   // * counter
62   // * attestation_data.
63   std::vector<uint8_t> SerializeToByteArray() const;
64 
65   // Retrieve credential ID from attested credential data section of the
66   // authenticator data.
67   std::vector<uint8_t> GetCredentialId() const;
68 
69   const base::Optional<AttestedCredentialData>& attested_data() const {
70     return attested_data_;
71   }
72 
73   // If a value is returned then the result of calling |is_map()| on it can be
74   // assumed to be true.
75   const base::Optional<cbor::Value>& extensions() const { return extensions_; }
76 
77   const std::array<uint8_t, kRpIdHashLength>& application_parameter() const {
78     return application_parameter_;
79   }
80 
81   bool obtained_user_presence() const {
82     return flags_ & base::strict_cast<uint8_t>(Flag::kTestOfUserPresence);
83   }
84 
85   bool obtained_user_verification() const {
86     return flags_ & base::strict_cast<uint8_t>(Flag::kTestOfUserVerification);
87   }
88 
89   bool attestation_credential_included() const {
90     return flags_ & base::strict_cast<uint8_t>(Flag::kAttestation);
91   }
92 
93   bool extension_data_included() const {
94     return flags_ & base::strict_cast<uint8_t>(Flag::kExtensionDataIncluded);
95   }
96 
97   base::span<const uint8_t, kSignCounterLength> counter() const {
98     return counter_;
99   }
100 
101  private:
102   // The application parameter: a SHA-256 hash of either the RP ID or the AppID
103   // associated with the credential.
104   std::array<uint8_t, kRpIdHashLength> application_parameter_;
105 
106   // Flags (bit 0 is the least significant bit):
107   // [ED | AT | RFU | RFU | RFU | RFU | RFU | UP ]
108   //  * Bit 0: Test of User Presence (TUP) result.
109   //  * Bits 1-5: Reserved for future use (RFU).
110   //  * Bit 6: Attestation data included (AT).
111   //  * Bit 7: Extension data included (ED).
112   uint8_t flags_;
113 
114   // Signature counter, 32-bit unsigned big-endian integer.
115   std::array<uint8_t, kSignCounterLength> counter_;
116   base::Optional<AttestedCredentialData> attested_data_;
117   // If |extensions_| has a value, then it will be a CBOR map.
118   base::Optional<cbor::Value> extensions_;
119 
120   DISALLOW_COPY_AND_ASSIGN(AuthenticatorData);
121 };
122 
123 }  // namespace device
124 
125 #endif  // DEVICE_FIDO_AUTHENTICATOR_DATA_H_
126