bug 1332681 - part 2/4 - authentication.getAssertion: return a PublicKeyCredential instead of a WebAuthnAssertion r?jcj,qdot
MozReview-Commit-ID: 72p9lvhQISe
rename from dom/webauthn/WebAuthnAssertion.cpp
rename to dom/webauthn/AuthenticatorAssertionResponse.cpp
--- a/dom/webauthn/WebAuthnAssertion.cpp
+++ b/dom/webauthn/AuthenticatorAssertionResponse.cpp
@@ -1,98 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/WebAuthnAssertion.h"
+#include "mozilla/dom/AuthenticatorAssertionResponse.h"
namespace mozilla {
namespace dom {
-// Only needed for refcounted objects.
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(WebAuthnAssertion, mParent)
-NS_IMPL_CYCLE_COLLECTING_ADDREF(WebAuthnAssertion)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(WebAuthnAssertion)
-NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebAuthnAssertion)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
-NS_INTERFACE_MAP_END
+NS_IMPL_ADDREF_INHERITED(AuthenticatorAssertionResponse, AuthenticatorResponse)
+NS_IMPL_RELEASE_INHERITED(AuthenticatorAssertionResponse, AuthenticatorResponse)
-WebAuthnAssertion::WebAuthnAssertion(nsPIDOMWindowInner* aParent)
- : mParent(aParent)
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(AuthenticatorAssertionResponse)
+NS_INTERFACE_MAP_END_INHERITING(AuthenticatorResponse)
+
+AuthenticatorAssertionResponse::AuthenticatorAssertionResponse(nsPIDOMWindowInner* aParent)
+ : AuthenticatorResponse(aParent)
{}
-WebAuthnAssertion::~WebAuthnAssertion()
+AuthenticatorAssertionResponse::~AuthenticatorAssertionResponse()
{}
JSObject*
-WebAuthnAssertion::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
+AuthenticatorAssertionResponse::WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto)
{
- return WebAuthnAssertionBinding::Wrap(aCx, this, aGivenProto);
-}
-
-already_AddRefed<ScopedCredential>
-WebAuthnAssertion::Credential() const
-{
- RefPtr<ScopedCredential> temp(mCredential);
- return temp.forget();
+ return AuthenticatorAssertionResponseBinding::Wrap(aCx, this, aGivenProto);
}
void
-WebAuthnAssertion::GetClientData(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetVal) const
-{
- aRetVal.set(mClientData.ToUint8Array(aCx));
-}
-
-void
-WebAuthnAssertion::GetAuthenticatorData(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetVal) const
+AuthenticatorAssertionResponse::GetAuthenticatorData(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aRetVal) const
{
aRetVal.set(mAuthenticatorData.ToUint8Array(aCx));
}
+nsresult
+AuthenticatorAssertionResponse::SetAuthenticatorData(CryptoBuffer& aBuffer)
+{
+ if (NS_WARN_IF(!mAuthenticatorData.Assign(aBuffer))) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ return NS_OK;
+}
+
void
-WebAuthnAssertion::GetSignature(JSContext* aCx,
- JS::MutableHandle<JSObject*> aRetVal) const
+AuthenticatorAssertionResponse::GetSignature(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aRetVal) const
{
aRetVal.set(mSignature.ToUint8Array(aCx));
}
nsresult
-WebAuthnAssertion::SetCredential(RefPtr<ScopedCredential> aCredential)
-{
- mCredential = aCredential;
- return NS_OK;
-}
-
-nsresult
-WebAuthnAssertion::SetClientData(CryptoBuffer& aBuffer)
+AuthenticatorAssertionResponse::SetSignature(CryptoBuffer& aBuffer)
{
- if (!mClientData.Assign(aBuffer)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- return NS_OK;
-}
-
-nsresult
-WebAuthnAssertion::SetAuthenticatorData(CryptoBuffer& aBuffer)
-{
- if (!mAuthenticatorData.Assign(aBuffer)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- return NS_OK;
-}
-
-nsresult
-WebAuthnAssertion::SetSignature(CryptoBuffer& aBuffer)
-{
- if (!mSignature.Assign(aBuffer)) {
+ if (NS_WARN_IF(!mSignature.Assign(aBuffer))) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
} // namespace dom
} // namespace mozilla
rename from dom/webauthn/WebAuthnAssertion.h
rename to dom/webauthn/AuthenticatorAssertionResponse.h
--- a/dom/webauthn/WebAuthnAssertion.h
+++ b/dom/webauthn/AuthenticatorAssertionResponse.h
@@ -1,86 +1,56 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
-#ifndef mozilla_dom_WebAuthnAssertion_h
-#define mozilla_dom_WebAuthnAssertion_h
+#ifndef mozilla_dom_AuthenticatorAssertionResponse_h
+#define mozilla_dom_AuthenticatorAssertionResponse_h
#include "js/TypeDecls.h"
#include "mozilla/Attributes.h"
#include "mozilla/ErrorResult.h"
+#include "mozilla/dom/AuthenticatorResponse.h"
#include "mozilla/dom/BindingDeclarations.h"
+#include "mozilla/dom/CryptoBuffer.h"
#include "nsCycleCollectionParticipant.h"
#include "nsWrapperCache.h"
namespace mozilla {
namespace dom {
-class ScopedCredential;
-
-} // namespace dom
-} // namespace mozilla
-
-namespace mozilla {
-namespace dom {
-
-class WebAuthnAssertion final : public nsISupports
- , public nsWrapperCache
+class AuthenticatorAssertionResponse final : public AuthenticatorResponse
{
public:
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebAuthnAssertion)
+ NS_DECL_ISUPPORTS_INHERITED
-public:
- explicit WebAuthnAssertion(nsPIDOMWindowInner* aParent);
+ explicit AuthenticatorAssertionResponse(nsPIDOMWindowInner* aParent);
protected:
- ~WebAuthnAssertion();
+ ~AuthenticatorAssertionResponse() override;
public:
- nsPIDOMWindowInner*
- GetParentObject() const
- {
- return mParent;
- }
-
virtual JSObject*
WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
- already_AddRefed<ScopedCredential>
- Credential() const;
-
void
- GetClientData(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal) const;
-
- void
- GetAuthenticatorData(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal) const;
-
- void
- GetSignature(JSContext* cx, JS::MutableHandle<JSObject*> aRetVal) const;
-
- nsresult
- SetCredential(RefPtr<ScopedCredential> aCredential);
-
- nsresult
- SetClientData(CryptoBuffer& aBuffer);
+ GetAuthenticatorData(JSContext* aCx, JS::MutableHandle<JSObject*> aRetVal) const;
nsresult
SetAuthenticatorData(CryptoBuffer& aBuffer);
+ void
+ GetSignature(JSContext* aCx, JS::MutableHandle<JSObject*> aRetVal) const;
+
nsresult
SetSignature(CryptoBuffer& aBuffer);
private:
- nsCOMPtr<nsPIDOMWindowInner> mParent;
- RefPtr<ScopedCredential> mCredential;
CryptoBuffer mAuthenticatorData;
- CryptoBuffer mClientData;
CryptoBuffer mSignature;
};
} // namespace dom
} // namespace mozilla
-#endif // mozilla_dom_WebAuthnAssertion_h
+#endif // mozilla_dom_AuthenticatorAssertionResponse_h
--- a/dom/webauthn/WebAuthnManager.cpp
+++ b/dom/webauthn/WebAuthnManager.cpp
@@ -727,31 +727,31 @@ WebAuthnManager::FinishGetAssertion(nsTA
CryptoBuffer credentialBuf;
if (!credentialBuf.Assign(aCredentialId)) {
Cancel(rv);
return;
}
// If any authenticator returns success:
- // Create a new WebAuthnAssertion object named value and populate its fields
+ // Create a new PublicKeyCredential object named value and populate its fields
// with the values returned from the authenticator as well as the
// clientDataJSON computed earlier.
-
- RefPtr<ScopedCredential> credential = new ScopedCredential(mCurrentParent);
- credential->SetType(ScopedCredentialType::ScopedCred);
- credential->SetId(credentialBuf);
-
- RefPtr<WebAuthnAssertion> assertion = new WebAuthnAssertion(mCurrentParent);
- assertion->SetCredential(credential);
- assertion->SetClientData(clientDataBuf);
+ RefPtr<AuthenticatorAssertionResponse> assertion =
+ new AuthenticatorAssertionResponse(mCurrentParent);
+ assertion->SetClientDataJSON(clientDataBuf);
assertion->SetAuthenticatorData(authenticatorDataBuf);
assertion->SetSignature(signatureData);
- mTransactionPromise->MaybeResolve(assertion);
+ RefPtr<PublicKeyCredential> credential =
+ new PublicKeyCredential(mCurrentParent);
+ credential->SetRawId(credentialBuf);
+ credential->SetResponse(assertion);
+
+ mTransactionPromise->MaybeResolve(credential);
MaybeClearTransaction();
}
void
WebAuthnManager::Cancel(const nsresult& aError)
{
if (mChild) {
mChild->SendRequestCancel();
--- a/dom/webauthn/moz.build
+++ b/dom/webauthn/moz.build
@@ -7,43 +7,43 @@
with Files("**"):
BUG_COMPONENT = ("Core", "DOM: Device Interfaces")
IPDL_SOURCES += [
'PWebAuthnTransaction.ipdl'
]
EXPORTS.mozilla.dom += [
+ 'AuthenticatorAssertionResponse.h',
'AuthenticatorAttestationResponse.h',
'AuthenticatorResponse.h',
'NSSU2FTokenRemote.h',
'PublicKeyCredential.h',
'ScopedCredential.h',
'U2FSoftTokenManager.h',
'U2FTokenManager.h',
'U2FTokenTransport.h',
'WebAuthentication.h',
- 'WebAuthnAssertion.h',
'WebAuthnManager.h',
'WebAuthnRequest.h',
'WebAuthnTransactionChild.h',
'WebAuthnTransactionParent.h',
'WebAuthnUtil.h'
]
UNIFIED_SOURCES += [
+ 'AuthenticatorAssertionResponse.cpp',
'AuthenticatorAttestationResponse.cpp',
'AuthenticatorResponse.cpp',
'NSSU2FTokenRemote.cpp',
'PublicKeyCredential.cpp',
'ScopedCredential.cpp',
'U2FSoftTokenManager.cpp',
'U2FTokenManager.cpp',
'WebAuthentication.cpp',
- 'WebAuthnAssertion.cpp',
'WebAuthnManager.cpp',
'WebAuthnTransactionChild.cpp',
'WebAuthnTransactionParent.cpp',
'WebAuthnUtil.cpp'
]
include('/ipc/chromium/chromium-config.mozbuild')
--- a/dom/webauthn/tests/test_webauthn_loopback.html
+++ b/dom/webauthn/tests/test_webauthn_loopback.html
@@ -58,47 +58,46 @@ function() {
return decodeU2FRegistration(aCredInfo.response.attestationObject)
.then(function(u2fObj) {
aCredInfo.u2fReg = u2fObj;
return aCredInfo;
});
}
function checkAssertionAndSigValid(aPublicKey, aAssertion) {
- /* WebAuthnAssertion
- - Credential
- -- ID: ID of Credential from AllowList that succeeded
- -- Type: "ScopedCred"
- - ClientData: serialized JSON
- - AuthenticatorData: RP ID Hash || U2F Sign() Response
- - Signature: U2F Sign() Response */
+ /* PublicKeyCredential : Credential
+ - rawId: ID of Credential from AllowList that succeeded
+ - response : AuthenticatorAssertionResponse : AuthenticatorResponse
+ - clientDataJSON: serialized JSON
+ - authenticatorData: RP ID Hash || U2F Sign() Response
+ - signature: U2F Sign() Response
+ */
- is(aAssertion.credential.type, "ScopedCred", "Type is correct");
- ok(aAssertion.credential.id.length > 0, "Key ID exists");
+ ok(aAssertion.rawId.length > 0, "Key ID exists");
- ok(aAssertion.authenticatorData.length > 0, "Authenticator data exists");
- let clientData = JSON.parse(buffer2string(aAssertion.clientData));
+ ok(aAssertion.response.authenticatorData.length > 0, "Authenticator data exists");
+ let clientData = JSON.parse(buffer2string(aAssertion.response.clientDataJSON));
is(clientData.challenge, bytesToBase64UrlSafe(gAssertionChallenge), "Challenge is correct");
is(clientData.origin, window.location.origin, "Origin is correct");
is(clientData.hashAlg, "S256", "Hash algorithm is correct");
// Parse the signature data
- if (aAssertion.signature[0] != 0x01) {
+ if (aAssertion.response.signature[0] != 0x01) {
throw "User presence byte not set";
}
- let presenceAndCounter = aAssertion.signature.slice(0,5);
- let signatureValue = aAssertion.signature.slice(5);
+ let presenceAndCounter = aAssertion.response.signature.slice(0,5);
+ let signatureValue = aAssertion.response.signature.slice(5);
- let rpIdHash = aAssertion.authenticatorData.slice(0,32);
+ let rpIdHash = aAssertion.response.authenticatorData.slice(0,32);
// Assemble the signed data and verify the signature
- return deriveAppAndChallengeParam(clientData.origin, aAssertion.clientData)
+ return deriveAppAndChallengeParam(clientData.origin, aAssertion.response.clientDataJSON)
.then(function(aParams) {
console.log(aParams.appParam, rpIdHash, presenceAndCounter, aParams.challengeParam);
- console.log("ClientData buffer: ", hexEncode(aAssertion.clientData));
+ console.log("ClientData buffer: ", hexEncode(aAssertion.response.clientDataJSON));
console.log("ClientDataHash: ", hexEncode(aParams.challengeParam));
return assembleSignedData(aParams.appParam, presenceAndCounter, aParams.challengeParam);
})
.then(function(aSignedData) {
console.log(aPublicKey, aSignedData, signatureValue);
return verifySignature(aPublicKey, aSignedData, signatureValue);
})
}
--- a/dom/webidl/WebAuthentication.webidl
+++ b/dom/webidl/WebAuthentication.webidl
@@ -45,19 +45,17 @@ dictionary ScopedCredentialParameters {
dictionary ScopedCredentialOptions {
unsigned long timeoutSeconds;
USVString rpId;
sequence<ScopedCredentialDescriptor> excludeList;
WebAuthnExtensions extensions;
};
[SecureContext, Pref="security.webauth.webauthn"]
-interface WebAuthnAssertion {
- readonly attribute ScopedCredential credential;
- readonly attribute ArrayBuffer clientData;
+interface AuthenticatorAssertionResponse : AuthenticatorResponse {
readonly attribute ArrayBuffer authenticatorData;
readonly attribute ArrayBuffer signature;
};
dictionary AssertionOptions {
unsigned long timeoutSeconds;
USVString rpId;
sequence<ScopedCredentialDescriptor> allowList;
@@ -105,13 +103,13 @@ enum WebAuthnTransport {
interface WebAuthentication {
Promise<PublicKeyCredential> makeCredential (
Account accountInformation,
sequence<ScopedCredentialParameters> cryptoParameters,
BufferSource attestationChallenge,
optional ScopedCredentialOptions options
);
- Promise<WebAuthnAssertion> getAssertion (
+ Promise<PublicKeyCredential> getAssertion (
BufferSource assertionChallenge,
optional AssertionOptions options
);
};