зеркало из https://github.com/mozilla/gecko-dev.git
173 строки
3.7 KiB
C++
173 строки
3.7 KiB
C++
/* -*- 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 "NSSToken.h"
|
|
|
|
#include "nsNSSComponent.h"
|
|
#include "pk11pub.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
|
|
const nsString NSSToken::mVersion = NS_LITERAL_STRING("U2F_V2");
|
|
|
|
const uint32_t kParamLen = 32;
|
|
const uint32_t kPublicKeyLen = 65;
|
|
const uint32_t kSignedDataLen = (2 * kParamLen) + 1 + 4;
|
|
|
|
NSSToken::NSSToken()
|
|
: mInitialized(false)
|
|
, mMutex("NSSToken::mMutex")
|
|
{}
|
|
|
|
NSSToken::~NSSToken()
|
|
{
|
|
nsNSSShutDownPreventionLock locker;
|
|
|
|
if (isAlreadyShutDown()) {
|
|
return;
|
|
}
|
|
|
|
destructorSafeDestroyNSSReference();
|
|
shutdown(calledFromObject);
|
|
}
|
|
|
|
void
|
|
NSSToken::virtualDestroyNSSReference()
|
|
{
|
|
destructorSafeDestroyNSSReference();
|
|
}
|
|
|
|
void
|
|
NSSToken::destructorSafeDestroyNSSReference()
|
|
{
|
|
mSlot = nullptr;
|
|
}
|
|
|
|
nsresult
|
|
NSSToken::Init()
|
|
{
|
|
MOZ_ASSERT(!mInitialized);
|
|
if (mInitialized) {
|
|
return NS_OK;
|
|
}
|
|
|
|
nsNSSShutDownPreventionLock locker;
|
|
if (isAlreadyShutDown()) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
if (!EnsureNSSInitializedChromeOrContent()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
mSlot = PK11_GetInternalSlot();
|
|
if (!mSlot.get()) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
mInitialized = true;
|
|
return NS_OK;
|
|
}
|
|
|
|
bool
|
|
NSSToken::IsCompatibleVersion(const nsString& aVersionParam) const
|
|
{
|
|
MOZ_ASSERT(mInitialized);
|
|
return mVersion == aVersionParam;
|
|
}
|
|
|
|
/*
|
|
* IsRegistered determines if the provided key handle is usable by this token.
|
|
*/
|
|
bool
|
|
NSSToken::IsRegistered(const CryptoBuffer& aKeyHandle) const
|
|
{
|
|
MOZ_ASSERT(mInitialized);
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* 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. The input parameters are used only for attestation, which this
|
|
* token does not provide. (We'll see how that works!)
|
|
*
|
|
* The format of the return registration data is as follows:
|
|
*
|
|
* Bytes Value
|
|
* 1 0x05
|
|
* 65 public key
|
|
* 1 key handle length
|
|
* * key handle
|
|
* * attestation certificate (omitted for now)
|
|
* * attestation signature (omitted for now)
|
|
*
|
|
*/
|
|
nsresult
|
|
NSSToken::Register(const CryptoBuffer& /* aChallengeParam */,
|
|
const CryptoBuffer& /* aApplicationParam */,
|
|
CryptoBuffer& aRegistrationData)
|
|
{
|
|
MOZ_ASSERT(mInitialized);
|
|
nsNSSShutDownPreventionLock locker;
|
|
if (isAlreadyShutDown()) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
if (!mInitialized) {
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
}
|
|
|
|
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
|
|
*
|
|
*/
|
|
nsresult
|
|
NSSToken::Sign(const CryptoBuffer& aApplicationParam,
|
|
const CryptoBuffer& aChallengeParam,
|
|
const CryptoBuffer& aKeyHandle,
|
|
CryptoBuffer& aSignatureData)
|
|
{
|
|
MOZ_ASSERT(mInitialized);
|
|
nsNSSShutDownPreventionLock locker;
|
|
if (isAlreadyShutDown()) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
MutexAutoLock lock(mMutex);
|
|
|
|
if (!mInitialized) {
|
|
return NS_ERROR_NOT_INITIALIZED;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
} // namespace dom
|
|
} // namespace mozilla
|