gecko-dev/dom/u2f/NSSToken.cpp

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