gecko-dev/dom/webauthn/AuthenticatorAssertionResponse.cpp
J.C. Jones 9ca7fca83d Bug 1463170 - Set AuthenticatorAssertionResponse.userHandle to null r=ttaubert r=smaug
Summary:
The WebAuthn spec says to set `AuthenticatorAssertionResponse.userHandle` to
null when the authenticator returns no user handle (e.g., when allowList is set),
but we return an empty ArrayBuffer. This is because of the defaults in
AuthenticatorAssertionResponse.h, as the field is itself unset.

We missed this change to the spec that happened in December [2], so this also
has a corresponding WebIDL update. I don't see any other instances of WebIDL
differences.

[1] https://w3c.github.io/webauthn/#ref-for-dom-authenticatorassertionresponse-userhandle%E2%91%A0
[2] 3b2a1d141c

Test Plan: https://treeherder.mozilla.org/#/jobs?repo=try&revision=59a2ab255ef14e935c1aa9f457276f8e61e5d779

Reviewers: smaug, ttaubert

Bug #: 1463170

Differential Revision: https://phabricator.services.mozilla.com/D1337

--HG--
extra : amend_source : 966dcd24050585e745078648e1d7995b3beaf9ca
extra : transplant_source : h%3E%B7COQ%F3%05%A9%95%1C%5D%CD%E1XZ%06Z%8D%83
2018-05-21 09:04:50 -07:00

125 lines
4.1 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/WebAuthenticationBinding.h"
#include "mozilla/dom/AuthenticatorAssertionResponse.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(AuthenticatorAssertionResponse)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(AuthenticatorAssertionResponse,
AuthenticatorResponse)
tmp->mAuthenticatorDataCachedObj = nullptr;
tmp->mSignatureCachedObj = nullptr;
tmp->mUserHandleCachedObj = nullptr;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(AuthenticatorAssertionResponse,
AuthenticatorResponse)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAuthenticatorDataCachedObj)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mSignatureCachedObj)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mUserHandleCachedObj)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(AuthenticatorAssertionResponse,
AuthenticatorResponse)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_ADDREF_INHERITED(AuthenticatorAssertionResponse, AuthenticatorResponse)
NS_IMPL_RELEASE_INHERITED(AuthenticatorAssertionResponse, AuthenticatorResponse)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AuthenticatorAssertionResponse)
NS_INTERFACE_MAP_END_INHERITING(AuthenticatorResponse)
AuthenticatorAssertionResponse::AuthenticatorAssertionResponse(nsPIDOMWindowInner* aParent)
: AuthenticatorResponse(aParent)
, mAuthenticatorDataCachedObj(nullptr)
, mSignatureCachedObj(nullptr)
, mUserHandleCachedObj(nullptr)
{
mozilla::HoldJSObjects(this);
}
AuthenticatorAssertionResponse::~AuthenticatorAssertionResponse()
{
mozilla::DropJSObjects(this);
}
JSObject*
AuthenticatorAssertionResponse::WrapObject(JSContext* aCx,
JS::Handle<JSObject*> aGivenProto)
{
return AuthenticatorAssertionResponseBinding::Wrap(aCx, this, aGivenProto);
}
void
AuthenticatorAssertionResponse::GetAuthenticatorData(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetVal)
{
if (!mAuthenticatorDataCachedObj) {
mAuthenticatorDataCachedObj = mAuthenticatorData.ToArrayBuffer(aCx);
}
aRetVal.set(mAuthenticatorDataCachedObj);
}
nsresult
AuthenticatorAssertionResponse::SetAuthenticatorData(CryptoBuffer& aBuffer)
{
if (NS_WARN_IF(!mAuthenticatorData.Assign(aBuffer))) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
void
AuthenticatorAssertionResponse::GetSignature(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetVal)
{
if (!mSignatureCachedObj) {
mSignatureCachedObj = mSignature.ToArrayBuffer(aCx);
}
aRetVal.set(mSignatureCachedObj);
}
nsresult
AuthenticatorAssertionResponse::SetSignature(CryptoBuffer& aBuffer)
{
if (NS_WARN_IF(!mSignature.Assign(aBuffer))) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
void
AuthenticatorAssertionResponse::GetUserHandle(JSContext* aCx,
JS::MutableHandle<JSObject*> aRetVal)
{
// Per https://w3c.github.io/webauthn/#ref-for-dom-authenticatorassertionresponse-userhandle%E2%91%A0
// this should return null if the handle is unset.
if (mUserHandle.IsEmpty()) {
aRetVal.set(nullptr);
} else {
if (!mUserHandleCachedObj) {
mUserHandleCachedObj = mUserHandle.ToArrayBuffer(aCx);
}
aRetVal.set(mUserHandleCachedObj);
}
}
nsresult
AuthenticatorAssertionResponse::SetUserHandle(CryptoBuffer& aBuffer)
{
if (NS_WARN_IF(!mUserHandle.Assign(aBuffer))) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
} // namespace dom
} // namespace mozilla