Coverage Report

Created: 2018-09-25 14:53

/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