Bug 1900133 - add probes for webauthn and passkeys. r=keeler

Differential Revision: https://phabricator.services.mozilla.com/D212336
This commit is contained in:
John Schanck
2024-06-04 15:49:29 +00:00
parent d092996113
commit bbc166eeb8
4 changed files with 197 additions and 17 deletions

View File

@@ -13,6 +13,7 @@
#include "WebAuthnTransportIdentifiers.h"
#include "mozilla/Base64.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/glean/GleanMetrics.h"
#include "mozilla/dom/AuthenticatorAssertionResponse.h"
#include "mozilla/dom/AuthenticatorAttestationResponse.h"
#include "mozilla/dom/PublicKeyCredential.h"
@@ -478,7 +479,8 @@ already_AddRefed<Promise> WebAuthnManager::MakeCredential(
}
MOZ_ASSERT(mTransaction.isNothing());
mTransaction = Some(WebAuthnTransaction(promise));
mTransaction =
Some(WebAuthnTransaction(promise, WebAuthnTransactionType::Create));
mChild->SendRequestRegister(mTransaction.ref().mId, info);
return promise.forget();
@@ -656,7 +658,8 @@ already_AddRefed<Promise> WebAuthnManager::GetAssertion(
}
MOZ_ASSERT(mTransaction.isNothing());
mTransaction = Some(WebAuthnTransaction(promise));
mTransaction =
Some(WebAuthnTransaction(promise, WebAuthnTransactionType::Get));
mChild->SendRequestSign(mTransaction.ref().mId, info);
return promise.forget();
@@ -741,7 +744,17 @@ void WebAuthnManager::FinishMakeCredential(
credential->SetType(u"public-key"_ns);
credential->SetRawId(aResult.KeyHandle());
credential->SetAttestationResponse(attestation);
credential->SetAuthenticatorAttachment(aResult.AuthenticatorAttachment());
if (aResult.AuthenticatorAttachment().isSome()) {
credential->SetAuthenticatorAttachment(aResult.AuthenticatorAttachment());
mozilla::glean::webauthn_create::authenticator_attachment
.Get(NS_ConvertUTF16toUTF8(aResult.AuthenticatorAttachment().ref()))
.Add(1);
} else {
mozilla::glean::webauthn_get::authenticator_attachment.Get("unknown"_ns)
.Add(1);
}
// Forward client extension results.
for (const auto& ext : aResult.Extensions()) {
@@ -749,6 +762,9 @@ void WebAuthnManager::FinishMakeCredential(
WebAuthnExtensionResult::TWebAuthnExtensionResultCredProps) {
bool credPropsRk = ext.get_WebAuthnExtensionResultCredProps().rk();
credential->SetClientExtensionResultCredPropsRk(credPropsRk);
if (credPropsRk) {
mozilla::glean::webauthn_create::passkey.Add(1);
}
}
if (ext.type() ==
WebAuthnExtensionResult::TWebAuthnExtensionResultHmacSecret) {
@@ -758,8 +774,7 @@ void WebAuthnManager::FinishMakeCredential(
}
}
mTransaction.ref().mPromise->MaybeResolve(credential);
ClearTransaction();
ResolveTransaction(credential);
}
void WebAuthnManager::FinishGetAssertion(
@@ -795,7 +810,17 @@ void WebAuthnManager::FinishGetAssertion(
credential->SetType(u"public-key"_ns);
credential->SetRawId(aResult.KeyHandle());
credential->SetAssertionResponse(assertion);
credential->SetAuthenticatorAttachment(aResult.AuthenticatorAttachment());
if (aResult.AuthenticatorAttachment().isSome()) {
credential->SetAuthenticatorAttachment(aResult.AuthenticatorAttachment());
mozilla::glean::webauthn_get::authenticator_attachment
.Get(NS_ConvertUTF16toUTF8(aResult.AuthenticatorAttachment().ref()))
.Add(1);
} else {
mozilla::glean::webauthn_get::authenticator_attachment.Get("unknown"_ns)
.Add(1);
}
// Forward client extension results.
for (const auto& ext : aResult.Extensions()) {
@@ -815,8 +840,7 @@ void WebAuthnManager::FinishGetAssertion(
}
}
mTransaction.ref().mPromise->MaybeResolve(credential);
ClearTransaction();
ResolveTransaction(credential);
}
void WebAuthnManager::RequestAborted(const uint64_t& aTransactionId,
@@ -846,4 +870,44 @@ void WebAuthnManager::RunAbortAlgorithm() {
CancelTransaction(reason);
}
void WebAuthnManager::ResolveTransaction(
const RefPtr<PublicKeyCredential>& aCredential) {
if (NS_WARN_IF(mTransaction.isNothing())) {
ClearTransaction();
return;
}
switch (mTransaction.ref().mType) {
case WebAuthnTransactionType::Create:
mozilla::glean::webauthn_create::success.Add(1);
break;
case WebAuthnTransactionType::Get:
mozilla::glean::webauthn_get::success.Add(1);
break;
}
mTransaction.ref().mPromise->MaybeResolve(aCredential);
ClearTransaction();
}
template <typename T>
void WebAuthnManager::RejectTransaction(const T& aReason) {
if (NS_WARN_IF(mTransaction.isNothing())) {
ClearTransaction();
return;
}
switch (mTransaction.ref().mType) {
case WebAuthnTransactionType::Create:
mozilla::glean::webauthn_create::failure.Add(1);
break;
case WebAuthnTransactionType::Get:
mozilla::glean::webauthn_get::failure.Add(1);
break;
}
mTransaction.ref().mPromise->MaybeReject(aReason);
ClearTransaction();
}
} // namespace mozilla::dom

View File

@@ -48,10 +48,13 @@ namespace mozilla::dom {
class Credential;
enum class WebAuthnTransactionType { Create, Get };
class WebAuthnTransaction {
public:
explicit WebAuthnTransaction(const RefPtr<Promise>& aPromise)
: mPromise(aPromise), mId(NextId()) {
explicit WebAuthnTransaction(const RefPtr<Promise>& aPromise,
WebAuthnTransactionType aType)
: mPromise(aPromise), mId(NextId()), mType(aType) {
MOZ_ASSERT(mId > 0);
}
@@ -61,6 +64,8 @@ class WebAuthnTransaction {
// Unique transaction id.
uint64_t mId;
WebAuthnTransactionType mType;
private:
// Generates a probabilistically unique ID for the new transaction. IDs are 53
// bits, as they are used in javascript. We use a random value if possible,
@@ -124,16 +129,13 @@ class WebAuthnManager final : public WebAuthnManagerBase, public AbortFollower {
RejectTransaction(aReason);
}
// Resolve the promise with the given credential.
void ResolveTransaction(const RefPtr<PublicKeyCredential>& aCredential);
// Reject the promise with the given reason (an nsresult or JS::Value), and
// clear the transaction.
template <typename T>
void RejectTransaction(const T& aReason) {
if (!NS_WARN_IF(mTransaction.isNothing())) {
mTransaction.ref().mPromise->MaybeReject(aReason);
}
ClearTransaction();
}
void RejectTransaction(const T& aReason);
// Send a Cancel message to the parent.
void CancelParent();

113
dom/webauthn/metrics.yaml Normal file
View File

@@ -0,0 +1,113 @@
# 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/.
# Adding a new metric? We have docs for that!
# https://firefox-source-docs.mozilla.org/toolkit/components/glean/user/new_definitions_file.html
---
$schema: moz://mozilla.org/schemas/glean/metrics/2-0-0
$tags:
- 'Core :: DOM: Web Authentication'
webauthn_create:
success:
type: counter
description:
The total number of successful calls to navigator.credentials.create.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_sensitivity:
- interaction
notification_emails:
- jschanck@mozilla.com
expires: never
failure:
type: counter
description:
The total number of failed calls to navigator.credentials.create.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_sensitivity:
- interaction
notification_emails:
- jschanck@mozilla.com
expires: never
authenticator_attachment:
type: labeled_counter
description:
The number of successfully created credentials by authenticator attachment modality.
labels:
- cross-platform
- platform
- unknown
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_sensitivity:
- interaction
notification_emails:
- jschanck@mozilla.com
expires: never
passkey:
type: counter
description:
The number of client-side discoverable credentials (passkeys) created.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_sensitivity:
- interaction
notification_emails:
- jschanck@mozilla.com
expires: never
webauthn_get:
success:
type: counter
description:
The total number of successful calls to navigator.credentials.get.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_sensitivity:
- interaction
notification_emails:
- jschanck@mozilla.com
expires: never
failure:
type: counter
description:
The total number of failed calls to navigator.credentials.get.
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_sensitivity:
- interaction
notification_emails:
- jschanck@mozilla.com
expires: never
authenticator_attachment:
type: labeled_counter
description:
The number of successfully asserted credentials by authenticator attachment modality.
labels:
- cross-platform
- platform
- unknown
bugs:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_reviews:
- https://bugzilla.mozilla.org/show_bug.cgi?id=1900133
data_sensitivity:
- interaction
notification_emails:
- jschanck@mozilla.com
expires: never

View File

@@ -25,6 +25,7 @@ gecko_metrics = [
"dom/metrics.yaml",
"dom/performance/metrics.yaml",
"dom/security/metrics.yaml",
"dom/webauthn/metrics.yaml",
"gfx/metrics.yaml",
"image/decoders/metrics.yaml",
"js/xpconnect/metrics.yaml",