Bug 1769628 [wpt PR 34081] - Update wpt metadata, a=testonly
[gecko.git] / dom / webauthn / U2FHIDTokenManager.h
blob5d2bc5323d2eca72890215ded90418df630fd02a
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 {
20 class U2FAppIds {
21 public:
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); }
34 private:
35 rust_u2f_app_ids* mAppIds;
38 class U2FKeyHandles {
39 public:
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(),
46 cred.transports());
50 rust_u2f_key_handles* Get() { return mKeyHandles; }
52 ~U2FKeyHandles() { rust_u2f_khs_free(mKeyHandles); }
54 private:
55 rust_u2f_key_handles* mKeyHandles;
58 class U2FResult {
59 public:
60 explicit U2FResult(uint64_t aTransactionId, rust_u2f_result* aResult)
61 : mTransactionId(aTransactionId), mResult(aResult) {
62 MOZ_ASSERT(mResult);
65 ~U2FResult() { rust_u2f_res_free(mResult); }
67 uint64_t GetTransactionId() { return mTransactionId; }
69 bool IsError() { return NS_FAILED(GetError()); }
71 nsresult 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;
82 default:
83 return NS_OK;
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);
103 private:
104 bool CopyBuffer(uint8_t aResBufID, nsTArray<uint8_t>& aBuffer) {
105 size_t len;
106 if (!rust_u2f_resbuf_length(mResult, aResBufID, &len)) {
107 return false;
110 if (!aBuffer.SetLength(len, fallible)) {
111 return false;
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 {
122 public:
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);
136 private:
137 ~U2FHIDTokenManager() = default;
139 void ClearPromises() {
140 mRegisterPromise.RejectIfExists(NS_ERROR_DOM_UNKNOWN_ERR, __func__);
141 mSignPromise.RejectIfExists(NS_ERROR_DOM_UNKNOWN_ERR, __func__);
144 class Transaction {
145 public:
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)
150 : mId(aId),
151 mRpIdHash(aRpIdHash.Clone()),
152 mClientDataJSON(aClientDataJSON),
153 mForceNoneAttestation(aForceNoneAttestation) {
154 if (aAppIdHash) {
155 mAppIdHash = Some(aAppIdHash->Clone());
156 } else {
157 mAppIdHash = Nothing();
161 // The transaction ID.
162 uint64_t mId;
164 // The RP ID hash.
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