/work/obj-fuzz/dist/include/mozilla/dom/U2FHIDTokenManager.h
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #ifndef mozilla_dom_U2FHIDTokenManager_h |
8 | | #define mozilla_dom_U2FHIDTokenManager_h |
9 | | |
10 | | #include "mozilla/dom/U2FTokenTransport.h" |
11 | | #include "u2f-hid-rs/src/u2fhid-capi.h" |
12 | | |
13 | | /* |
14 | | * U2FHIDTokenManager is a Rust implementation of a secure token manager |
15 | | * for the U2F and WebAuthn APIs, talking to HIDs. |
16 | | */ |
17 | | |
18 | | namespace mozilla { |
19 | | namespace dom { |
20 | | |
21 | | class U2FAppIds { |
22 | | public: |
23 | | explicit U2FAppIds(const nsTArray<nsTArray<uint8_t>>& aApplications) |
24 | 0 | { |
25 | 0 | mAppIds = rust_u2f_app_ids_new(); |
26 | 0 |
|
27 | 0 | for (auto& app_id: aApplications) { |
28 | 0 | rust_u2f_app_ids_add(mAppIds, app_id.Elements(), app_id.Length()); |
29 | 0 | } |
30 | 0 | } |
31 | | |
32 | 0 | rust_u2f_app_ids* Get() { return mAppIds; } |
33 | | |
34 | 0 | ~U2FAppIds() { rust_u2f_app_ids_free(mAppIds); } |
35 | | |
36 | | private: |
37 | | rust_u2f_app_ids* mAppIds; |
38 | | }; |
39 | | |
40 | | class U2FKeyHandles { |
41 | | public: |
42 | | explicit U2FKeyHandles(const nsTArray<WebAuthnScopedCredential>& aCredentials) |
43 | 0 | { |
44 | 0 | mKeyHandles = rust_u2f_khs_new(); |
45 | 0 |
|
46 | 0 | for (auto& cred: aCredentials) { |
47 | 0 | rust_u2f_khs_add(mKeyHandles, |
48 | 0 | cred.id().Elements(), |
49 | 0 | cred.id().Length(), |
50 | 0 | cred.transports()); |
51 | 0 | } |
52 | 0 | } |
53 | | |
54 | 0 | rust_u2f_key_handles* Get() { return mKeyHandles; } |
55 | | |
56 | 0 | ~U2FKeyHandles() { rust_u2f_khs_free(mKeyHandles); } |
57 | | |
58 | | private: |
59 | | rust_u2f_key_handles* mKeyHandles; |
60 | | }; |
61 | | |
62 | | class U2FResult { |
63 | | public: |
64 | | explicit U2FResult(uint64_t aTransactionId, rust_u2f_result* aResult) |
65 | | : mTransactionId(aTransactionId) |
66 | | , mResult(aResult) |
67 | 0 | { |
68 | 0 | MOZ_ASSERT(mResult); |
69 | 0 | } |
70 | | |
71 | 0 | ~U2FResult() { rust_u2f_res_free(mResult); } |
72 | | |
73 | 0 | uint64_t GetTransactionId() { return mTransactionId; } |
74 | | |
75 | 0 | bool IsError() { return NS_FAILED(GetError()); } |
76 | | |
77 | | nsresult GetError() { |
78 | | switch (rust_u2f_result_error(mResult)) { |
79 | | case U2F_ERROR_UKNOWN: |
80 | | case U2F_ERROR_CONSTRAINT: |
81 | | return NS_ERROR_DOM_UNKNOWN_ERR; |
82 | | case U2F_ERROR_NOT_SUPPORTED: |
83 | | return NS_ERROR_DOM_NOT_SUPPORTED_ERR; |
84 | | case U2F_ERROR_INVALID_STATE: |
85 | | return NS_ERROR_DOM_INVALID_STATE_ERR; |
86 | | case U2F_ERROR_NOT_ALLOWED: |
87 | | return NS_ERROR_DOM_NOT_ALLOWED_ERR; |
88 | | default: |
89 | | return NS_OK; |
90 | | } |
91 | | } |
92 | | |
93 | | bool CopyRegistration(nsTArray<uint8_t>& aBuffer) |
94 | 0 | { |
95 | 0 | return CopyBuffer(U2F_RESBUF_ID_REGISTRATION, aBuffer); |
96 | 0 | } |
97 | | |
98 | | bool CopyKeyHandle(nsTArray<uint8_t>& aBuffer) |
99 | 0 | { |
100 | 0 | return CopyBuffer(U2F_RESBUF_ID_KEYHANDLE, aBuffer); |
101 | 0 | } |
102 | | |
103 | | bool CopySignature(nsTArray<uint8_t>& aBuffer) |
104 | 0 | { |
105 | 0 | return CopyBuffer(U2F_RESBUF_ID_SIGNATURE, aBuffer); |
106 | 0 | } |
107 | | |
108 | | bool CopyAppId(nsTArray<uint8_t>& aBuffer) |
109 | 0 | { |
110 | 0 | return CopyBuffer(U2F_RESBUF_ID_APPID, aBuffer); |
111 | 0 | } |
112 | | |
113 | | private: |
114 | 0 | bool CopyBuffer(uint8_t aResBufID, nsTArray<uint8_t>& aBuffer) { |
115 | 0 | size_t len; |
116 | 0 | if (!rust_u2f_resbuf_length(mResult, aResBufID, &len)) { |
117 | 0 | return false; |
118 | 0 | } |
119 | 0 | |
120 | 0 | if (!aBuffer.SetLength(len, fallible)) { |
121 | 0 | return false; |
122 | 0 | } |
123 | 0 | |
124 | 0 | return rust_u2f_resbuf_copy(mResult, aResBufID, aBuffer.Elements()); |
125 | 0 | } |
126 | | |
127 | | uint64_t mTransactionId; |
128 | | rust_u2f_result* mResult; |
129 | | }; |
130 | | |
131 | | class U2FHIDTokenManager final : public U2FTokenTransport |
132 | | { |
133 | | public: |
134 | | explicit U2FHIDTokenManager(); |
135 | | |
136 | | RefPtr<U2FRegisterPromise> |
137 | | Register(const WebAuthnMakeCredentialInfo& aInfo, |
138 | | bool aForceNoneAttestation) override; |
139 | | |
140 | | RefPtr<U2FSignPromise> |
141 | | Sign(const WebAuthnGetAssertionInfo& aInfo) override; |
142 | | |
143 | | void Cancel() override; |
144 | | void Drop() override; |
145 | | |
146 | | void HandleRegisterResult(UniquePtr<U2FResult>&& aResult); |
147 | | void HandleSignResult(UniquePtr<U2FResult>&& aResult); |
148 | | |
149 | | private: |
150 | 0 | ~U2FHIDTokenManager() { } |
151 | | |
152 | 0 | void ClearPromises() { |
153 | 0 | mRegisterPromise.RejectIfExists(NS_ERROR_DOM_UNKNOWN_ERR, __func__); |
154 | 0 | mSignPromise.RejectIfExists(NS_ERROR_DOM_UNKNOWN_ERR, __func__); |
155 | 0 | } |
156 | | |
157 | | class Transaction |
158 | | { |
159 | | public: |
160 | | Transaction(uint64_t aId, |
161 | | const nsTArray<uint8_t>& aRpIdHash, |
162 | | const nsCString& aClientDataJSON, |
163 | | bool aForceNoneAttestation = false) |
164 | | : mId(aId) |
165 | | , mRpIdHash(aRpIdHash) |
166 | | , mClientDataJSON(aClientDataJSON) |
167 | | , mForceNoneAttestation(aForceNoneAttestation) |
168 | 0 | { } |
169 | | |
170 | | // The transaction ID. |
171 | | uint64_t mId; |
172 | | |
173 | | // The RP ID hash. |
174 | | nsTArray<uint8_t> mRpIdHash; |
175 | | |
176 | | // The clientData JSON. |
177 | | nsCString mClientDataJSON; |
178 | | |
179 | | // Whether we'll force "none" attestation. |
180 | | bool mForceNoneAttestation; |
181 | | }; |
182 | | |
183 | | rust_u2f_manager* mU2FManager; |
184 | | Maybe<Transaction> mTransaction; |
185 | | MozPromiseHolder<U2FRegisterPromise> mRegisterPromise; |
186 | | MozPromiseHolder<U2FSignPromise> mSignPromise; |
187 | | }; |
188 | | |
189 | | } // namespace dom |
190 | | } // namespace mozilla |
191 | | |
192 | | #endif // mozilla_dom_U2FHIDTokenManager_h |