--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -127,17 +127,16 @@
#include "nsIFormProcessor.h"
#include "nsIGfxInfo.h"
#include "nsIIdleService.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIMemoryInfoDumper.h"
#include "nsIMemoryReporter.h"
#include "nsIMozBrowserFrame.h"
#include "nsIMutable.h"
-#include "nsINSSU2FToken.h"
#include "nsIObserverService.h"
#include "nsIParentChannel.h"
#include "nsIPresShell.h"
#include "nsIRemoteWindowContext.h"
#include "nsIScriptError.h"
#include "nsIScriptSecurityManager.h"
#include "nsISiteSecurityService.h"
#include "nsISpellChecker.h"
@@ -3546,115 +3545,16 @@ ContentParent::RecvSetURITitle(const URI
nsCOMPtr<IHistory> history = services::GetHistoryService();
if (history) {
history->SetURITitle(ourURI, title);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
-ContentParent::RecvNSSU2FTokenIsCompatibleVersion(const nsString& aVersion,
- bool* aIsCompatible)
-{
- MOZ_ASSERT(aIsCompatible);
-
- nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
- if (NS_WARN_IF(!nssToken)) {
- return IPC_FAIL_NO_REASON(this);
- }
-
- nsresult rv = nssToken->IsCompatibleVersion(aVersion, aIsCompatible);
- if (NS_FAILED(rv)) {
- return IPC_FAIL_NO_REASON(this);
- }
- return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-ContentParent::RecvNSSU2FTokenIsRegistered(nsTArray<uint8_t>&& aKeyHandle,
- nsTArray<uint8_t>&& aApplication,
- bool* aIsValidKeyHandle)
-{
- MOZ_ASSERT(aIsValidKeyHandle);
-
- nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
- if (NS_WARN_IF(!nssToken)) {
- return IPC_FAIL_NO_REASON(this);
- }
-
- nsresult rv = nssToken->IsRegistered(aKeyHandle.Elements(), aKeyHandle.Length(),
- aApplication.Elements(), aApplication.Length(),
- aIsValidKeyHandle);
- if (NS_FAILED(rv)) {
- return IPC_FAIL_NO_REASON(this);
- }
- return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-ContentParent::RecvNSSU2FTokenRegister(nsTArray<uint8_t>&& aApplication,
- nsTArray<uint8_t>&& aChallenge,
- nsTArray<uint8_t>* aRegistration)
-{
- MOZ_ASSERT(aRegistration);
-
- nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
- if (NS_WARN_IF(!nssToken)) {
- return IPC_FAIL_NO_REASON(this);
- }
- uint8_t* buffer;
- uint32_t bufferlen;
- nsresult rv = nssToken->Register(aApplication.Elements(), aApplication.Length(),
- aChallenge.Elements(), aChallenge.Length(),
- &buffer, &bufferlen);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return IPC_FAIL_NO_REASON(this);
- }
-
- MOZ_ASSERT(buffer);
- aRegistration->ReplaceElementsAt(0, aRegistration->Length(), buffer, bufferlen);
- free(buffer);
- if (NS_FAILED(rv)) {
- return IPC_FAIL_NO_REASON(this);
- }
- return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
-ContentParent::RecvNSSU2FTokenSign(nsTArray<uint8_t>&& aApplication,
- nsTArray<uint8_t>&& aChallenge,
- nsTArray<uint8_t>&& aKeyHandle,
- nsTArray<uint8_t>* aSignature)
-{
- MOZ_ASSERT(aSignature);
-
- nsCOMPtr<nsINSSU2FToken> nssToken(do_GetService(NS_NSSU2FTOKEN_CONTRACTID));
- if (NS_WARN_IF(!nssToken)) {
- return IPC_FAIL_NO_REASON(this);
- }
- uint8_t* buffer;
- uint32_t bufferlen;
- nsresult rv = nssToken->Sign(aApplication.Elements(), aApplication.Length(),
- aChallenge.Elements(), aChallenge.Length(),
- aKeyHandle.Elements(), aKeyHandle.Length(),
- &buffer, &bufferlen);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return IPC_FAIL_NO_REASON(this);
- }
-
- MOZ_ASSERT(buffer);
- aSignature->ReplaceElementsAt(0, aSignature->Length(), buffer, bufferlen);
- free(buffer);
- if (NS_FAILED(rv)) {
- return IPC_FAIL_NO_REASON(this);
- }
- return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
ContentParent::RecvIsSecureURI(const uint32_t& aType,
const URIParams& aURI,
const uint32_t& aFlags,
const OriginAttributes& aOriginAttributes,
bool* aIsSecureURI)
{
nsCOMPtr<nsISiteSecurityService> sss(do_GetService(NS_SSSERVICE_CONTRACTID));
if (!sss) {
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -855,32 +855,16 @@ private:
virtual PIPCBlobInputStreamParent*
AllocPIPCBlobInputStreamParent(const nsID& aID,
const uint64_t& aSize) override;
virtual bool
DeallocPIPCBlobInputStreamParent(PIPCBlobInputStreamParent* aActor) override;
- virtual mozilla::ipc::IPCResult RecvNSSU2FTokenIsCompatibleVersion(const nsString& aVersion,
- bool* aIsCompatible) override;
-
- virtual mozilla::ipc::IPCResult RecvNSSU2FTokenIsRegistered(nsTArray<uint8_t>&& aKeyHandle,
- nsTArray<uint8_t>&& aApplication,
- bool* aIsValidKeyHandle) override;
-
- virtual mozilla::ipc::IPCResult RecvNSSU2FTokenRegister(nsTArray<uint8_t>&& aApplication,
- nsTArray<uint8_t>&& aChallenge,
- nsTArray<uint8_t>* aRegistration) override;
-
- virtual mozilla::ipc::IPCResult RecvNSSU2FTokenSign(nsTArray<uint8_t>&& aApplication,
- nsTArray<uint8_t>&& aChallenge,
- nsTArray<uint8_t>&& aKeyHandle,
- nsTArray<uint8_t>* aSignature) override;
-
virtual mozilla::ipc::IPCResult RecvIsSecureURI(const uint32_t& aType, const URIParams& aURI,
const uint32_t& aFlags,
const OriginAttributes& aOriginAttributes,
bool* aIsSecureURI) override;
virtual mozilla::ipc::IPCResult RecvAccumulateMixedContentHSTS(const URIParams& aURI,
const bool& aActive,
const bool& aHSTSPriming,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -697,61 +697,16 @@ parent:
returns (nsresult rv, Endpoint<PPluginModuleParent> aEndpoint);
async PJavaScript();
async PRemoteSpellcheckEngine();
async InitCrashReporter(Shmem shmem, NativeThreadId tid);
- /**
- * Is this token compatible with the provided version?
- *
- * |version| The offered version to test
- * Returns |True| if the offered version is compatible
- */
- sync NSSU2FTokenIsCompatibleVersion(nsString version)
- returns (bool result);
-
- /**
- * Return whether the provided KeyHandle belongs to this Token
- *
- * |keyHandle| Key Handle to evaluate.
- * |application| The FIDO Application data that is associated with this key.
- * Returns |True| if the Key Handle is ours.
- */
- sync NSSU2FTokenIsRegistered(uint8_t[] keyHandle, uint8_t[] application)
- returns (bool isValidKeyHandle);
-
- /**
- * Generates a public/private keypair for the provided application
- * and challenge, returning the pubkey, challenge response, and
- * key handle in the registration data.
- *
- * |application| The FIDO Application data to associate with the key.
- * |challenge| The Challenge to satisfy in the response.
- * |registration| An array containing the pubkey, challenge response,
- * and key handle.
- */
- sync NSSU2FTokenRegister(uint8_t[] application, uint8_t[] challenge)
- returns (uint8_t[] registration);
-
- /**
- * Creates a signature over the "param" arguments using the private key
- * provided in the key handle argument.
- *
- * |application| The FIDO Application data to associate with the key.
- * |challenge| The Challenge to satisfy in the response.
- * |keyHandle| The Key Handle opaque object to use.
- * |signature| The resulting signature.
- */
- sync NSSU2FTokenSign(uint8_t[] application, uint8_t[] challenge,
- uint8_t[] keyHandle)
- returns (uint8_t[] signature);
-
sync IsSecureURI(uint32_t aType, URIParams aURI, uint32_t aFlags,
OriginAttributes aOriginAttributes)
returns (bool isSecureURI);
async AccumulateMixedContentHSTS(URIParams aURI, bool aActive, bool aHasHSTSPriming,
OriginAttributes aOriginAttributes);
nested(inside_cpow) async PHal();
deleted file mode 100644
--- a/dom/webauthn/NSSU2FTokenRemote.cpp
+++ /dev/null
@@ -1,158 +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 "mozilla/dom/ContentChild.h"
-
-#include "NSSU2FTokenRemote.h"
-
-using mozilla::dom::ContentChild;
-
-NS_IMPL_ISUPPORTS(NSSU2FTokenRemote, nsIU2FToken)
-
-static mozilla::LazyLogModule gWebauthLog("webauth_u2f");
-
-NSSU2FTokenRemote::NSSU2FTokenRemote()
-{}
-
-NSSU2FTokenRemote::~NSSU2FTokenRemote()
-{}
-
-NS_IMETHODIMP
-NSSU2FTokenRemote::IsCompatibleVersion(const nsAString& aVersionString,
- bool* aIsCompatible)
-{
- NS_ENSURE_ARG_POINTER(aIsCompatible);
-
- ContentChild* cc = ContentChild::GetSingleton();
- MOZ_ASSERT(cc);
- if (!cc->SendNSSU2FTokenIsCompatibleVersion(
- nsString(aVersionString), aIsCompatible)) {
- return NS_ERROR_FAILURE;
- }
- return NS_OK;
-}
-
-NS_IMETHODIMP
-NSSU2FTokenRemote::IsRegistered(uint8_t* aKeyHandle, uint32_t aKeyHandleLen,
- uint8_t* aAppParam, uint32_t aAppParamLen,
- bool* aIsRegistered)
-{
- NS_ENSURE_ARG_POINTER(aKeyHandle);
- NS_ENSURE_ARG_POINTER(aAppParam);
- NS_ENSURE_ARG_POINTER(aIsRegistered);
-
- nsTArray<uint8_t> keyHandle;
- if (!keyHandle.ReplaceElementsAt(0, keyHandle.Length(), aKeyHandle,
- aKeyHandleLen)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- nsTArray<uint8_t> appParam;
- if (!appParam.ReplaceElementsAt(0, appParam.Length(), aAppParam,
- aAppParamLen)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- ContentChild* cc = ContentChild::GetSingleton();
- MOZ_ASSERT(cc);
- if (!cc->SendNSSU2FTokenIsRegistered(keyHandle, appParam, aIsRegistered)) {
- return NS_ERROR_FAILURE;
- }
- return NS_OK;
-}
-
-NS_IMETHODIMP
-NSSU2FTokenRemote::Register(uint8_t* aApplication,
- uint32_t aApplicationLen,
- uint8_t* aChallenge,
- uint32_t aChallengeLen,
- uint8_t** aRegistration,
- uint32_t* aRegistrationLen)
-{
- NS_ENSURE_ARG_POINTER(aApplication);
- NS_ENSURE_ARG_POINTER(aChallenge);
- NS_ENSURE_ARG_POINTER(aRegistration);
- NS_ENSURE_ARG_POINTER(aRegistrationLen);
-
- nsTArray<uint8_t> application;
- if (!application.ReplaceElementsAt(0, application.Length(), aApplication,
- aApplicationLen)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- nsTArray<uint8_t> challenge;
- if (!challenge.ReplaceElementsAt(0, challenge.Length(), aChallenge,
- aChallengeLen)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- nsTArray<uint8_t> registrationBuffer;
- ContentChild* cc = ContentChild::GetSingleton();
- MOZ_ASSERT(cc);
- if (!cc->SendNSSU2FTokenRegister(application, challenge,
- ®istrationBuffer)) {
- return NS_ERROR_FAILURE;
- }
-
- size_t dataLen = registrationBuffer.Length();
- uint8_t* tmp = reinterpret_cast<uint8_t*>(moz_xmalloc(dataLen));
- if (NS_WARN_IF(!tmp)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- memcpy(tmp, registrationBuffer.Elements(), dataLen);
- *aRegistration = tmp;
- *aRegistrationLen = dataLen;
- return NS_OK;
-}
-
-NS_IMETHODIMP
-NSSU2FTokenRemote::Sign(uint8_t* aApplication, uint32_t aApplicationLen,
- uint8_t* aChallenge, uint32_t aChallengeLen,
- uint8_t* aKeyHandle, uint32_t aKeyHandleLen,
- uint8_t** aSignature, uint32_t* aSignatureLen)
-{
- NS_ENSURE_ARG_POINTER(aApplication);
- NS_ENSURE_ARG_POINTER(aChallenge);
- NS_ENSURE_ARG_POINTER(aKeyHandle);
- NS_ENSURE_ARG_POINTER(aSignature);
- NS_ENSURE_ARG_POINTER(aSignatureLen);
-
- nsTArray<uint8_t> application;
- if (!application.ReplaceElementsAt(0, application.Length(), aApplication,
- aApplicationLen)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- nsTArray<uint8_t> challenge;
- if (!challenge.ReplaceElementsAt(0, challenge.Length(), aChallenge,
- aChallengeLen)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- nsTArray<uint8_t> keyHandle;
- if (!keyHandle.ReplaceElementsAt(0, keyHandle.Length(), aKeyHandle,
- aKeyHandleLen)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- nsTArray<uint8_t> signatureBuffer;
- ContentChild* cc = ContentChild::GetSingleton();
- MOZ_ASSERT(cc);
- if (!cc->SendNSSU2FTokenSign(application, challenge, keyHandle,
- &signatureBuffer)) {
- return NS_ERROR_FAILURE;
- }
-
- size_t dataLen = signatureBuffer.Length();
- uint8_t* tmp = reinterpret_cast<uint8_t*>(moz_xmalloc(dataLen));
- if (NS_WARN_IF(!tmp)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- memcpy(tmp, signatureBuffer.Elements(), dataLen);
- *aSignature = tmp;
- *aSignatureLen = dataLen;
- return NS_OK;
-}
deleted file mode 100644
--- a/dom/webauthn/NSSU2FTokenRemote.h
+++ /dev/null
@@ -1,24 +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 NSSU2FTokenRemote_h
-#define NSSU2FTokenRemote_h
-
-#include "nsIU2FToken.h"
-
-class NSSU2FTokenRemote : public nsIU2FToken
-{
-public:
- NS_DECL_THREADSAFE_ISUPPORTS
- NS_DECL_NSIU2FTOKEN
-
- NSSU2FTokenRemote();
-
-private:
- virtual ~NSSU2FTokenRemote();
-};
-
-#endif // NSSU2FTokenRemote_h
--- a/dom/webauthn/moz.build
+++ b/dom/webauthn/moz.build
@@ -10,17 +10,16 @@ with Files("**"):
IPDL_SOURCES += [
'PWebAuthnTransaction.ipdl'
]
EXPORTS.mozilla.dom += [
'AuthenticatorAssertionResponse.h',
'AuthenticatorAttestationResponse.h',
'AuthenticatorResponse.h',
- 'NSSU2FTokenRemote.h',
'PublicKeyCredential.h',
'U2FHIDTokenManager.h',
'U2FSoftTokenManager.h',
'U2FTokenManager.h',
'U2FTokenTransport.h',
'WebAuthnCBORUtil.h',
'WebAuthnManager.h',
'WebAuthnRequest.h',
@@ -30,17 +29,16 @@ EXPORTS.mozilla.dom += [
]
UNIFIED_SOURCES += [
'AuthenticatorAssertionResponse.cpp',
'AuthenticatorAttestationResponse.cpp',
'AuthenticatorResponse.cpp',
'cbor-cpp/src/encoder.cpp',
'cbor-cpp/src/output_dynamic.cpp',
- 'NSSU2FTokenRemote.cpp',
'PublicKeyCredential.cpp',
'U2FHIDTokenManager.cpp',
'U2FSoftTokenManager.cpp',
'U2FTokenManager.cpp',
'WebAuthnCBORUtil.cpp',
'WebAuthnManager.cpp',
'WebAuthnTransactionChild.cpp',
'WebAuthnTransactionParent.cpp',
--- a/ipc/ipdl/sync-messages.ini
+++ b/ipc/ipdl/sync-messages.ini
@@ -851,24 +851,16 @@ description =
[PContent::CreateChildProcess]
description =
[PContent::BridgeToChildProcess]
description =
[PContent::LoadPlugin]
description =
[PContent::ConnectPluginBridge]
description =
-[PContent::NSSU2FTokenIsCompatibleVersion]
-description =
-[PContent::NSSU2FTokenIsRegistered]
-description =
-[PContent::NSSU2FTokenRegister]
-description =
-[PContent::NSSU2FTokenSign]
-description =
[PContent::IsSecureURI]
description =
[PContent::PURLClassifier]
description =
[PContent::ClassifyLocal]
description =
[PContent::GetGfxVars]
description =
--- a/security/manager/ssl/moz.build
+++ b/security/manager/ssl/moz.build
@@ -20,32 +20,30 @@ XPIDL_SOURCES += [
'nsICryptoHash.idl',
'nsICryptoHMAC.idl',
'nsIDataSignatureVerifier.idl',
'nsIGenKeypairInfoDlg.idl',
'nsIKeygenThread.idl',
'nsIKeyModule.idl',
'nsILocalCertService.idl',
'nsINSSErrorsService.idl',
- 'nsINSSU2FToken.idl',
'nsINSSVersion.idl',
'nsIPK11Token.idl',
'nsIPK11TokenDB.idl',
'nsIPKCS11Module.idl',
'nsIPKCS11ModuleDB.idl',
'nsIPKCS11Slot.idl',
'nsIProtectedAuthThread.idl',
'nsISecretDecoderRing.idl',
'nsISecurityUITelemetry.idl',
'nsISiteSecurityService.idl',
'nsISSLStatus.idl',
'nsISSLStatusProvider.idl',
'nsITokenDialogs.idl',
'nsITokenPasswordDialogs.idl',
- 'nsIU2FToken.idl',
'nsIX509Cert.idl',
'nsIX509CertDB.idl',
'nsIX509CertList.idl',
'nsIX509CertValidity.idl',
]
if CONFIG['MOZ_XUL']:
XPIDL_SOURCES += [
@@ -64,17 +62,16 @@ TESTING_JS_MODULES.psm += [
EXPORTS += [
'CryptoTask.h',
'nsClientAuthRemember.h',
'nsNSSCallbacks.h',
'nsNSSCertificate.h',
'nsNSSComponent.h',
'nsNSSHelper.h',
'nsNSSShutDown.h',
- 'nsNSSU2FToken.h',
'nsRandomGenerator.h',
'nsSecurityHeaderParser.h',
'NSSErrorsService.h',
'ScopedNSSTypes.h',
'SharedCertVerifier.h',
]
EXPORTS.mozilla += [
@@ -113,17 +110,16 @@ UNIFIED_SOURCES += [
'nsNSSCertificateDB.cpp',
'nsNSSCertTrust.cpp',
'nsNSSCertValidity.cpp',
'nsNSSComponent.cpp',
'nsNSSErrors.cpp',
'nsNSSIOLayer.cpp',
'nsNSSModule.cpp',
'nsNSSShutDown.cpp',
- 'nsNSSU2FToken.cpp',
'nsNSSVersion.cpp',
'nsNTLMAuthModule.cpp',
'nsPK11TokenDB.cpp',
'nsPKCS11Slot.cpp',
'nsPKCS12Blob.cpp',
'nsProtectedAuthThread.cpp',
'nsRandomGenerator.cpp',
'nsSecureBrowserUIImpl.cpp',
deleted file mode 100644
--- a/security/manager/ssl/nsINSSU2FToken.idl
+++ /dev/null
@@ -1,16 +0,0 @@
-/* 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 "nsIU2FToken.idl"
-
-/**
- * Interface used to interact with the NSS-backed software U2F Token
- */
-[scriptable, uuid(d9104a00-140b-4f86-a4b0-4998878ef4e6 )]
-interface nsINSSU2FToken : nsIU2FToken {
-};
-
-%{C++
-#define NS_NSSU2FTOKEN_CONTRACTID "@mozilla.org/dom/u2f/nss-u2f-token;1"
-%}
deleted file mode 100644
--- a/security/manager/ssl/nsIU2FToken.idl
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 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 "nsISupports.idl"
-
-interface nsIArray;
-
-/**
- * Interface used to interact with U2F Token devices
- */
-[scriptable, uuid(5778242f-1f42-47a2-b514-fa1adde2d904)]
-interface nsIU2FToken : nsISupports {
- /**
- * Is this token compatible with the provided version?
- *
- * @param version The offered version to test
- * @return True if the offered version is compatible
- */
- [must_use]
- void isCompatibleVersion(in AString version, [retval] out boolean result);
-
- /**
- * Return whether the provided KeyHandle belongs to this Token
- *
- * @param keyHandle Key Handle to evaluate.
- * @param application The FIDO Application data to associate with the key.
- * @return True if the Key Handle is ours.
- */
- [must_use]
- void isRegistered([array, size_is(keyHandleLen)] in octet keyHandle,
- in uint32_t keyHandleLen,
- [array, size_is(applicationLen)] in octet application,
- in uint32_t applicationLen,
- [retval] out boolean result);
-
- /**
- * Generates a public/private keypair for the provided application
- * and challenge, returning the pubkey, challenge response, and
- * key handle in the registration data.
- *
- * @param application The FIDO Application data to associate with the key.
- * @param challenge The Challenge to satisfy in the response.
- * @param registration An array containing the pubkey, challenge response,
- * and key handle.
- */
- [must_use]
- void register([array, size_is(applicationLen)] in octet application,
- in uint32_t applicationLen,
- [array, size_is(challengeLen)] in octet challenge,
- in uint32_t challengeLen,
- [array, size_is(registrationLen)] out octet registration,
- out uint32_t registrationLen);
-
- /**
- * Creates a signature over the "param" arguments using the private key
- * provided in the key handle argument.
- *
- * @param application The FIDO Application data to associate with the key.
- * @param challenge The Challenge to satisfy in the response.
- * @param keyHandle The Key Handle opaque object to use.
- * @param signature The resulting signature.
- */
- [must_use]
- void sign([array, size_is(applicationLen)] in octet application,
- in uint32_t applicationLen,
- [array, size_is(challengeLen)] in octet challenge,
- in uint32_t challengeLen,
- [array, size_is(keyHandleLen)] in octet keyHandle,
- in uint32_t keyHandleLen,
- [array, size_is(signatureLen)] out octet signature,
- out uint32_t signatureLen);
-};
--- a/security/manager/ssl/nsNSSModule.cpp
+++ b/security/manager/ssl/nsNSSModule.cpp
@@ -17,17 +17,16 @@
#include "nsCryptoHash.h"
#include "nsDataSignatureVerifier.h"
#include "nsICategoryManager.h"
#include "nsKeyModule.h"
#include "nsKeygenHandler.h"
#include "nsNSSCertificate.h"
#include "nsNSSCertificateDB.h"
#include "nsNSSComponent.h"
-#include "nsNSSU2FToken.h"
#include "nsNSSVersion.h"
#include "nsNTLMAuthModule.h"
#include "nsNetCID.h"
#include "nsPK11TokenDB.h"
#include "nsPKCS11Slot.h"
#include "nsRandomGenerator.h"
#include "nsSSLSocketProvider.h"
#include "nsSSLStatus.h"
@@ -150,17 +149,16 @@ NS_DEFINE_NAMED_CID(NS_CRYPTO_HASH_CID);
NS_DEFINE_NAMED_CID(NS_CRYPTO_HMAC_CID);
NS_DEFINE_NAMED_CID(NS_NTLMAUTHMODULE_CID);
NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECT_CID);
NS_DEFINE_NAMED_CID(NS_KEYMODULEOBJECTFACTORY_CID);
NS_DEFINE_NAMED_CID(NS_DATASIGNATUREVERIFIER_CID);
NS_DEFINE_NAMED_CID(NS_CONTENTSIGNATUREVERIFIER_CID);
NS_DEFINE_NAMED_CID(NS_CERTOVERRIDE_CID);
NS_DEFINE_NAMED_CID(NS_RANDOMGENERATOR_CID);
-NS_DEFINE_NAMED_CID(NS_NSSU2FTOKEN_CID);
NS_DEFINE_NAMED_CID(NS_SSLSTATUS_CID);
NS_DEFINE_NAMED_CID(TRANSPORTSECURITYINFO_CID);
NS_DEFINE_NAMED_CID(NS_NSSERRORSSERVICE_CID);
NS_DEFINE_NAMED_CID(NS_NSSVERSION_CID);
NS_DEFINE_NAMED_CID(NS_SECURE_BROWSER_UI_CID);
NS_DEFINE_NAMED_CID(NS_SITE_SECURITY_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_CERT_BLOCKLIST_CID);
@@ -199,18 +197,16 @@ static const mozilla::Module::CIDEntry k
{ &kNS_CONTENTSIGNATUREVERIFIER_CID, false, nullptr,
Constructor<ContentSignatureVerifier> },
{ &kNS_CERTOVERRIDE_CID, false, nullptr,
Constructor<nsCertOverrideService, &nsCertOverrideService::Init,
ProcessRestriction::ParentProcessOnly,
ThreadRestriction::MainThreadOnly> },
{ &kNS_RANDOMGENERATOR_CID, false, nullptr,
Constructor<nsRandomGenerator, nullptr, ProcessRestriction::AnyProcess> },
- { &kNS_NSSU2FTOKEN_CID, false, nullptr,
- Constructor<nsNSSU2FToken, &nsNSSU2FToken::Init> },
{ &kNS_SSLSTATUS_CID, false, nullptr,
Constructor<nsSSLStatus, nullptr, ProcessRestriction::AnyProcess> },
{ &kTRANSPORTSECURITYINFO_CID, false, nullptr,
Constructor<TransportSecurityInfo, nullptr,
ProcessRestriction::AnyProcess> },
{ &kNS_NSSERRORSSERVICE_CID, false, nullptr, NSSErrorsServiceConstructor },
{ &kNS_NSSVERSION_CID, false, nullptr, nsNSSVersionConstructor },
{ &kNS_SECURE_BROWSER_UI_CID, false, nullptr, nsSecureBrowserUIImplConstructor },
@@ -246,17 +242,16 @@ static const mozilla::Module::ContractID
{ "@mozilla.org/uriloader/psm-external-content-listener;1", &kNS_PSMCONTENTLISTEN_CID },
{ NS_NTLMAUTHMODULE_CONTRACTID, &kNS_NTLMAUTHMODULE_CID },
{ NS_KEYMODULEOBJECT_CONTRACTID, &kNS_KEYMODULEOBJECT_CID },
{ NS_KEYMODULEOBJECTFACTORY_CONTRACTID, &kNS_KEYMODULEOBJECTFACTORY_CID },
{ NS_DATASIGNATUREVERIFIER_CONTRACTID, &kNS_DATASIGNATUREVERIFIER_CID },
{ NS_CONTENTSIGNATUREVERIFIER_CONTRACTID, &kNS_CONTENTSIGNATUREVERIFIER_CID },
{ NS_CERTOVERRIDE_CONTRACTID, &kNS_CERTOVERRIDE_CID },
{ NS_RANDOMGENERATOR_CONTRACTID, &kNS_RANDOMGENERATOR_CID },
- { NS_NSSU2FTOKEN_CONTRACTID, &kNS_NSSU2FTOKEN_CID },
{ NS_SECURE_BROWSER_UI_CONTRACTID, &kNS_SECURE_BROWSER_UI_CID },
{ NS_SSSERVICE_CONTRACTID, &kNS_SITE_SECURITY_SERVICE_CID },
{ NS_CERTBLOCKLIST_CONTRACTID, &kNS_CERT_BLOCKLIST_CID },
{ nullptr }
};
static const mozilla::Module::CategoryEntry kNSSCategories[] = {
{ NS_CONTENT_LISTENER_CATEGORYMANAGER_ENTRY, "application/x-x509-ca-cert", "@mozilla.org/uriloader/psm-external-content-listener;1" },
deleted file mode 100644
--- a/security/manager/ssl/nsNSSU2FToken.cpp
+++ /dev/null
@@ -1,876 +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 "nsNSSU2FToken.h"
-
-#include "CryptoBuffer.h"
-#include "mozilla/Base64.h"
-#include "mozilla/Casting.h"
-#include "nsNSSComponent.h"
-#include "pk11pub.h"
-#include "prerror.h"
-#include "secerr.h"
-#include "WebCryptoCommon.h"
-
-using namespace mozilla;
-using mozilla::dom::CreateECParamsForCurve;
-
-NS_IMPL_ISUPPORTS(nsNSSU2FToken, nsIU2FToken, nsINSSU2FToken)
-
-// Not named "security.webauth.u2f_softtoken_counter" because setting that
-// name causes the window.u2f object to disappear until preferences get
-// reloaded, as its' pref is a substring!
-#define PREF_U2F_NSSTOKEN_COUNTER "security.webauth.softtoken_counter"
-
-const nsCString nsNSSU2FToken::mSecretNickname =
- NS_LITERAL_CSTRING("U2F_NSSTOKEN");
-const nsString nsNSSU2FToken::mVersion =
- NS_LITERAL_STRING("U2F_V2");
-const char* kAttestCertSubjectName = "CN=Firefox U2F Soft Token";
-
-// This U2F-compatible soft token uses FIDO U2F-compatible ECDSA keypairs
-// on the SEC_OID_SECG_EC_SECP256R1 curve. When asked to Register, it will
-// generate and return a new keypair KP, where the private component is wrapped
-// using AES-KW with the 128-bit mWrappingKey to make an opaque "key handle".
-// In other words, Register yields { KP_pub, AES-KW(KP_priv, key=mWrappingKey) }
-//
-// The value mWrappingKey is long-lived; it is persisted as part of the NSS DB
-// for the current profile. The attestation certificates that are produced are
-// ephemeral to counteract profiling. They have little use for a soft-token
-// at any rate, but are required by the specification.
-
-const uint32_t kParamLen = 32;
-const uint32_t kPublicKeyLen = 65;
-const uint32_t kWrappedKeyBufLen = 256;
-const uint32_t kWrappingKeyByteLen = 128/8;
-const uint32_t kSaltByteLen = 64/8;
-const uint32_t kVersion1KeyHandleLen = 162;
-NS_NAMED_LITERAL_STRING(kEcAlgorithm, WEBCRYPTO_NAMED_CURVE_P256);
-
-const PRTime kOneDay = PRTime(PR_USEC_PER_SEC)
- * PRTime(60) // sec
- * PRTime(60) // min
- * PRTime(24); // hours
-const PRTime kExpirationSlack = kOneDay; // Pre-date for clock skew
-const PRTime kExpirationLife = kOneDay;
-
-enum SoftTokenHandle {
- Version1 = 0,
-};
-
-static mozilla::LazyLogModule gNSSTokenLog("webauth_u2f");
-
-nsNSSU2FToken::nsNSSU2FToken()
- : mInitialized(false)
-{}
-
-nsNSSU2FToken::~nsNSSU2FToken()
-{
- nsNSSShutDownPreventionLock locker;
-
- if (isAlreadyShutDown()) {
- return;
- }
-
- destructorSafeDestroyNSSReference();
- shutdown(ShutdownCalledFrom::Object);
-}
-
-void
-nsNSSU2FToken::virtualDestroyNSSReference()
-{
- destructorSafeDestroyNSSReference();
-}
-
-void
-nsNSSU2FToken::destructorSafeDestroyNSSReference()
-{
- mWrappingKey = nullptr;
-}
-
-/**
- * Gets the first key with the given nickname from the given slot. Any other
- * keys found are not returned.
- * PK11_GetNextSymKey() should not be called on the returned key.
- *
- * @param aSlot Slot to search.
- * @param aNickname Nickname the key should have.
- * @return The first key found. nullptr if no key could be found.
- */
-static UniquePK11SymKey
-GetSymKeyByNickname(const UniquePK11SlotInfo& aSlot,
- const nsCString& aNickname,
- const nsNSSShutDownPreventionLock&)
-{
- MOZ_ASSERT(aSlot);
- if (!aSlot) {
- return nullptr;
- }
-
- MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
- ("Searching for a symmetric key named %s", aNickname.get()));
-
- UniquePK11SymKey keyListHead(
- PK11_ListFixedKeysInSlot(aSlot.get(), const_cast<char*>(aNickname.get()),
- /* wincx */ nullptr));
- if (!keyListHead) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("Symmetric key not found."));
- return nullptr;
- }
-
- // Sanity check PK11_ListFixedKeysInSlot() only returns keys with the correct
- // nickname.
- MOZ_ASSERT(aNickname ==
- UniquePORTString(PK11_GetSymKeyNickname(keyListHead.get())).get());
- MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("Symmetric key found!"));
-
- // Free any remaining keys in the key list.
- UniquePK11SymKey freeKey(PK11_GetNextSymKey(keyListHead.get()));
- while (freeKey) {
- freeKey = UniquePK11SymKey(PK11_GetNextSymKey(freeKey.get()));
- }
-
- return keyListHead;
-}
-
-static nsresult
-GenEcKeypair(const UniquePK11SlotInfo& aSlot,
- /*out*/ UniqueSECKEYPrivateKey& aPrivKey,
- /*out*/ UniqueSECKEYPublicKey& aPubKey,
- const nsNSSShutDownPreventionLock&)
-{
- MOZ_ASSERT(aSlot);
- if (!aSlot) {
- return NS_ERROR_INVALID_ARG;
- }
-
- UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
- if (!arena) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- // Set the curve parameters; keyParams belongs to the arena memory space
- SECItem* keyParams = CreateECParamsForCurve(kEcAlgorithm, arena.get());
- if (!keyParams) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- // Generate a key pair
- CK_MECHANISM_TYPE mechanism = CKM_EC_KEY_PAIR_GEN;
-
- SECKEYPublicKey* pubKeyRaw;
- aPrivKey = UniqueSECKEYPrivateKey(
- PK11_GenerateKeyPair(aSlot.get(), mechanism, keyParams, &pubKeyRaw,
- /* ephemeral */ false, false,
- /* wincx */ nullptr));
- aPubKey = UniqueSECKEYPublicKey(pubKeyRaw);
- pubKeyRaw = nullptr;
- if (!aPrivKey.get() || !aPubKey.get()) {
- return NS_ERROR_FAILURE;
- }
-
- // Check that the public key has the correct length
- if (aPubKey->u.ec.publicValue.len != kPublicKeyLen) {
- return NS_ERROR_FAILURE;
- }
-
- return NS_OK;
-}
-
-nsresult
-nsNSSU2FToken::GetOrCreateWrappingKey(const UniquePK11SlotInfo& aSlot,
- const nsNSSShutDownPreventionLock& locker)
-{
- MOZ_ASSERT(aSlot);
- if (!aSlot) {
- return NS_ERROR_INVALID_ARG;
- }
-
- // Search for an existing wrapping key. If we find it,
- // store it for later and mark ourselves initialized.
- mWrappingKey = GetSymKeyByNickname(aSlot, mSecretNickname, locker);
- if (mWrappingKey) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("U2F Soft Token Key found."));
- mInitialized = true;
- return NS_OK;
- }
-
- MOZ_LOG(gNSSTokenLog, LogLevel::Info,
- ("No keys found. Generating new U2F Soft Token wrapping key."));
-
- // We did not find an existing wrapping key, so we generate one in the
- // persistent database (e.g, Token).
- mWrappingKey = UniquePK11SymKey(
- PK11_TokenKeyGenWithFlags(aSlot.get(), CKM_AES_KEY_GEN,
- /* default params */ nullptr,
- kWrappingKeyByteLen,
- /* empty keyid */ nullptr,
- /* flags */ CKF_WRAP | CKF_UNWRAP,
- /* attributes */ PK11_ATTR_TOKEN |
- PK11_ATTR_PRIVATE,
- /* wincx */ nullptr));
-
- if (!mWrappingKey) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to store wrapping key, NSS error #%d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
-
- SECStatus srv = PK11_SetSymKeyNickname(mWrappingKey.get(),
- mSecretNickname.get());
- if (srv != SECSuccess) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to set nickname, NSS error #%d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
-
- MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
- ("Key stored, nickname set to %s.", mSecretNickname.get()));
-
- Preferences::SetUint(PREF_U2F_NSSTOKEN_COUNTER, 0);
- return NS_OK;
-}
-
-static nsresult
-GetAttestationCertificate(const UniquePK11SlotInfo& aSlot,
- /*out*/ UniqueSECKEYPrivateKey& aAttestPrivKey,
- /*out*/ UniqueCERTCertificate& aAttestCert,
- const nsNSSShutDownPreventionLock& locker)
-{
- MOZ_ASSERT(aSlot);
- if (!aSlot) {
- return NS_ERROR_INVALID_ARG;
- }
-
- UniqueSECKEYPublicKey pubKey;
-
- // Construct an ephemeral keypair for this Attestation Certificate
- nsresult rv = GenEcKeypair(aSlot, aAttestPrivKey, pubKey, locker);
- if (NS_FAILED(rv) || !aAttestPrivKey || !pubKey) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to gen keypair, NSS error #%d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
-
- // Construct the Attestation Certificate itself
- UniqueCERTName subjectName(CERT_AsciiToName(kAttestCertSubjectName));
- if (!subjectName) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to set subject name, NSS error #%d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
-
- UniqueCERTSubjectPublicKeyInfo spki(
- SECKEY_CreateSubjectPublicKeyInfo(pubKey.get()));
- if (!spki) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to set SPKI, NSS error #%d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
-
- UniqueCERTCertificateRequest certreq(
- CERT_CreateCertificateRequest(subjectName.get(), spki.get(), nullptr));
- if (!certreq) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to gen CSR, NSS error #%d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
-
- PRTime now = PR_Now();
- PRTime notBefore = now - kExpirationSlack;
- PRTime notAfter = now + kExpirationLife;
-
- UniqueCERTValidity validity(CERT_CreateValidity(notBefore, notAfter));
- if (!validity) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to gen validity, NSS error #%d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
-
- unsigned long serial;
- unsigned char* serialBytes =
- mozilla::BitwiseCast<unsigned char*, unsigned long*>(&serial);
- SECStatus srv = PK11_GenerateRandomOnSlot(aSlot.get(), serialBytes,
- sizeof(serial));
- if (srv != SECSuccess) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to gen serial, NSS error #%d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
- // Ensure that the most significant bit isn't set (which would
- // indicate a negative number, which isn't valid for serial
- // numbers).
- serialBytes[0] &= 0x7f;
- // Also ensure that the least significant bit on the most
- // significant byte is set (to prevent a leading zero byte,
- // which also wouldn't be valid).
- serialBytes[0] |= 0x01;
-
- aAttestCert = UniqueCERTCertificate(
- CERT_CreateCertificate(serial, subjectName.get(), validity.get(),
- certreq.get()));
- if (!aAttestCert) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to gen certificate, NSS error #%d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
-
- PLArenaPool* arena = aAttestCert->arena;
-
- srv = SECOID_SetAlgorithmID(arena, &aAttestCert->signature,
- SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE,
- /* wincx */ nullptr);
- if (srv != SECSuccess) {
- return NS_ERROR_FAILURE;
- }
-
- // Set version to X509v3.
- *(aAttestCert->version.data) = SEC_CERTIFICATE_VERSION_3;
- aAttestCert->version.len = 1;
-
- SECItem innerDER = { siBuffer, nullptr, 0 };
- if (!SEC_ASN1EncodeItem(arena, &innerDER, aAttestCert.get(),
- SEC_ASN1_GET(CERT_CertificateTemplate))) {
- return NS_ERROR_FAILURE;
- }
-
- SECItem* signedCert = PORT_ArenaZNew(arena, SECItem);
- if (!signedCert) {
- return NS_ERROR_FAILURE;
- }
-
- srv = SEC_DerSignData(arena, signedCert, innerDER.data, innerDER.len,
- aAttestPrivKey.get(),
- SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
- if (srv != SECSuccess) {
- return NS_ERROR_FAILURE;
- }
- aAttestCert->derCert = *signedCert;
-
- MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
- ("U2F Soft Token attestation certificate generated."));
- return NS_OK;
-}
-
-// Set up the context for the soft U2F Token. This is called by NSS
-// initialization.
-nsresult
-nsNSSU2FToken::Init()
-{
- MOZ_ASSERT(NS_IsMainThread());
- MOZ_ASSERT(!mInitialized);
- if (mInitialized) {
- return NS_ERROR_FAILURE;
- }
-
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
- MOZ_ASSERT(slot.get());
-
- // Search for an existing wrapping key, or create one.
- nsresult rv = GetOrCreateWrappingKey(slot, locker);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return rv;
- }
-
- mInitialized = true;
- MOZ_LOG(gNSSTokenLog, LogLevel::Debug, ("U2F Soft Token initialized."));
- return NS_OK;
-}
-
-// Convert a Private Key object into an opaque key handle, using AES Key Wrap
-// with the long-lived aPersistentKey mixed with aAppParam to convert aPrivKey.
-// The key handle's format is version || saltLen || salt || wrappedPrivateKey
-static UniqueSECItem
-KeyHandleFromPrivateKey(const UniquePK11SlotInfo& aSlot,
- const UniquePK11SymKey& aPersistentKey,
- uint8_t* aAppParam, uint32_t aAppParamLen,
- const UniqueSECKEYPrivateKey& aPrivKey,
- const nsNSSShutDownPreventionLock&)
-{
- MOZ_ASSERT(aSlot);
- MOZ_ASSERT(aPersistentKey);
- MOZ_ASSERT(aAppParam);
- MOZ_ASSERT(aPrivKey);
- if (!aSlot || !aPersistentKey || !aPrivKey || !aAppParam) {
- return nullptr;
- }
-
- // Generate a random salt
- uint8_t saltParam[kSaltByteLen];
- SECStatus srv = PK11_GenerateRandomOnSlot(aSlot.get(), saltParam,
- sizeof(saltParam));
- if (srv != SECSuccess) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to generate a salt, NSS error #%d", PORT_GetError()));
- return nullptr;
- }
-
- // Prepare the HKDF (https://tools.ietf.org/html/rfc5869)
- CK_NSS_HKDFParams hkdfParams = { true, saltParam, sizeof(saltParam),
- true, aAppParam, aAppParamLen };
- SECItem kdfParams = { siBuffer, (unsigned char*)&hkdfParams,
- sizeof(hkdfParams) };
-
- // Derive a wrapping key from aPersistentKey, the salt, and the aAppParam.
- // CKM_AES_KEY_GEN and CKA_WRAP are key type and usage attributes of the
- // derived symmetric key and don't matter because we ignore them anyway.
- UniquePK11SymKey wrapKey(PK11_Derive(aPersistentKey.get(), CKM_NSS_HKDF_SHA256,
- &kdfParams, CKM_AES_KEY_GEN, CKA_WRAP,
- kWrappingKeyByteLen));
- if (!wrapKey.get()) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to derive a wrapping key, NSS error #%d", PORT_GetError()));
- return nullptr;
- }
-
- UniqueSECItem wrappedKey(SECITEM_AllocItem(/* default arena */ nullptr,
- /* no buffer */ nullptr,
- kWrappedKeyBufLen));
- if (!wrappedKey) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Failed to allocate memory"));
- return nullptr;
- }
-
- UniqueSECItem param(PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP_PAD,
- /* default IV */ nullptr ));
-
- srv = PK11_WrapPrivKey(aSlot.get(), wrapKey.get(), aPrivKey.get(),
- CKM_NSS_AES_KEY_WRAP_PAD, param.get(), wrappedKey.get(),
- /* wincx */ nullptr);
- if (srv != SECSuccess) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to wrap U2F key, NSS error #%d", PORT_GetError()));
- return nullptr;
- }
-
- // Concatenate the salt and the wrapped Private Key together
- mozilla::dom::CryptoBuffer keyHandleBuf;
- if (!keyHandleBuf.SetCapacity(wrappedKey.get()->len + sizeof(saltParam) + 2,
- mozilla::fallible)) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Failed to allocate memory"));
- return nullptr;
- }
-
- // It's OK to ignore the return values here because we're writing into
- // pre-allocated space
- keyHandleBuf.AppendElement(SoftTokenHandle::Version1, mozilla::fallible);
- keyHandleBuf.AppendElement(sizeof(saltParam), mozilla::fallible);
- keyHandleBuf.AppendElements(saltParam, sizeof(saltParam), mozilla::fallible);
- keyHandleBuf.AppendSECItem(wrappedKey.get());
-
- UniqueSECItem keyHandle(SECITEM_AllocItem(nullptr, nullptr, 0));
- if (!keyHandle) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Failed to allocate memory"));
- return nullptr;
- }
-
- if (!keyHandleBuf.ToSECItem(/* default arena */ nullptr, keyHandle.get())) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Failed to allocate memory"));
- return nullptr;
- }
- return keyHandle;
-}
-
-// Convert an opaque key handle aKeyHandle back into a Private Key object, using
-// the long-lived aPersistentKey mixed with aAppParam and the AES Key Wrap
-// algorithm.
-static UniqueSECKEYPrivateKey
-PrivateKeyFromKeyHandle(const UniquePK11SlotInfo& aSlot,
- const UniquePK11SymKey& aPersistentKey,
- uint8_t* aKeyHandle, uint32_t aKeyHandleLen,
- uint8_t* aAppParam, uint32_t aAppParamLen,
- const nsNSSShutDownPreventionLock&)
-{
- MOZ_ASSERT(aSlot);
- MOZ_ASSERT(aPersistentKey);
- MOZ_ASSERT(aKeyHandle);
- MOZ_ASSERT(aAppParam);
- MOZ_ASSERT(aAppParamLen == SHA256_LENGTH);
- if (!aSlot || !aPersistentKey || !aKeyHandle || !aAppParam ||
- aAppParamLen != SHA256_LENGTH) {
- return nullptr;
- }
-
- // As we only support one key format ourselves (right now), fail early if
- // we aren't that length
- if (aKeyHandleLen != kVersion1KeyHandleLen) {
- return nullptr;
- }
-
- if (aKeyHandle[0] != SoftTokenHandle::Version1) {
- // Unrecognized version
- return nullptr;
- }
-
- uint8_t saltLen = aKeyHandle[1];
- uint8_t* saltPtr = aKeyHandle + 2;
- if (saltLen != kSaltByteLen) {
- return nullptr;
- }
-
- // Prepare the HKDF (https://tools.ietf.org/html/rfc5869)
- CK_NSS_HKDFParams hkdfParams = { true, saltPtr, saltLen,
- true, aAppParam, aAppParamLen };
- SECItem kdfParams = { siBuffer, (unsigned char*)&hkdfParams,
- sizeof(hkdfParams) };
-
- // Derive a wrapping key from aPersistentKey, the salt, and the aAppParam.
- // CKM_AES_KEY_GEN and CKA_WRAP are key type and usage attributes of the
- // derived symmetric key and don't matter because we ignore them anyway.
- UniquePK11SymKey wrapKey(PK11_Derive(aPersistentKey.get(), CKM_NSS_HKDF_SHA256,
- &kdfParams, CKM_AES_KEY_GEN, CKA_WRAP,
- kWrappingKeyByteLen));
- if (!wrapKey.get()) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Failed to derive a wrapping key, NSS error #%d", PORT_GetError()));
- return nullptr;
- }
-
- uint8_t wrappedLen = aKeyHandleLen - saltLen - 2;
- uint8_t* wrappedPtr = aKeyHandle + saltLen + 2;
-
- ScopedAutoSECItem wrappedKeyItem(wrappedLen);
- memcpy(wrappedKeyItem.data, wrappedPtr, wrappedKeyItem.len);
-
- ScopedAutoSECItem pubKey(kPublicKeyLen);
-
- UniqueSECItem param(PK11_ParamFromIV(CKM_NSS_AES_KEY_WRAP_PAD,
- /* default IV */ nullptr ));
-
- CK_ATTRIBUTE_TYPE usages[] = { CKA_SIGN };
- int usageCount = 1;
-
- UniqueSECKEYPrivateKey unwrappedKey(
- PK11_UnwrapPrivKey(aSlot.get(), wrapKey.get(), CKM_NSS_AES_KEY_WRAP_PAD,
- param.get(), &wrappedKeyItem,
- /* no nickname */ nullptr,
- /* discard pubkey */ &pubKey,
- /* not permanent */ false,
- /* non-exportable */ true,
- CKK_EC, usages, usageCount,
- /* wincx */ nullptr));
- if (!unwrappedKey) {
- // Not our key.
- MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
- ("Could not unwrap key handle, NSS Error #%d", PORT_GetError()));
- return nullptr;
- }
-
- return unwrappedKey;
-}
-
-// Return whether the provided version is supported by this token.
-NS_IMETHODIMP
-nsNSSU2FToken::IsCompatibleVersion(const nsAString& aVersion, bool* aResult)
-{
- NS_ENSURE_ARG_POINTER(aResult);
- MOZ_ASSERT(mInitialized);
- *aResult = (mVersion == aVersion);
- return NS_OK;
-}
-
-// IsRegistered determines if the provided key handle is usable by this token.
-NS_IMETHODIMP
-nsNSSU2FToken::IsRegistered(uint8_t* aKeyHandle, uint32_t aKeyHandleLen,
- uint8_t* aAppParam, uint32_t aAppParamLen,
- bool* aResult)
-{
- NS_ENSURE_ARG_POINTER(aKeyHandle);
- NS_ENSURE_ARG_POINTER(aAppParam);
- NS_ENSURE_ARG_POINTER(aResult);
-
- if (!NS_IsMainThread()) {
- NS_ERROR("nsNSSU2FToken::IsRegistered called off the main thread");
- return NS_ERROR_NOT_SAME_THREAD;
- }
-
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_FAILURE;
- }
-
- MOZ_ASSERT(mInitialized);
- if (!mInitialized) {
- return NS_ERROR_FAILURE;
- }
-
- UniquePK11SlotInfo slot(PK11_GetInternalSlot());
- MOZ_ASSERT(slot.get());
-
- // Decode the key handle
- UniqueSECKEYPrivateKey privKey = PrivateKeyFromKeyHandle(slot, mWrappingKey,
- aKeyHandle,
- aKeyHandleLen,
- aAppParam,
- aAppParamLen,
- locker);
- *aResult = (privKey.get() != nullptr);
- return NS_OK;
-}
-
-// A U2F Register operation causes a new key pair to be generated by the token.
-// The token then returns the public key of the key pair, and a handle to the
-// private key, which is a fancy way of saying "key wrapped private key", as
-// well as the generated attestation certificate and a signature using that
-// certificate's private key.
-//
-// The KeyHandleFromPrivateKey and PrivateKeyFromKeyHandle methods perform
-// the actual key wrap/unwrap operations.
-//
-// The format of the return registration data is as follows:
-//
-// Bytes Value
-// 1 0x05
-// 65 public key
-// 1 key handle length
-// * key handle
-// ASN.1 attestation certificate
-// * attestation signature
-//
-NS_IMETHODIMP
-nsNSSU2FToken::Register(uint8_t* aApplication,
- uint32_t aApplicationLen,
- uint8_t* aChallenge,
- uint32_t aChallengeLen,
- uint8_t** aRegistration,
- uint32_t* aRegistrationLen)
-{
- NS_ENSURE_ARG_POINTER(aApplication);
- NS_ENSURE_ARG_POINTER(aChallenge);
- NS_ENSURE_ARG_POINTER(aRegistration);
- NS_ENSURE_ARG_POINTER(aRegistrationLen);
-
- if (!NS_IsMainThread()) {
- NS_ERROR("nsNSSU2FToken::Register called off the main thread");
- return NS_ERROR_NOT_SAME_THREAD;
- }
-
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- MOZ_ASSERT(mInitialized);
- if (!mInitialized) {
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- // We should already have a wrapping key
- MOZ_ASSERT(mWrappingKey);
-
- UniquePK11SlotInfo slot(PK11_GetInternalSlot());
- MOZ_ASSERT(slot.get());
-
- // Construct a one-time-use Attestation Certificate
- UniqueSECKEYPrivateKey attestPrivKey;
- UniqueCERTCertificate attestCert;
- nsresult rv = GetAttestationCertificate(slot, attestPrivKey, attestCert,
- locker);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return NS_ERROR_FAILURE;
- }
- MOZ_ASSERT(attestCert);
- MOZ_ASSERT(attestPrivKey);
-
- // Generate a new keypair; the private will be wrapped into a Key Handle
- UniqueSECKEYPrivateKey privKey;
- UniqueSECKEYPublicKey pubKey;
- rv = GenEcKeypair(slot, privKey, pubKey, locker);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return NS_ERROR_FAILURE;
- }
-
- // The key handle will be the result of keywrap(privKey, key=mWrappingKey)
- UniqueSECItem keyHandleItem = KeyHandleFromPrivateKey(slot, mWrappingKey,
- aApplication,
- aApplicationLen,
- privKey, locker);
- if (!keyHandleItem.get()) {
- return NS_ERROR_FAILURE;
- }
-
- // Sign the challenge using the Attestation privkey (from attestCert)
- mozilla::dom::CryptoBuffer signedDataBuf;
- if (!signedDataBuf.SetCapacity(1 + aApplicationLen + aChallengeLen +
- keyHandleItem->len + kPublicKeyLen,
- mozilla::fallible)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- // It's OK to ignore the return values here because we're writing into
- // pre-allocated space
- signedDataBuf.AppendElement(0x00, mozilla::fallible);
- signedDataBuf.AppendElements(aApplication, aApplicationLen, mozilla::fallible);
- signedDataBuf.AppendElements(aChallenge, aChallengeLen, mozilla::fallible);
- signedDataBuf.AppendSECItem(keyHandleItem.get());
- signedDataBuf.AppendSECItem(pubKey->u.ec.publicValue);
-
- ScopedAutoSECItem signatureItem;
- SECStatus srv = SEC_SignData(&signatureItem, signedDataBuf.Elements(),
- signedDataBuf.Length(), attestPrivKey.get(),
- SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
- if (srv != SECSuccess) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Signature failure: %d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
-
- // Serialize the registration data
- mozilla::dom::CryptoBuffer registrationBuf;
- if (!registrationBuf.SetCapacity(1 + kPublicKeyLen + 1 + keyHandleItem->len +
- attestCert.get()->derCert.len +
- signatureItem.len, mozilla::fallible)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
- registrationBuf.AppendElement(0x05, mozilla::fallible);
- registrationBuf.AppendSECItem(pubKey->u.ec.publicValue);
- registrationBuf.AppendElement(keyHandleItem->len, mozilla::fallible);
- registrationBuf.AppendSECItem(keyHandleItem.get());
- registrationBuf.AppendSECItem(attestCert.get()->derCert);
- registrationBuf.AppendSECItem(signatureItem);
- if (!registrationBuf.ToNewUnsignedBuffer(aRegistration, aRegistrationLen)) {
- return NS_ERROR_FAILURE;
- }
-
- return NS_OK;
-}
-
-// A U2F Sign operation creates a signature over the "param" arguments (plus
-// some other stuff) using the private key indicated in the key handle argument.
-//
-// The format of the signed data is as follows:
-//
-// 32 Application parameter
-// 1 User presence (0x01)
-// 4 Counter
-// 32 Challenge parameter
-//
-// The format of the signature data is as follows:
-//
-// 1 User presence
-// 4 Counter
-// * Signature
-//
-NS_IMETHODIMP
-nsNSSU2FToken::Sign(uint8_t* aApplication, uint32_t aApplicationLen,
- uint8_t* aChallenge, uint32_t aChallengeLen,
- uint8_t* aKeyHandle, uint32_t aKeyHandleLen,
- uint8_t** aSignature, uint32_t* aSignatureLen)
-{
- NS_ENSURE_ARG_POINTER(aApplication);
- NS_ENSURE_ARG_POINTER(aChallenge);
- NS_ENSURE_ARG_POINTER(aKeyHandle);
- NS_ENSURE_ARG_POINTER(aKeyHandleLen);
- NS_ENSURE_ARG_POINTER(aSignature);
- NS_ENSURE_ARG_POINTER(aSignatureLen);
-
- if (!NS_IsMainThread()) {
- NS_ERROR("nsNSSU2FToken::Sign called off the main thread");
- return NS_ERROR_NOT_SAME_THREAD;
- }
-
- nsNSSShutDownPreventionLock locker;
- if (isAlreadyShutDown()) {
- return NS_ERROR_NOT_AVAILABLE;
- }
-
- MOZ_ASSERT(mInitialized);
- if (!mInitialized) {
- return NS_ERROR_NOT_INITIALIZED;
- }
-
- MOZ_ASSERT(mWrappingKey);
-
- UniquePK11SlotInfo slot(PK11_GetInternalSlot());
- MOZ_ASSERT(slot.get());
-
- if ((aChallengeLen != kParamLen) || (aApplicationLen != kParamLen)) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Parameter lengths are wrong! challenge=%d app=%d expected=%d",
- aChallengeLen, aApplicationLen, kParamLen));
-
- return NS_ERROR_ILLEGAL_VALUE;
- }
-
- // Decode the key handle
- UniqueSECKEYPrivateKey privKey = PrivateKeyFromKeyHandle(slot, mWrappingKey,
- aKeyHandle,
- aKeyHandleLen,
- aApplication,
- aApplicationLen,
- locker);
- if (!privKey.get()) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning, ("Couldn't get the priv key!"));
- return NS_ERROR_FAILURE;
- }
-
- // Increment the counter and turn it into a SECItem
- uint32_t counter = Preferences::GetUint(PREF_U2F_NSSTOKEN_COUNTER) + 1;
- Preferences::SetUint(PREF_U2F_NSSTOKEN_COUNTER, counter);
- ScopedAutoSECItem counterItem(4);
- counterItem.data[0] = (counter >> 24) & 0xFF;
- counterItem.data[1] = (counter >> 16) & 0xFF;
- counterItem.data[2] = (counter >> 8) & 0xFF;
- counterItem.data[3] = (counter >> 0) & 0xFF;
-
- // Compute the signature
- mozilla::dom::CryptoBuffer signedDataBuf;
- if (!signedDataBuf.SetCapacity(1 + 4 + (2 * kParamLen), mozilla::fallible)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- // It's OK to ignore the return values here because we're writing into
- // pre-allocated space
- signedDataBuf.AppendElements(aApplication, aApplicationLen, mozilla::fallible);
- signedDataBuf.AppendElement(0x01, mozilla::fallible);
- signedDataBuf.AppendSECItem(counterItem);
- signedDataBuf.AppendElements(aChallenge, aChallengeLen, mozilla::fallible);
-
- if (MOZ_LOG_TEST(gNSSTokenLog, LogLevel::Debug)) {
- nsAutoCString base64;
- nsresult rv = Base64URLEncode(signedDataBuf.Length(), signedDataBuf.Elements(),
- Base64URLEncodePaddingPolicy::Omit, base64);
- if (NS_WARN_IF(NS_FAILED(rv))) {
- return NS_ERROR_FAILURE;
- }
-
- MOZ_LOG(gNSSTokenLog, LogLevel::Debug,
- ("U2F Token signing bytes (base64): %s", base64.get()));
- }
-
- ScopedAutoSECItem signatureItem;
- SECStatus srv = SEC_SignData(&signatureItem, signedDataBuf.Elements(),
- signedDataBuf.Length(), privKey.get(),
- SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE);
- if (srv != SECSuccess) {
- MOZ_LOG(gNSSTokenLog, LogLevel::Warning,
- ("Signature failure: %d", PORT_GetError()));
- return NS_ERROR_FAILURE;
- }
-
- // Assemble the signature data into a buffer for return
- mozilla::dom::CryptoBuffer signatureBuf;
- if (!signatureBuf.SetCapacity(1 + counterItem.len + signatureItem.len,
- mozilla::fallible)) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- // It's OK to ignore the return values here because we're writing into
- // pre-allocated space
- signatureBuf.AppendElement(0x01, mozilla::fallible);
- signatureBuf.AppendSECItem(counterItem);
- signatureBuf.AppendSECItem(signatureItem);
-
- if (!signatureBuf.ToNewUnsignedBuffer(aSignature, aSignatureLen)) {
- return NS_ERROR_FAILURE;
- }
- return NS_OK;
-}
deleted file mode 100644
--- a/security/manager/ssl/nsNSSU2FToken.h
+++ /dev/null
@@ -1,48 +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 nsNSSU2FToken_h
-#define nsNSSU2FToken_h
-
-#include "nsINSSU2FToken.h"
-
-#include "nsNSSShutDown.h"
-#include "ScopedNSSTypes.h"
-
-#define NS_NSSU2FTOKEN_CID \
- {0x79f95a6c, 0xd0f7, 0x4d7d, {0xae, 0xaa, 0xcd, 0x0a, 0x04, 0xb6, 0x50, 0x89}}
-
-class nsNSSU2FToken : public nsINSSU2FToken,
- public nsNSSShutDownObject
-{
-public:
- NS_DECL_ISUPPORTS
- NS_DECL_NSIU2FTOKEN
- NS_DECL_NSINSSU2FTOKEN
-
- nsNSSU2FToken();
-
- // For nsNSSShutDownObject
- virtual void virtualDestroyNSSReference() override;
- void destructorSafeDestroyNSSReference();
-
- // Initializes the token and constructs and persists keys, if needed. Asserts
- // that it is only called by the main thread.
- nsresult Init();
-
-private:
- bool mInitialized;
- mozilla::UniquePK11SymKey mWrappingKey;
-
- static const nsCString mSecretNickname;
- static const nsString mVersion;
-
- ~nsNSSU2FToken();
- nsresult GetOrCreateWrappingKey(const mozilla::UniquePK11SlotInfo& aSlot,
- const nsNSSShutDownPreventionLock&);
-};
-
-#endif // nsNSSU2FToken_h