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 #include "mozilla/Base64.h"
8 #include "mozilla/dom/WebAuthenticationBinding.h"
9 #include "mozilla/dom/AuthenticatorAssertionResponse.h"
10 #include "mozilla/HoldDropJSObjects.h"
12 namespace mozilla::dom
{
14 NS_IMPL_CYCLE_COLLECTION_CLASS(AuthenticatorAssertionResponse
)
15 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(AuthenticatorAssertionResponse
,
16 AuthenticatorResponse
)
17 tmp
->mAuthenticatorDataCachedObj
= nullptr;
18 tmp
->mSignatureCachedObj
= nullptr;
19 tmp
->mUserHandleCachedObj
= nullptr;
20 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
22 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(AuthenticatorAssertionResponse
,
23 AuthenticatorResponse
)
24 NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
25 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAuthenticatorDataCachedObj
)
26 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mSignatureCachedObj
)
27 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mUserHandleCachedObj
)
28 NS_IMPL_CYCLE_COLLECTION_TRACE_END
30 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(
31 AuthenticatorAssertionResponse
, AuthenticatorResponse
)
32 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
34 NS_IMPL_ADDREF_INHERITED(AuthenticatorAssertionResponse
, AuthenticatorResponse
)
35 NS_IMPL_RELEASE_INHERITED(AuthenticatorAssertionResponse
, AuthenticatorResponse
)
37 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AuthenticatorAssertionResponse
)
38 NS_INTERFACE_MAP_END_INHERITING(AuthenticatorResponse
)
40 AuthenticatorAssertionResponse::AuthenticatorAssertionResponse(
41 nsPIDOMWindowInner
* aParent
)
42 : AuthenticatorResponse(aParent
),
43 mAuthenticatorDataCachedObj(nullptr),
44 mSignatureCachedObj(nullptr),
45 mUserHandleCachedObj(nullptr) {
46 mozilla::HoldJSObjects(this);
49 AuthenticatorAssertionResponse::~AuthenticatorAssertionResponse() {
50 mozilla::DropJSObjects(this);
53 JSObject
* AuthenticatorAssertionResponse::WrapObject(
54 JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
) {
55 return AuthenticatorAssertionResponse_Binding::Wrap(aCx
, this, aGivenProto
);
58 void AuthenticatorAssertionResponse::GetAuthenticatorData(
59 JSContext
* aCx
, JS::MutableHandle
<JSObject
*> aValue
, ErrorResult
& aRv
) {
60 if (!mAuthenticatorDataCachedObj
) {
61 mAuthenticatorDataCachedObj
=
62 ArrayBuffer::Create(aCx
, mAuthenticatorData
, aRv
);
67 aValue
.set(mAuthenticatorDataCachedObj
);
70 void AuthenticatorAssertionResponse::SetAuthenticatorData(
71 const nsTArray
<uint8_t>& aBuffer
) {
72 mAuthenticatorData
.Assign(aBuffer
);
75 void AuthenticatorAssertionResponse::GetSignature(
76 JSContext
* aCx
, JS::MutableHandle
<JSObject
*> aValue
, ErrorResult
& aRv
) {
77 if (!mSignatureCachedObj
) {
78 mSignatureCachedObj
= ArrayBuffer::Create(aCx
, mSignature
, aRv
);
83 aValue
.set(mSignatureCachedObj
);
86 void AuthenticatorAssertionResponse::SetSignature(
87 const nsTArray
<uint8_t>& aBuffer
) {
88 mSignature
.Assign(aBuffer
);
91 void AuthenticatorAssertionResponse::GetUserHandle(
92 JSContext
* aCx
, JS::MutableHandle
<JSObject
*> aValue
, ErrorResult
& aRv
) {
94 // https://w3c.github.io/webauthn/#ref-for-dom-authenticatorassertionresponse-userhandle%E2%91%A0
95 // this should return null if the handle is unset.
96 if (mUserHandle
.IsEmpty()) {
99 if (!mUserHandleCachedObj
) {
100 mUserHandleCachedObj
= ArrayBuffer::Create(aCx
, mUserHandle
, aRv
);
105 aValue
.set(mUserHandleCachedObj
);
109 void AuthenticatorAssertionResponse::SetUserHandle(
110 const nsTArray
<uint8_t>& aBuffer
) {
111 mUserHandle
.Assign(aBuffer
);
114 void AuthenticatorAssertionResponse::ToJSON(
115 AuthenticatorAssertionResponseJSON
& aJSON
, ErrorResult
& aError
) {
116 nsAutoCString clientDataJSONBase64
;
117 nsresult rv
= Base64URLEncode(
118 mClientDataJSON
.Length(),
119 reinterpret_cast<const uint8_t*>(mClientDataJSON
.get()),
120 mozilla::Base64URLEncodePaddingPolicy::Omit
, clientDataJSONBase64
);
121 // This will only fail if the length is so long that it overflows 32-bits
122 // when calculating the encoded size.
124 aError
.ThrowDataError("clientDataJSON too long");
127 aJSON
.mClientDataJSON
.Assign(NS_ConvertUTF8toUTF16(clientDataJSONBase64
));
129 nsAutoCString authenticatorDataBase64
;
130 rv
= Base64URLEncode(
131 mAuthenticatorData
.Length(), mAuthenticatorData
.Elements(),
132 mozilla::Base64URLEncodePaddingPolicy::Omit
, authenticatorDataBase64
);
134 aError
.ThrowDataError("authenticatorData too long");
137 aJSON
.mAuthenticatorData
.Assign(
138 NS_ConvertUTF8toUTF16(authenticatorDataBase64
));
140 nsAutoCString signatureBase64
;
141 rv
= Base64URLEncode(mSignature
.Length(), mSignature
.Elements(),
142 mozilla::Base64URLEncodePaddingPolicy::Omit
,
145 aError
.ThrowDataError("signature too long");
148 aJSON
.mSignature
.Assign(NS_ConvertUTF8toUTF16(signatureBase64
));
150 if (!mUserHandle
.IsEmpty()) {
151 nsAutoCString userHandleBase64
;
152 rv
= Base64URLEncode(mUserHandle
.Length(), mUserHandle
.Elements(),
153 mozilla::Base64URLEncodePaddingPolicy::Omit
,
156 aError
.ThrowDataError("userHandle too long");
159 aJSON
.mUserHandle
.Construct(NS_ConvertUTF8toUTF16(userHandleBase64
));
162 // attestationObject is not currently supported on assertion responses
165 } // namespace mozilla::dom