Backed out changeset cdc1a8372229 (bug 1323339)

This commit is contained in:
Sebastian Hengst 2017-05-08 21:17:19 +02:00
parent e5136852e6
commit a03d774c23
11 changed files with 0 additions and 639 deletions

View File

@ -1,93 +0,0 @@
/* -*- 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 "mozilla/dom/U2FSoftTokenManager.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"
namespace mozilla {
namespace dom {
U2FSoftTokenManager::U2FSoftTokenManager(uint32_t aCounter) :
mCounter(aCounter)
{
}
U2FSoftTokenManager::~U2FSoftTokenManager()
{
}
// IsRegistered determines if the provided key handle is usable by this token.
nsresult
U2FSoftTokenManager::IsRegistered(nsTArray<uint8_t>& aKeyHandle,
nsTArray<uint8_t>& aAppParam,
bool& aResult)
{
aResult = false;
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
//
nsresult
U2FSoftTokenManager::Register(nsTArray<uint8_t>& aApplication,
nsTArray<uint8_t>& aChallenge,
/* out */ nsTArray<uint8_t>& aRegistration,
/* out */ nsTArray<uint8_t>& aSignature)
{
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
U2FSoftTokenManager::Sign(nsTArray<uint8_t>& aApplication,
nsTArray<uint8_t>& aChallenge,
nsTArray<uint8_t>& aKeyHandle,
nsTArray<uint8_t>& aSignature)
{
return NS_OK;
}
}
}

View File

@ -1,45 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_dom_U2FSoftTokenManager_h
#define mozilla_dom_U2FSoftTokenManager_h
#include "mozilla/dom/U2FTokenTransport.h"
#include "ScopedNSSTypes.h"
#include "nsNSSShutDown.h"
/*
* U2FSoftTokenManager is a software implementation of a secure token manager
* for the U2F and WebAuthn APIs.
*/
namespace mozilla {
namespace dom {
class U2FSoftTokenManager final : public U2FTokenTransport
{
public:
U2FSoftTokenManager(uint32_t aCounter);
virtual nsresult Register(nsTArray<uint8_t>& aApplication,
nsTArray<uint8_t>& aChallenge,
/* out */ nsTArray<uint8_t>& aRegistration,
/* out */ nsTArray<uint8_t>& aSignature) override;
virtual nsresult Sign(nsTArray<uint8_t>& aApplication,
nsTArray<uint8_t>& aChallenge,
nsTArray<uint8_t>& aKeyHandle,
/* out */ nsTArray<uint8_t>& aSignature) override;
nsresult IsRegistered(nsTArray<uint8_t>& aKeyHandle,
nsTArray<uint8_t>& aAppParam,
bool& aResult);
private:
~U2FSoftTokenManager();
uint32_t mCounter;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_U2FSoftTokenManager_h

View File

@ -1,279 +0,0 @@
/* -*- 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 "mozilla/dom/U2FTokenManager.h"
#include "mozilla/dom/U2FTokenTransport.h"
#include "mozilla/dom/U2FSoftTokenManager.h"
#include "mozilla/dom/WebAuthnTransactionParent.h"
#include "mozilla/MozPromise.h"
#include "mozilla/dom/WebAuthnUtil.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Unused.h"
#include "hasht.h"
#include "nsICryptoHash.h"
#include "pkix/Input.h"
#include "pkixutil.h"
// 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"
#define PREF_WEBAUTHN_SOFTTOKEN_ENABLED "security.webauth.webauthn_enable_softtoken"
namespace mozilla {
namespace dom {
/***********************************************************************
* Statics
**********************************************************************/
class U2FPrefManager;
namespace {
static mozilla::LazyLogModule gU2FTokenManagerLog("u2fkeymanager");
StaticRefPtr<U2FTokenManager> gU2FTokenManager;
StaticRefPtr<U2FPrefManager> gPrefManager;
}
class U2FPrefManager final : public nsIObserver
{
private:
U2FPrefManager() :
mPrefMutex("U2FPrefManager Mutex")
{
MOZ_ASSERT(NS_IsMainThread());
MutexAutoLock lock(mPrefMutex);
mSoftTokenEnabled = Preferences::GetBool(PREF_WEBAUTHN_SOFTTOKEN_ENABLED);
mSoftTokenCounter = Preferences::GetUint(PREF_U2F_NSSTOKEN_COUNTER);
}
~U2FPrefManager() = default;
public:
NS_DECL_ISUPPORTS
static U2FPrefManager* GetOrCreate()
{
MOZ_ASSERT(NS_IsMainThread());
if (!gPrefManager) {
gPrefManager = new U2FPrefManager();
Preferences::AddStrongObserver(gPrefManager, PREF_WEBAUTHN_SOFTTOKEN_ENABLED);
Preferences::AddStrongObserver(gPrefManager, PREF_U2F_NSSTOKEN_COUNTER);
ClearOnShutdown(&gPrefManager, ShutdownPhase::ShutdownThreads);
}
return gPrefManager;
}
static U2FPrefManager* Get()
{
return gPrefManager;
}
bool GetSoftTokenEnabled()
{
MutexAutoLock lock(mPrefMutex);
return mSoftTokenEnabled;
}
int GetSoftTokenCounter()
{
MutexAutoLock lock(mPrefMutex);
return mSoftTokenCounter;
}
NS_IMETHODIMP
Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData) override
{
MOZ_ASSERT(NS_IsMainThread());
MutexAutoLock lock(mPrefMutex);
mSoftTokenEnabled = Preferences::GetBool(PREF_WEBAUTHN_SOFTTOKEN_ENABLED);
mSoftTokenCounter = Preferences::GetUint(PREF_U2F_NSSTOKEN_COUNTER);
return NS_OK;
}
private:
Mutex mPrefMutex;
bool mSoftTokenEnabled;
int mSoftTokenCounter;
};
NS_IMPL_ISUPPORTS(U2FPrefManager, nsIObserver);
/***********************************************************************
* U2FManager Implementation
**********************************************************************/
U2FTokenManager::U2FTokenManager() :
mTransactionParent(nullptr)
{
MOZ_ASSERT(XRE_IsParentProcess());
// Create on the main thread to make sure ClearOnShutdown() works.
MOZ_ASSERT(NS_IsMainThread());
// Create the preference manager while we're initializing.
U2FPrefManager::GetOrCreate();
}
U2FTokenManager::~U2FTokenManager()
{
MOZ_ASSERT(NS_IsMainThread());
}
//static
void
U2FTokenManager::Initialize()
{
if (!XRE_IsParentProcess()) {
return;
}
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!gU2FTokenManager);
gU2FTokenManager = new U2FTokenManager();
ClearOnShutdown(&gU2FTokenManager);
}
//static
U2FTokenManager*
U2FTokenManager::Get()
{
MOZ_ASSERT(XRE_IsParentProcess());
// We should only be accessing this on the background thread
MOZ_ASSERT(!NS_IsMainThread());
return gU2FTokenManager;
}
void
U2FTokenManager::MaybeClearTransaction(WebAuthnTransactionParent* aParent)
{
// Only clear if we've been requested to do so by our current transaction
// parent.
if (mTransactionParent != aParent) {
return;
}
mTransactionParent = nullptr;
// Drop managers at the end of all transactions
mSoftTokenManager = nullptr;
}
void
U2FTokenManager::Cancel(const nsresult& aError)
{
if (mTransactionParent) {
Unused << mTransactionParent->SendCancel(aError);
}
MaybeClearTransaction(mTransactionParent);
}
void
U2FTokenManager::Register(WebAuthnTransactionParent* aTransactionParent,
WebAuthnTransactionInfo& aTransactionInfo)
{
MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthRegister"));
MOZ_ASSERT(U2FPrefManager::Get());
mTransactionParent = aTransactionParent;
// Since we only have soft token available at the moment, use that if the pref
// is on.
//
// TODO Check all transports and use WebAuthnRequest to aggregate
// replies
if (U2FPrefManager::Get()->GetSoftTokenEnabled()) {
if (!mSoftTokenManager) {
mSoftTokenManager = new U2FSoftTokenManager(U2FPrefManager::Get()->GetSoftTokenCounter());
}
// Check if all the supplied parameters are syntactically well-formed and
// of the correct length. If not, return an error code equivalent to
// UnknownError and terminate the operation.
if ((aTransactionInfo.RpIdHash().Length() != SHA256_LENGTH) ||
(aTransactionInfo.ClientDataHash().Length() != SHA256_LENGTH)) {
Cancel(NS_ERROR_DOM_UNKNOWN_ERR);
return;
}
nsresult rv;
for (auto desc: aTransactionInfo.Descriptors()) {
bool isRegistered = false;
rv = mSoftTokenManager->IsRegistered(desc.id(), aTransactionInfo.RpIdHash(), isRegistered);
if (NS_FAILED(rv)) {
Cancel(rv);
return;
}
if (isRegistered) {
Cancel(NS_ERROR_DOM_NOT_ALLOWED_ERR);
return;
}
}
nsTArray<uint8_t> reg;
nsTArray<uint8_t> sig;
rv = mSoftTokenManager->Register(aTransactionInfo.RpIdHash(),
aTransactionInfo.ClientDataHash(),
reg,
sig);
if (NS_FAILED(rv)) {
Cancel(rv);
return;
}
Unused << mTransactionParent->SendConfirmRegister(reg,
sig);
MaybeClearTransaction(mTransactionParent);
return;
}
Cancel(NS_ERROR_DOM_NOT_ALLOWED_ERR);
}
void
U2FTokenManager::Sign(WebAuthnTransactionParent* aTransactionParent,
WebAuthnTransactionInfo& aTransactionInfo)
{
MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthSign"));
MOZ_ASSERT(U2FPrefManager::Get());
mTransactionParent = aTransactionParent;
// Since we only have soft token available at the moment, use that if the pref
// is on.
//
// TODO Check all transports and use WebAuthnRequest to aggregate
// replies
if (U2FPrefManager::Get()->GetSoftTokenEnabled()) {
if (!mSoftTokenManager) {
mSoftTokenManager = new U2FSoftTokenManager(U2FPrefManager::Get()->GetSoftTokenCounter());
}
if ((aTransactionInfo.RpIdHash().Length() != SHA256_LENGTH) ||
(aTransactionInfo.ClientDataHash().Length() != SHA256_LENGTH)) {
Cancel(NS_ERROR_DOM_UNKNOWN_ERR);
return;
}
for (auto desc: aTransactionInfo.Descriptors()) {
bool reg;
nsresult rv = mSoftTokenManager->IsRegistered(desc.id(), aTransactionInfo.RpIdHash(), reg);
if (!reg) {
continue;
}
nsTArray<uint8_t> sig;
rv = mSoftTokenManager->Sign(aTransactionInfo.RpIdHash(),
aTransactionInfo.ClientDataHash(),
desc.id(),
sig);
if (NS_FAILED(rv)) {
Cancel(rv);
return;
}
Unused << mTransactionParent->SendConfirmSign(desc.id(), sig);
MaybeClearTransaction(mTransactionParent);
return;
}
}
// If we come out of the loop, we aren't registered
Cancel(NS_ERROR_DOM_NOT_ALLOWED_ERR);
}
}
}

View File

@ -1,67 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_dom_U2FTokenManager_h
#define mozilla_dom_U2FTokenManager_h
#include "mozilla/dom/PWebAuthnTransaction.h"
#include "mozilla/MozPromise.h"
/*
* Parent process manager for U2F and WebAuthn API transactions. Handles process
* transactions from all content processes, make sure only one transaction is
* live at any time. Manages access to hardware and software based key systems.
*
* U2FTokenManager is created on the first access to functions of either the U2F
* or WebAuthn APIs that require key registration or signing. It lives until the
* end of the browser process.
*/
namespace mozilla {
namespace dom {
class U2FTokenTransport;
class U2FSoftTokenManager;
class WebAuthnTransactionParent;
class U2FTokenManager final
{
struct U2FPrefs
{
bool softTokenEnabled;
uint32_t softTokenCounter;
};
typedef MozPromise<bool, nsresult, false> PrefPromise;
public:
enum TransactionType
{
RegisterTransaction = 0,
SignTransaction,
NumTransactionTypes
};
NS_INLINE_DECL_REFCOUNTING(U2FTokenManager)
static U2FTokenManager* Get();
void Register(WebAuthnTransactionParent* aTransactionParent,
WebAuthnTransactionInfo& aTransactionInfo);
void Sign(WebAuthnTransactionParent* aTransactionParent,
WebAuthnTransactionInfo& aTransactionInfo);
void MaybeClearTransaction(WebAuthnTransactionParent* aParent);
static void Initialize();
private:
U2FTokenManager();
~U2FTokenManager();
void Cancel(const nsresult& aError);
// Using a raw pointer here, as the lifetime of the IPC object is managed by
// the PBackground protocol code. This means we cannot be left holding an
// invalid IPC protocol object after the transaction is finished.
WebAuthnTransactionParent* mTransactionParent;
RefPtr<U2FSoftTokenManager> mSoftTokenManager;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_U2FTokenManager_h

View File

@ -1,39 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_dom_U2FTokenTransport_h
#define mozilla_dom_U2FTokenTransport_h
/*
* Abstract class representing a transport manager for U2F Keys (software,
* bluetooth, usb, etc.). Hides the implementation details for specific key
* transport types.
*/
namespace mozilla {
namespace dom {
class U2FTokenTransport
{
public:
NS_INLINE_DECL_REFCOUNTING(U2FTokenTransport);
U2FTokenTransport() {}
virtual nsresult Register(nsTArray<uint8_t>& aApplication,
nsTArray<uint8_t>& aChallenge,
/* out */ nsTArray<uint8_t>& aRegistration,
/* out */ nsTArray<uint8_t>& aSignature) = 0;
virtual nsresult Sign(nsTArray<uint8_t>& aApplication,
nsTArray<uint8_t>& aChallenge,
nsTArray<uint8_t>& aKeyHandle,
/* out */ nsTArray<uint8_t>& aSignature) = 0;
protected:
virtual ~U2FTokenTransport() = default;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_U2FTokenTransport_h

View File

@ -1,46 +0,0 @@
/* -*- 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 "mozilla/dom/WebAuthnTransactionParent.h"
#include "mozilla/dom/U2FTokenManager.h"
namespace mozilla {
namespace dom {
mozilla::ipc::IPCResult
WebAuthnTransactionParent::RecvRequestRegister(const WebAuthnTransactionInfo& aTransactionInfo)
{
U2FTokenManager* mgr = U2FTokenManager::Get();
// Cast away const here since NSS wants to be able to use non-const functions
mgr->Register(this, const_cast<WebAuthnTransactionInfo&>(aTransactionInfo));
return IPC_OK();
}
mozilla::ipc::IPCResult
WebAuthnTransactionParent::RecvRequestSign(const WebAuthnTransactionInfo& aTransactionInfo)
{
U2FTokenManager* mgr = U2FTokenManager::Get();
// Cast away const here since NSS wants to be able to use non-const functions
mgr->Sign(this, const_cast<WebAuthnTransactionInfo&>(aTransactionInfo));
return IPC_OK();
}
mozilla::ipc::IPCResult
WebAuthnTransactionParent::RecvRequestCancel()
{
U2FTokenManager* mgr = U2FTokenManager::Get();
mgr->MaybeClearTransaction(this);
return IPC_OK();
}
void
WebAuthnTransactionParent::ActorDestroy(ActorDestroyReason aWhy)
{
U2FTokenManager* mgr = U2FTokenManager::Get();
mgr->MaybeClearTransaction(this);
}
}
}

View File

@ -1,39 +0,0 @@
/* -*- 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/. */
#ifndef mozilla_dom_WebAuthnTransactionParent_h
#define mozilla_dom_WebAuthnTransactionParent_h
#include "mozilla/dom/PWebAuthnTransactionParent.h"
/*
* Parent process IPC implementation for WebAuthn and U2F API. Receives
* authentication data to be either registered or signed by a key, passes
* information to U2FTokenManager.
*/
namespace mozilla {
namespace dom {
class WebAuthnTransactionParent final : public PWebAuthnTransactionParent
{
public:
NS_INLINE_DECL_REFCOUNTING(WebAuthnTransactionParent);
WebAuthnTransactionParent() = default;
virtual mozilla::ipc::IPCResult
RecvRequestRegister(const WebAuthnTransactionInfo& aTransactionInfo) override;
virtual mozilla::ipc::IPCResult
RecvRequestSign(const WebAuthnTransactionInfo& aTransactionInfo) override;
virtual mozilla::ipc::IPCResult RecvRequestCancel() override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
private:
~WebAuthnTransactionParent() = default;
};
}
}
#endif //mozilla_dom_WebAuthnTransactionParent_h

View File

@ -15,16 +15,12 @@ EXPORTS.mozilla.dom += [
'NSSU2FTokenRemote.h',
'ScopedCredential.h',
'ScopedCredentialInfo.h',
'U2FSoftTokenManager.h',
'U2FTokenManager.h',
'U2FTokenTransport.h',
'WebAuthentication.h',
'WebAuthnAssertion.h',
'WebAuthnAttestation.h',
'WebAuthnManager.h',
'WebAuthnRequest.h',
'WebAuthnTransactionChild.h',
'WebAuthnTransactionParent.h',
'WebAuthnUtil.h'
]
@ -32,14 +28,11 @@ UNIFIED_SOURCES += [
'NSSU2FTokenRemote.cpp',
'ScopedCredential.cpp',
'ScopedCredentialInfo.cpp',
'U2FSoftTokenManager.cpp',
'U2FTokenManager.cpp',
'WebAuthentication.cpp',
'WebAuthnAssertion.cpp',
'WebAuthnAttestation.cpp',
'WebAuthnManager.cpp',
'WebAuthnTransactionChild.cpp',
'WebAuthnTransactionParent.cpp',
'WebAuthnUtil.cpp'
]

View File

@ -40,7 +40,6 @@
#include "mozilla/ipc/PParentToChildStreamParent.h"
#include "mozilla/layout/VsyncParent.h"
#include "mozilla/dom/network/UDPSocketParent.h"
#include "mozilla/dom/WebAuthnTransactionParent.h"
#include "mozilla/Preferences.h"
#include "nsNetUtil.h"
#include "nsIScriptSecurityManager.h"
@ -67,7 +66,6 @@ using mozilla::dom::FileSystemRequestParent;
using mozilla::dom::MessagePortParent;
using mozilla::dom::PMessagePortParent;
using mozilla::dom::UDPSocketParent;
using mozilla::dom::WebAuthnTransactionParent;
namespace {
@ -890,20 +888,6 @@ BackgroundParentImpl::DeallocPGamepadTestChannelParent(dom::PGamepadTestChannelP
return true;
}
dom::PWebAuthnTransactionParent*
BackgroundParentImpl::AllocPWebAuthnTransactionParent()
{
return new dom::WebAuthnTransactionParent();
}
bool
BackgroundParentImpl::DeallocPWebAuthnTransactionParent(dom::PWebAuthnTransactionParent *aActor)
{
MOZ_ASSERT(aActor);
delete aActor;
return true;
}
} // namespace ipc
} // namespace mozilla

View File

@ -225,12 +225,6 @@ protected:
virtual bool
DeallocPGamepadTestChannelParent(PGamepadTestChannelParent* aActor) override;
virtual PWebAuthnTransactionParent*
AllocPWebAuthnTransactionParent() override;
virtual bool
DeallocPWebAuthnTransactionParent(PWebAuthnTransactionParent* aActor) override;
};
} // namespace ipc

View File

@ -127,7 +127,6 @@
#include "mozilla/StaticPresData.h"
#include "mozilla/dom/WebIDLGlobalNameHash.h"
#include "mozilla/dom/ipc/IPCBlobInputStreamStorage.h"
#include "mozilla/dom/U2FTokenManager.h"
using namespace mozilla;
using namespace mozilla::net;
@ -318,7 +317,6 @@ nsLayoutStatics::Initialize()
// This must be initialized on the main-thread.
mozilla::dom::IPCBlobInputStreamStorage::Initialize();
mozilla::dom::U2FTokenManager::Initialize();
return NS_OK;
}