mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 1838938 - Remove U2FSoftTokenTransport. r=keeler
Depends on D181302 Differential Revision: https://phabricator.services.mozilla.com/D181301
This commit is contained in:
parent
5f8b0f5223
commit
22d1d1cb02
@ -1,82 +0,0 @@
|
||||
/* -*- 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 "CtapResults.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS(CtapRegisterResult, nsICtapRegisterResult)
|
||||
|
||||
NS_IMETHODIMP
|
||||
CtapRegisterResult::GetStatus(nsresult* aStatus) {
|
||||
*aStatus = mStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CtapRegisterResult::GetAttestationObject(
|
||||
nsTArray<uint8_t>& aAttestationObject) {
|
||||
aAttestationObject.Clear();
|
||||
aAttestationObject.AppendElements(mAttestationObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CtapRegisterResult::GetCredentialId(nsTArray<uint8_t>& aCredentialId) {
|
||||
aCredentialId.Clear();
|
||||
aCredentialId.AppendElements(mCredentialId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(CtapSignResult, nsICtapSignResult)
|
||||
|
||||
NS_IMETHODIMP
|
||||
CtapSignResult::GetStatus(nsresult* aStatus) {
|
||||
*aStatus = mStatus;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CtapSignResult::GetCredentialId(nsTArray<uint8_t>& aCredentialId) {
|
||||
aCredentialId.Clear();
|
||||
aCredentialId.AppendElements(mCredentialId);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CtapSignResult::GetAuthenticatorData(nsTArray<uint8_t>& aAuthenticatorData) {
|
||||
aAuthenticatorData.Clear();
|
||||
aAuthenticatorData.AppendElements(mAuthenticatorData);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CtapSignResult::GetSignature(nsTArray<uint8_t>& aSignature) {
|
||||
aSignature.Clear();
|
||||
aSignature.AppendElements(mSignature);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CtapSignResult::GetUserHandle(nsTArray<uint8_t>& aUserHandle) {
|
||||
aUserHandle.Clear();
|
||||
aUserHandle.AppendElements(mUserHandle);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CtapSignResult::GetUserName(nsACString& aUserName) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CtapSignResult::GetRpIdHash(nsTArray<uint8_t>& aRpIdHash) {
|
||||
aRpIdHash.Clear();
|
||||
aRpIdHash.AppendElements(mRpIdHash);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace mozilla::dom
|
@ -1,65 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=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/. */
|
||||
|
||||
#ifndef CtapResults_h
|
||||
#define CtapResults_h
|
||||
|
||||
#include "mozilla/dom/WebAuthnTransactionChild.h"
|
||||
#include "nsIWebAuthnController.h"
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class CtapRegisterResult final : public nsICtapRegisterResult {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICTAPREGISTERRESULT
|
||||
|
||||
explicit CtapRegisterResult(nsresult aStatus,
|
||||
nsTArray<uint8_t>&& aAttestationObject,
|
||||
nsTArray<uint8_t>&& aCredentialId)
|
||||
: mStatus(aStatus),
|
||||
mAttestationObject(std::move(aAttestationObject)),
|
||||
mCredentialId(std::move(aCredentialId)) {}
|
||||
|
||||
private:
|
||||
~CtapRegisterResult() = default;
|
||||
|
||||
nsresult mStatus;
|
||||
nsTArray<uint8_t> mAttestationObject;
|
||||
nsTArray<uint8_t> mCredentialId;
|
||||
};
|
||||
|
||||
class CtapSignResult final : public nsICtapSignResult {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICTAPSIGNRESULT
|
||||
|
||||
explicit CtapSignResult(nsresult aStatus, nsTArray<uint8_t>&& aCredentialId,
|
||||
nsTArray<uint8_t>&& aSignature,
|
||||
nsTArray<uint8_t>&& aAuthenticatorData,
|
||||
nsTArray<uint8_t>&& aUserHandle,
|
||||
nsTArray<uint8_t>&& aRpIdHash)
|
||||
: mStatus(aStatus),
|
||||
mCredentialId(std::move(aCredentialId)),
|
||||
mSignature(std::move(aSignature)),
|
||||
mAuthenticatorData(std::move(aAuthenticatorData)),
|
||||
mUserHandle(std::move(aUserHandle)),
|
||||
mRpIdHash(std::move(aRpIdHash)) {}
|
||||
|
||||
private:
|
||||
~CtapSignResult() = default;
|
||||
|
||||
nsresult mStatus;
|
||||
nsTArray<uint8_t> mCredentialId;
|
||||
nsTArray<uint8_t> mSignature;
|
||||
nsTArray<uint8_t> mAuthenticatorData;
|
||||
nsTArray<uint8_t> mUserHandle;
|
||||
nsTArray<uint8_t> mRpIdHash;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // CtapResult_h
|
File diff suppressed because it is too large
Load Diff
@ -1,53 +0,0 @@
|
||||
/* -*- 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/. */
|
||||
|
||||
#ifndef mozilla_dom_U2FSoftTokenTransport_h
|
||||
#define mozilla_dom_U2FSoftTokenTransport_h
|
||||
|
||||
#include "nsIWebAuthnController.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
|
||||
/*
|
||||
* U2FSoftTokenManager is a software implementation of a secure token manager
|
||||
* for the U2F and WebAuthn APIs.
|
||||
*/
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
class U2FSoftTokenTransport final : public nsIWebAuthnTransport {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBAUTHNTRANSPORT
|
||||
|
||||
explicit U2FSoftTokenTransport(uint32_t aCounter);
|
||||
|
||||
private:
|
||||
~U2FSoftTokenTransport() = default;
|
||||
nsresult Init();
|
||||
|
||||
nsresult IsRegistered(const nsTArray<uint8_t>& aKeyHandle,
|
||||
const nsTArray<uint8_t>& aAppParam, bool& aResult);
|
||||
|
||||
bool FindRegisteredKeyHandle(
|
||||
const nsTArray<nsTArray<uint8_t>>& aAppIds,
|
||||
const nsTArray<nsTArray<uint8_t>>& aCredentialIds,
|
||||
/*out*/ nsTArray<uint8_t>& aKeyHandle,
|
||||
/*out*/ nsTArray<uint8_t>& aAppId);
|
||||
|
||||
bool mInitialized;
|
||||
mozilla::UniquePK11SymKey mWrappingKey;
|
||||
|
||||
static const nsCString mSecretNickname;
|
||||
|
||||
nsresult GetOrCreateWrappingKey(const mozilla::UniquePK11SlotInfo& aSlot);
|
||||
uint32_t mCounter;
|
||||
|
||||
nsCOMPtr<nsIWebAuthnController> mController;
|
||||
};
|
||||
|
||||
} // namespace mozilla::dom
|
||||
|
||||
#endif // mozilla_dom_U2FSoftTokenTransport_h
|
@ -10,89 +10,6 @@
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
nsresult CBOREncodePublicKeyObj(const CryptoBuffer& aPubKeyBuf,
|
||||
/* out */ CryptoBuffer& aPubKeyObj) {
|
||||
mozilla::dom::CryptoBuffer xBuf, yBuf;
|
||||
nsresult rv = U2FDecomposeECKey(aPubKeyBuf, xBuf, yBuf);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// COSE_Key object. See https://tools.ietf.org/html/rfc8152#section-7
|
||||
cbor::output_dynamic cborPubKeyOut;
|
||||
cbor::encoder encoder(cborPubKeyOut);
|
||||
encoder.write_map(5);
|
||||
{
|
||||
encoder.write_int(1); // kty
|
||||
encoder.write_int(2); // EC2
|
||||
encoder.write_int(3); // alg
|
||||
encoder.write_int(-7); // ES256
|
||||
|
||||
// See https://tools.ietf.org/html/rfc8152#section-13.1
|
||||
encoder.write_int(-1); // crv
|
||||
encoder.write_int(1); // P-256
|
||||
encoder.write_int(-2); // x
|
||||
encoder.write_bytes(xBuf.Elements(), xBuf.Length());
|
||||
encoder.write_int(-3); // y
|
||||
encoder.write_bytes(yBuf.Elements(), yBuf.Length());
|
||||
}
|
||||
|
||||
if (!aPubKeyObj.Assign(cborPubKeyOut.data(), cborPubKeyOut.size())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult CBOREncodeFidoU2FAttestationObj(
|
||||
const CryptoBuffer& aAuthDataBuf, const CryptoBuffer& aAttestationCertBuf,
|
||||
const CryptoBuffer& aSignatureBuf,
|
||||
/* out */ CryptoBuffer& aAttestationObj) {
|
||||
/*
|
||||
Attestation Object, encoded in CBOR (description is CDDL)
|
||||
|
||||
attObj = {
|
||||
authData: bytes,
|
||||
$$attStmtType
|
||||
}
|
||||
$$attStmtType //= (
|
||||
fmt: "fido-u2f",
|
||||
attStmt: u2fStmtFormat
|
||||
)
|
||||
u2fStmtFormat = {
|
||||
x5c: [ attestnCert: bytes, * (caCert: bytes) ],
|
||||
sig: bytes
|
||||
}
|
||||
*/
|
||||
cbor::output_dynamic cborAttOut;
|
||||
cbor::encoder encoder(cborAttOut);
|
||||
encoder.write_map(3);
|
||||
{
|
||||
encoder.write_string("fmt");
|
||||
encoder.write_string("fido-u2f");
|
||||
|
||||
encoder.write_string("attStmt");
|
||||
encoder.write_map(2);
|
||||
{
|
||||
encoder.write_string("sig");
|
||||
encoder.write_bytes(aSignatureBuf.Elements(), aSignatureBuf.Length());
|
||||
|
||||
encoder.write_string("x5c");
|
||||
// U2F wire protocol can only deliver 1 certificate, so it's never a chain
|
||||
encoder.write_array(1);
|
||||
encoder.write_bytes(aAttestationCertBuf.Elements(),
|
||||
aAttestationCertBuf.Length());
|
||||
}
|
||||
|
||||
encoder.write_string("authData");
|
||||
encoder.write_bytes(aAuthDataBuf.Elements(), aAuthDataBuf.Length());
|
||||
}
|
||||
|
||||
if (!aAttestationObj.Assign(cborAttOut.data(), cborAttOut.size())) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult CBOREncodeNoneAttestationObj(const CryptoBuffer& aAuthDataBuf,
|
||||
/* out */ CryptoBuffer& aAttestationObj) {
|
||||
/*
|
||||
|
@ -15,14 +15,6 @@
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
nsresult CBOREncodePublicKeyObj(const CryptoBuffer& aPubKeyBuf,
|
||||
/* out */ CryptoBuffer& aPubKeyObj);
|
||||
|
||||
nsresult CBOREncodeFidoU2FAttestationObj(
|
||||
const CryptoBuffer& aAuthDataBuf, const CryptoBuffer& aAttestationCertBuf,
|
||||
const CryptoBuffer& aSignatureBuf,
|
||||
/* out */ CryptoBuffer& aAttestationObj);
|
||||
|
||||
nsresult CBOREncodeNoneAttestationObj(const CryptoBuffer& aAuthDataBuf,
|
||||
/* out */ CryptoBuffer& aAttestationObj);
|
||||
|
||||
|
@ -23,8 +23,6 @@
|
||||
|
||||
#include "AuthrsTransport.h"
|
||||
#include "CtapArgs.h"
|
||||
#include "CtapResults.h"
|
||||
#include "U2FSoftTokenTransport.h"
|
||||
#include "WebAuthnEnumStrings.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
|
@ -22,9 +22,6 @@ constexpr auto kGoogleAccountsAppId1 =
|
||||
constexpr auto kGoogleAccountsAppId2 =
|
||||
u"https://www.gstatic.com/securitykey/a/google.com/origins.json"_ns;
|
||||
|
||||
const uint8_t FLAG_TUP = 0x01; // Test of User Presence required
|
||||
const uint8_t FLAG_AT = 0x40; // Authenticator Data is provided
|
||||
|
||||
bool EvaluateAppID(nsPIDOMWindowInner* aParent, const nsString& aOrigin,
|
||||
/* in/out */ nsString& aAppId) {
|
||||
// Facet is the specification's way of referring to the web origin.
|
||||
@ -134,253 +131,6 @@ nsresult ReadToCryptoBuffer(pkix::Reader& aSrc, /* out */ CryptoBuffer& aDest,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Format:
|
||||
// 32 bytes: SHA256 of the RP ID
|
||||
// 1 byte: flags (TUP & AT)
|
||||
// 4 bytes: sign counter
|
||||
// variable: attestation data struct
|
||||
// variable: CBOR-format extension auth data (optional, not flagged)
|
||||
nsresult AssembleAuthenticatorData(const CryptoBuffer& rpIdHashBuf,
|
||||
const uint8_t flags,
|
||||
const CryptoBuffer& counterBuf,
|
||||
const CryptoBuffer& attestationDataBuf,
|
||||
/* out */ CryptoBuffer& authDataBuf) {
|
||||
if (NS_WARN_IF(!authDataBuf.SetCapacity(
|
||||
32 + 1 + 4 + attestationDataBuf.Length(), mozilla::fallible))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (rpIdHashBuf.Length() != 32 || counterBuf.Length() != 4) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
(void)authDataBuf.AppendElements(rpIdHashBuf, mozilla::fallible);
|
||||
(void)authDataBuf.AppendElement(flags, mozilla::fallible);
|
||||
(void)authDataBuf.AppendElements(counterBuf, mozilla::fallible);
|
||||
(void)authDataBuf.AppendElements(attestationDataBuf, mozilla::fallible);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// attestation data struct format:
|
||||
// - 16 bytes: AAGUID
|
||||
// - 2 bytes: Length of Credential ID
|
||||
// - L bytes: Credential ID
|
||||
// - variable: CBOR-format public key
|
||||
nsresult AssembleAttestationData(const CryptoBuffer& aaguidBuf,
|
||||
const CryptoBuffer& keyHandleBuf,
|
||||
const CryptoBuffer& pubKeyObj,
|
||||
/* out */ CryptoBuffer& attestationDataBuf) {
|
||||
if (NS_WARN_IF(!attestationDataBuf.SetCapacity(
|
||||
aaguidBuf.Length() + 2 + keyHandleBuf.Length() + pubKeyObj.Length(),
|
||||
mozilla::fallible))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
if (keyHandleBuf.Length() > 0xFFFF) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
(void)attestationDataBuf.AppendElements(aaguidBuf, mozilla::fallible);
|
||||
(void)attestationDataBuf.AppendElement((keyHandleBuf.Length() >> 8) & 0xFF,
|
||||
mozilla::fallible);
|
||||
(void)attestationDataBuf.AppendElement((keyHandleBuf.Length() >> 0) & 0xFF,
|
||||
mozilla::fallible);
|
||||
(void)attestationDataBuf.AppendElements(keyHandleBuf, mozilla::fallible);
|
||||
(void)attestationDataBuf.AppendElements(pubKeyObj, mozilla::fallible);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult AssembleAttestationObject(const CryptoBuffer& aRpIdHash,
|
||||
const CryptoBuffer& aPubKeyBuf,
|
||||
const CryptoBuffer& aKeyHandleBuf,
|
||||
const CryptoBuffer& aAttestationCertBuf,
|
||||
const CryptoBuffer& aSignatureBuf,
|
||||
bool aForceNoneAttestation,
|
||||
/* out */ CryptoBuffer& aAttestationObjBuf) {
|
||||
// Construct the public key object
|
||||
CryptoBuffer pubKeyObj;
|
||||
nsresult rv = CBOREncodePublicKeyObj(aPubKeyBuf, pubKeyObj);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mozilla::dom::CryptoBuffer aaguidBuf;
|
||||
if (NS_WARN_IF(!aaguidBuf.SetCapacity(16, mozilla::fallible))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// FIDO U2F devices have no AAGUIDs, so they'll be all zeros until we add
|
||||
// support for CTAP2 devices.
|
||||
for (int i = 0; i < 16; i++) {
|
||||
// SetCapacity was just called, these cannot fail.
|
||||
(void)aaguidBuf.AppendElement(0x00, mozilla::fallible);
|
||||
}
|
||||
|
||||
// During create credential, counter is always 0 for U2F
|
||||
// See https://github.com/w3c/webauthn/issues/507
|
||||
mozilla::dom::CryptoBuffer counterBuf;
|
||||
if (NS_WARN_IF(!counterBuf.SetCapacity(4, mozilla::fallible))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
// SetCapacity was just called, these cannot fail.
|
||||
(void)counterBuf.AppendElement(0x00, mozilla::fallible);
|
||||
(void)counterBuf.AppendElement(0x00, mozilla::fallible);
|
||||
(void)counterBuf.AppendElement(0x00, mozilla::fallible);
|
||||
(void)counterBuf.AppendElement(0x00, mozilla::fallible);
|
||||
|
||||
// Construct the Attestation Data, which slots into the end of the
|
||||
// Authentication Data buffer.
|
||||
CryptoBuffer attDataBuf;
|
||||
rv = AssembleAttestationData(aaguidBuf, aKeyHandleBuf, pubKeyObj, attDataBuf);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
CryptoBuffer authDataBuf;
|
||||
// attDataBuf always contains data, so per [1] we have to set the AT flag.
|
||||
// [1] https://w3c.github.io/webauthn/#sec-authenticator-data
|
||||
const uint8_t flags = FLAG_TUP | FLAG_AT;
|
||||
rv = AssembleAuthenticatorData(aRpIdHash, flags, counterBuf, attDataBuf,
|
||||
authDataBuf);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Direct attestation might have been requested by the RP.
|
||||
// The user might override this and request anonymization anyway.
|
||||
if (aForceNoneAttestation) {
|
||||
rv = CBOREncodeNoneAttestationObj(authDataBuf, aAttestationObjBuf);
|
||||
} else {
|
||||
rv = CBOREncodeFidoU2FAttestationObj(authDataBuf, aAttestationCertBuf,
|
||||
aSignatureBuf, aAttestationObjBuf);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult U2FDecomposeSignResponse(const CryptoBuffer& aResponse,
|
||||
/* out */ uint8_t& aFlags,
|
||||
/* out */ CryptoBuffer& aCounterBuf,
|
||||
/* out */ CryptoBuffer& aSignatureBuf) {
|
||||
if (aResponse.Length() < 5) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
Span<const uint8_t> rspView = Span(aResponse);
|
||||
aFlags = rspView[0];
|
||||
|
||||
if (NS_WARN_IF(!aCounterBuf.AppendElements(rspView.FromTo(1, 5),
|
||||
mozilla::fallible))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(
|
||||
!aSignatureBuf.AppendElements(rspView.From(5), mozilla::fallible))) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult U2FDecomposeRegistrationResponse(
|
||||
const CryptoBuffer& aResponse,
|
||||
/* out */ CryptoBuffer& aPubKeyBuf,
|
||||
/* out */ CryptoBuffer& aKeyHandleBuf,
|
||||
/* out */ CryptoBuffer& aAttestationCertBuf,
|
||||
/* out */ CryptoBuffer& aSignatureBuf) {
|
||||
// U2F v1.1 Format via
|
||||
// http://fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-raw-message-formats-v1.1-id-20160915.html
|
||||
//
|
||||
// Bytes Value
|
||||
// 1 0x05
|
||||
// 65 public key
|
||||
// 1 key handle length
|
||||
// * key handle
|
||||
// ASN.1 attestation certificate
|
||||
// * attestation signature
|
||||
|
||||
pkix::Input u2fResponse;
|
||||
u2fResponse.Init(aResponse.Elements(), aResponse.Length());
|
||||
|
||||
pkix::Reader input(u2fResponse);
|
||||
|
||||
uint8_t b;
|
||||
if (input.Read(b) != pkix::Success) {
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
if (b != 0x05) {
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
nsresult rv = ReadToCryptoBuffer(input, aPubKeyBuf, 65);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
uint8_t handleLen;
|
||||
if (input.Read(handleLen) != pkix::Success) {
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
rv = ReadToCryptoBuffer(input, aKeyHandleBuf, handleLen);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// We have to parse the ASN.1 SEQUENCE on the outside to determine the cert's
|
||||
// length.
|
||||
pkix::Input cert;
|
||||
if (pkix::der::ExpectTagAndGetTLV(input, pkix::der::SEQUENCE, cert) !=
|
||||
pkix::Success) {
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
pkix::Reader certInput(cert);
|
||||
rv = ReadToCryptoBuffer(certInput, aAttestationCertBuf, cert.GetLength());
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// The remainder of u2fResponse is the signature
|
||||
pkix::Input u2fSig;
|
||||
input.SkipToEnd(u2fSig);
|
||||
pkix::Reader sigInput(u2fSig);
|
||||
rv = ReadToCryptoBuffer(sigInput, aSignatureBuf, u2fSig.GetLength());
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(input.AtEnd());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult U2FDecomposeECKey(const CryptoBuffer& aPubKeyBuf,
|
||||
/* out */ CryptoBuffer& aXcoord,
|
||||
/* out */ CryptoBuffer& aYcoord) {
|
||||
pkix::Input pubKey;
|
||||
pubKey.Init(aPubKeyBuf.Elements(), aPubKeyBuf.Length());
|
||||
|
||||
pkix::Reader input(pubKey);
|
||||
uint8_t b;
|
||||
if (input.Read(b) != pkix::Success) {
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
if (b != 0x04) {
|
||||
return NS_ERROR_DOM_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
nsresult rv = ReadToCryptoBuffer(input, aXcoord, 32);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = ReadToCryptoBuffer(input, aYcoord, 32);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(input.AtEnd());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult HashCString(nsICryptoHash* aHashService, const nsACString& aIn,
|
||||
/* out */ CryptoBuffer& aOut) {
|
||||
MOZ_ASSERT(aHashService);
|
||||
|
@ -18,41 +18,9 @@
|
||||
|
||||
namespace mozilla::dom {
|
||||
|
||||
enum class U2FOperation { Register, Sign };
|
||||
|
||||
bool EvaluateAppID(nsPIDOMWindowInner* aParent, const nsString& aOrigin,
|
||||
/* in/out */ nsString& aAppId);
|
||||
|
||||
nsresult AssembleAuthenticatorData(const CryptoBuffer& rpIdHashBuf,
|
||||
const uint8_t flags,
|
||||
const CryptoBuffer& counterBuf,
|
||||
const CryptoBuffer& attestationDataBuf,
|
||||
/* out */ CryptoBuffer& authDataBuf);
|
||||
|
||||
nsresult AssembleAttestationObject(const CryptoBuffer& aRpIdHash,
|
||||
const CryptoBuffer& aPubKeyBuf,
|
||||
const CryptoBuffer& aKeyHandleBuf,
|
||||
const CryptoBuffer& aAttestationCertBuf,
|
||||
const CryptoBuffer& aSignatureBuf,
|
||||
bool aForceNoneAttestation,
|
||||
/* out */ CryptoBuffer& aAttestationObjBuf);
|
||||
|
||||
nsresult U2FDecomposeSignResponse(const CryptoBuffer& aResponse,
|
||||
/* out */ uint8_t& aFlags,
|
||||
/* out */ CryptoBuffer& aCounterBuf,
|
||||
/* out */ CryptoBuffer& aSignatureBuf);
|
||||
|
||||
nsresult U2FDecomposeRegistrationResponse(
|
||||
const CryptoBuffer& aResponse,
|
||||
/* out */ CryptoBuffer& aPubKeyBuf,
|
||||
/* out */ CryptoBuffer& aKeyHandleBuf,
|
||||
/* out */ CryptoBuffer& aAttestationCertBuf,
|
||||
/* out */ CryptoBuffer& aSignatureBuf);
|
||||
|
||||
nsresult U2FDecomposeECKey(const CryptoBuffer& aPubKeyBuf,
|
||||
/* out */ CryptoBuffer& aXcoord,
|
||||
/* out */ CryptoBuffer& aYcoord);
|
||||
|
||||
nsresult HashCString(const nsACString& aIn, /* out */ CryptoBuffer& aOut);
|
||||
|
||||
nsresult BuildTransactionHashes(const nsCString& aRpId,
|
||||
|
@ -38,9 +38,7 @@ UNIFIED_SOURCES += [
|
||||
"cbor-cpp/src/encoder.cpp",
|
||||
"cbor-cpp/src/output_dynamic.cpp",
|
||||
"CtapArgs.cpp",
|
||||
"CtapResults.cpp",
|
||||
"PublicKeyCredential.cpp",
|
||||
"U2FSoftTokenTransport.cpp",
|
||||
"U2FTokenManager.cpp",
|
||||
"WebAuthnCBORUtil.cpp",
|
||||
"WebAuthnController.cpp",
|
||||
|
@ -13854,12 +13854,6 @@
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
# Global counter for U2F soft token operations
|
||||
- name: security.webauth.softtoken_counter
|
||||
type: RelaxedAtomicUint32
|
||||
value: 0
|
||||
mirror: always
|
||||
|
||||
# Block Worker/SharedWorker scripts with wrong MIME type.
|
||||
- name: security.block_Worker_with_wrong_mime
|
||||
type: bool
|
||||
|
Loading…
Reference in New Issue
Block a user