1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_U2FHIDTokenManager_h
8 #define mozilla_dom_U2FHIDTokenManager_h
10 #include "mozilla/dom/U2FTokenTransport.h"
11 #include "authenticator/src/u2fhid-capi.h"
14 * U2FHIDTokenManager is a Rust implementation of a secure token manager
15 * for the U2F and WebAuthn APIs, talking to HIDs.
18 namespace mozilla::dom
{
22 explicit U2FAppIds(const nsTArray
<nsTArray
<uint8_t>>& aApplications
) {
23 mAppIds
= rust_u2f_app_ids_new();
25 for (auto& app_id
: aApplications
) {
26 rust_u2f_app_ids_add(mAppIds
, app_id
.Elements(), app_id
.Length());
30 rust_u2f_app_ids
* Get() { return mAppIds
; }
32 ~U2FAppIds() { rust_u2f_app_ids_free(mAppIds
); }
35 rust_u2f_app_ids
* mAppIds
;
40 explicit U2FKeyHandles(
41 const nsTArray
<WebAuthnScopedCredential
>& aCredentials
) {
42 mKeyHandles
= rust_u2f_khs_new();
44 for (auto& cred
: aCredentials
) {
45 rust_u2f_khs_add(mKeyHandles
, cred
.id().Elements(), cred
.id().Length(),
50 rust_u2f_key_handles
* Get() { return mKeyHandles
; }
52 ~U2FKeyHandles() { rust_u2f_khs_free(mKeyHandles
); }
55 rust_u2f_key_handles
* mKeyHandles
;
60 explicit U2FResult(uint64_t aTransactionId
, rust_u2f_result
* aResult
)
61 : mTransactionId(aTransactionId
), mResult(aResult
) {
65 ~U2FResult() { rust_u2f_res_free(mResult
); }
67 uint64_t GetTransactionId() { return mTransactionId
; }
69 bool IsError() { return NS_FAILED(GetError()); }
72 switch (rust_u2f_result_error(mResult
)) {
73 case U2F_ERROR_UKNOWN
:
74 case U2F_ERROR_CONSTRAINT
:
75 return NS_ERROR_DOM_UNKNOWN_ERR
;
76 case U2F_ERROR_NOT_SUPPORTED
:
77 return NS_ERROR_DOM_NOT_SUPPORTED_ERR
;
78 case U2F_ERROR_INVALID_STATE
:
79 return NS_ERROR_DOM_INVALID_STATE_ERR
;
80 case U2F_ERROR_NOT_ALLOWED
:
81 return NS_ERROR_DOM_NOT_ALLOWED_ERR
;
87 bool CopyRegistration(nsTArray
<uint8_t>& aBuffer
) {
88 return CopyBuffer(U2F_RESBUF_ID_REGISTRATION
, aBuffer
);
91 bool CopyKeyHandle(nsTArray
<uint8_t>& aBuffer
) {
92 return CopyBuffer(U2F_RESBUF_ID_KEYHANDLE
, aBuffer
);
95 bool CopySignature(nsTArray
<uint8_t>& aBuffer
) {
96 return CopyBuffer(U2F_RESBUF_ID_SIGNATURE
, aBuffer
);
99 bool CopyAppId(nsTArray
<uint8_t>& aBuffer
) {
100 return CopyBuffer(U2F_RESBUF_ID_APPID
, aBuffer
);
104 bool CopyBuffer(uint8_t aResBufID
, nsTArray
<uint8_t>& aBuffer
) {
106 if (!rust_u2f_resbuf_length(mResult
, aResBufID
, &len
)) {
110 if (!aBuffer
.SetLength(len
, fallible
)) {
114 return rust_u2f_resbuf_copy(mResult
, aResBufID
, aBuffer
.Elements());
117 uint64_t mTransactionId
;
118 rust_u2f_result
* mResult
;
121 class U2FHIDTokenManager final
: public U2FTokenTransport
{
123 explicit U2FHIDTokenManager();
125 RefPtr
<U2FRegisterPromise
> Register(const WebAuthnMakeCredentialInfo
& aInfo
,
126 bool aForceNoneAttestation
) override
;
128 RefPtr
<U2FSignPromise
> Sign(const WebAuthnGetAssertionInfo
& aInfo
) override
;
130 void Cancel() override
;
131 void Drop() override
;
133 void HandleRegisterResult(UniquePtr
<U2FResult
>&& aResult
);
134 void HandleSignResult(UniquePtr
<U2FResult
>&& aResult
);
137 ~U2FHIDTokenManager() = default;
139 void ClearPromises() {
140 mRegisterPromise
.RejectIfExists(NS_ERROR_DOM_UNKNOWN_ERR
, __func__
);
141 mSignPromise
.RejectIfExists(NS_ERROR_DOM_UNKNOWN_ERR
, __func__
);
146 Transaction(uint64_t aId
, const nsTArray
<uint8_t>& aRpIdHash
,
147 const Maybe
<nsTArray
<uint8_t>>& aAppIdHash
,
148 const nsCString
& aClientDataJSON
,
149 bool aForceNoneAttestation
= false)
151 mRpIdHash(aRpIdHash
.Clone()),
152 mClientDataJSON(aClientDataJSON
),
153 mForceNoneAttestation(aForceNoneAttestation
) {
155 mAppIdHash
= Some(aAppIdHash
->Clone());
157 mAppIdHash
= Nothing();
161 // The transaction ID.
165 nsTArray
<uint8_t> mRpIdHash
;
167 // The App ID hash, if the AppID extension was set
168 Maybe
<nsTArray
<uint8_t>> mAppIdHash
;
170 // The clientData JSON.
171 nsCString mClientDataJSON
;
173 // Whether we'll force "none" attestation.
174 bool mForceNoneAttestation
;
177 rust_u2f_manager
* mU2FManager
;
178 Maybe
<Transaction
> mTransaction
;
179 MozPromiseHolder
<U2FRegisterPromise
> mRegisterPromise
;
180 MozPromiseHolder
<U2FSignPromise
> mSignPromise
;
183 } // namespace mozilla::dom
185 #endif // mozilla_dom_U2FHIDTokenManager_h