diff --git a/dom/webauthn/U2FTokenManager.cpp b/dom/webauthn/U2FTokenManager.cpp index c97dc6e16fdd..6fdd9279a38e 100644 --- a/dom/webauthn/U2FTokenManager.cpp +++ b/dom/webauthn/U2FTokenManager.cpp @@ -157,17 +157,6 @@ U2FTokenManager::Get() return gU2FTokenManager; } -void -U2FTokenManager::MaybeAbortTransaction(uint64_t aTransactionId, - const nsresult& aError) -{ - if (mTransactionId != aTransactionId) { - return; - } - - AbortTransaction(aError); -} - void U2FTokenManager::AbortTransaction(const nsresult& aError) { @@ -191,16 +180,18 @@ U2FTokenManager::ClearTransaction() mTransactionParent = nullptr; // Drop managers at the end of all transactions mTokenManagerImpl = nullptr; - // Drop promises. - mRegisterPromise = nullptr; - mSignPromise = nullptr; - // Increase in case we're called by the WebAuthnTransactionParent. + // Forget promises, if necessary. + mRegisterPromise.DisconnectIfExists(); + mSignPromise.DisconnectIfExists(); + // Bump transaction id. mTransactionId++; } RefPtr U2FTokenManager::GetTokenManagerImpl() { + MOZ_ASSERT(U2FPrefManager::Get()); + if (mTokenManagerImpl) { return mTokenManagerImpl; } @@ -231,9 +222,8 @@ U2FTokenManager::Register(WebAuthnTransactionParent* aTransactionParent, const WebAuthnTransactionInfo& aTransactionInfo) { MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthRegister")); - MOZ_ASSERT(U2FPrefManager::Get()); - uint64_t tid = ++mTransactionId; + ClearTransaction(); mTransactionParent = aTransactionParent; mTokenManagerImpl = GetTokenManagerImpl(); @@ -252,12 +242,12 @@ U2FTokenManager::Register(WebAuthnTransactionParent* aTransactionParent, return; } - mRegisterPromise = mTokenManagerImpl->Register(aTransactionInfo.Descriptors(), - aTransactionInfo.RpIdHash(), - aTransactionInfo.ClientDataHash(), - aTransactionInfo.TimeoutMS()); - - mRegisterPromise->Then(GetCurrentThreadSerialEventTarget(), __func__, + uint64_t tid = mTransactionId; + mTokenManagerImpl->Register(aTransactionInfo.Descriptors(), + aTransactionInfo.RpIdHash(), + aTransactionInfo.ClientDataHash(), + aTransactionInfo.TimeoutMS()) + ->Then(GetCurrentThreadSerialEventTarget(), __func__, [tid](U2FRegisterResult&& aResult) { U2FTokenManager* mgr = U2FTokenManager::Get(); mgr->MaybeConfirmRegister(tid, aResult); @@ -265,8 +255,9 @@ U2FTokenManager::Register(WebAuthnTransactionParent* aTransactionParent, [tid](nsresult rv) { MOZ_ASSERT(NS_FAILED(rv)); U2FTokenManager* mgr = U2FTokenManager::Get(); - mgr->MaybeAbortTransaction(tid, rv); - }); + mgr->MaybeAbortRegister(tid, rv); + }) + ->Track(mRegisterPromise); } void @@ -277,6 +268,8 @@ U2FTokenManager::MaybeConfirmRegister(uint64_t aTransactionId, return; } + mRegisterPromise.Complete(); + nsTArray registration; aResult.ConsumeRegistration(registration); @@ -284,14 +277,25 @@ U2FTokenManager::MaybeConfirmRegister(uint64_t aTransactionId, ClearTransaction(); } +void +U2FTokenManager::MaybeAbortRegister(uint64_t aTransactionId, + const nsresult& aError) +{ + if (mTransactionId != aTransactionId) { + return; + } + + mRegisterPromise.Complete(); + AbortTransaction(aError); +} + void U2FTokenManager::Sign(WebAuthnTransactionParent* aTransactionParent, const WebAuthnTransactionInfo& aTransactionInfo) { MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthSign")); - MOZ_ASSERT(U2FPrefManager::Get()); - uint64_t tid = ++mTransactionId; + ClearTransaction(); mTransactionParent = aTransactionParent; mTokenManagerImpl = GetTokenManagerImpl(); @@ -306,12 +310,12 @@ U2FTokenManager::Sign(WebAuthnTransactionParent* aTransactionParent, return; } - mSignPromise = mTokenManagerImpl->Sign(aTransactionInfo.Descriptors(), - aTransactionInfo.RpIdHash(), - aTransactionInfo.ClientDataHash(), - aTransactionInfo.TimeoutMS()); - - mSignPromise->Then(GetCurrentThreadSerialEventTarget(), __func__, + uint64_t tid = mTransactionId; + mTokenManagerImpl->Sign(aTransactionInfo.Descriptors(), + aTransactionInfo.RpIdHash(), + aTransactionInfo.ClientDataHash(), + aTransactionInfo.TimeoutMS()) + ->Then(GetCurrentThreadSerialEventTarget(), __func__, [tid](U2FSignResult&& aResult) { U2FTokenManager* mgr = U2FTokenManager::Get(); mgr->MaybeConfirmSign(tid, aResult); @@ -319,8 +323,9 @@ U2FTokenManager::Sign(WebAuthnTransactionParent* aTransactionParent, [tid](nsresult rv) { MOZ_ASSERT(NS_FAILED(rv)); U2FTokenManager* mgr = U2FTokenManager::Get(); - mgr->MaybeAbortTransaction(tid, rv); - }); + mgr->MaybeAbortSign(tid, rv); + }) + ->Track(mSignPromise); } void @@ -331,6 +336,8 @@ U2FTokenManager::MaybeConfirmSign(uint64_t aTransactionId, return; } + mSignPromise.Complete(); + nsTArray keyHandle; aResult.ConsumeKeyHandle(keyHandle); nsTArray signature; @@ -340,13 +347,26 @@ U2FTokenManager::MaybeConfirmSign(uint64_t aTransactionId, ClearTransaction(); } +void +U2FTokenManager::MaybeAbortSign(uint64_t aTransactionId, const nsresult& aError) +{ + if (mTransactionId != aTransactionId) { + return; + } + + mSignPromise.Complete(); + AbortTransaction(aError); +} + void U2FTokenManager::Cancel(WebAuthnTransactionParent* aParent) { - if (mTransactionParent == aParent) { - mTokenManagerImpl->Cancel(); - ClearTransaction(); + if (mTransactionParent != aParent) { + return; } + + mTokenManagerImpl->Cancel(); + ClearTransaction(); } } diff --git a/dom/webauthn/U2FTokenManager.h b/dom/webauthn/U2FTokenManager.h index f54faec2299e..cab154efa1cd 100644 --- a/dom/webauthn/U2FTokenManager.h +++ b/dom/webauthn/U2FTokenManager.h @@ -49,18 +49,18 @@ private: RefPtr GetTokenManagerImpl(); void AbortTransaction(const nsresult& aError); void ClearTransaction(); - void MaybeAbortTransaction(uint64_t aTransactionId, - const nsresult& aError); void MaybeConfirmRegister(uint64_t aTransactionId, U2FRegisterResult& aResult); + void MaybeAbortRegister(uint64_t aTransactionId, const nsresult& aError); void MaybeConfirmSign(uint64_t aTransactionId, U2FSignResult& aResult); + void MaybeAbortSign(uint64_t aTransactionId, 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 mTokenManagerImpl; - RefPtr mRegisterPromise; - RefPtr mSignPromise; + MozPromiseRequestHolder mRegisterPromise; + MozPromiseRequestHolder mSignPromise; // Guards the asynchronous promise resolution of token manager impls. // We don't need to protect this with a lock as it will only be modified // and checked on the PBackground thread in the parent process.