void
U2FTokenManager::ClearTransaction()
{
  if (mLastTransactionId > 0) {
    // Remove any prompts we might be showing for the current transaction.
    SendPromptNotification(kCancelPromptNotifcation, mLastTransactionId);
  }

  mTransactionParent = nullptr;

  // Drop managers at the end of all transactions
  if (mTokenManagerImpl) {
    mTokenManagerImpl->Drop();
    mTokenManagerImpl = nullptr;
  }

  // Forget promises, if necessary.
  mRegisterPromise.DisconnectIfExists();
  mSignPromise.DisconnectIfExists();

  // Clear transaction id.
  mLastTransactionId = 0;

  // Forget any pending registration.
  mPendingRegisterInfo.reset();
}
Esempio n. 2
0
void
U2FTokenManager::Sign(PWebAuthnTransactionParent* aTransactionParent,
                      const uint64_t& aTransactionId,
                      const WebAuthnGetAssertionInfo& aTransactionInfo)
{
  MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthSign"));

  ClearTransaction();
  mTransactionParent = aTransactionParent;
  mTokenManagerImpl = GetTokenManagerImpl();

  if (!mTokenManagerImpl) {
    AbortTransaction(aTransactionId, NS_ERROR_DOM_NOT_ALLOWED_ERR);
    return;
  }

  if ((aTransactionInfo.RpIdHash().Length() != SHA256_LENGTH) ||
      (aTransactionInfo.ClientDataHash().Length() != SHA256_LENGTH)) {
    AbortTransaction(aTransactionId, NS_ERROR_DOM_UNKNOWN_ERR);
    return;
  }

  // Show a prompt that lets the user cancel the ongoing transaction.
  NS_ConvertUTF16toUTF8 origin(aTransactionInfo.Origin());
  SendPromptNotification(kSignPromptNotifcation,
                         aTransactionId,
                         origin.get());

  uint64_t tid = mLastTransactionId = aTransactionId;
  mozilla::TimeStamp startTime = mozilla::TimeStamp::Now();

  mTokenManagerImpl
    ->Sign(aTransactionInfo)
    ->Then(GetCurrentThreadSerialEventTarget(), __func__,
      [tid, startTime](WebAuthnGetAssertionResult&& aResult) {
        U2FTokenManager* mgr = U2FTokenManager::Get();
        mgr->MaybeConfirmSign(tid, aResult);
        Telemetry::ScalarAdd(
          Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
          NS_LITERAL_STRING("U2FSignFinish"), 1);
        Telemetry::AccumulateTimeDelta(
          Telemetry::WEBAUTHN_GET_ASSERTION_MS,
          startTime);
      },
      [tid](nsresult rv) {
        MOZ_ASSERT(NS_FAILED(rv));
        U2FTokenManager* mgr = U2FTokenManager::Get();
        mgr->MaybeAbortSign(tid, rv);
        Telemetry::ScalarAdd(
          Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
          NS_LITERAL_STRING("U2FSignAbort"), 1);
      })
    ->Track(mSignPromise);
}
void
U2FTokenManager::Register(PWebAuthnTransactionParent* aTransactionParent,
                          const uint64_t& aTransactionId,
                          const WebAuthnMakeCredentialInfo& aTransactionInfo)
{
  MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthRegister"));

  ClearTransaction();
  mTransactionParent = aTransactionParent;
  mTokenManagerImpl = GetTokenManagerImpl();

  if (!mTokenManagerImpl) {
    AbortTransaction(aTransactionId, NS_ERROR_DOM_NOT_ALLOWED_ERR);
    return;
  }

  mLastTransactionId = aTransactionId;

  // Determine whether direct attestation was requested.
  bool directAttestationRequested = false;
  if (aTransactionInfo.Extra().type() == WebAuthnMaybeMakeCredentialExtraInfo::TWebAuthnMakeCredentialExtraInfo) {
    const auto& extra = aTransactionInfo.Extra().get_WebAuthnMakeCredentialExtraInfo();
    directAttestationRequested = extra.RequestDirectAttestation();
  }

  // Start a register request immediately if direct attestation
  // wasn't requested or the test pref is set.
  if (!directAttestationRequested ||
      U2FPrefManager::Get()->GetAllowDirectAttestationForTesting()) {
    // Force "none" attestation when "direct" attestation wasn't requested.
    DoRegister(aTransactionInfo, !directAttestationRequested);
    return;
  }

  // If the RP request direct attestation, ask the user for permission and
  // store the transaction info until the user proceeds or cancels.
  NS_ConvertUTF16toUTF8 origin(aTransactionInfo.Origin());
  SendPromptNotification(kRegisterDirectPromptNotifcation,
                         aTransactionId,
                         origin.get());

  MOZ_ASSERT(mPendingRegisterInfo.isNothing());
  mPendingRegisterInfo = Some(aTransactionInfo);
}
Esempio n. 4
0
void
U2FTokenManager::Register(PWebAuthnTransactionParent* aTransactionParent,
                          const uint64_t& aTransactionId,
                          const WebAuthnMakeCredentialInfo& aTransactionInfo)
{
  MOZ_LOG(gU2FTokenManagerLog, LogLevel::Debug, ("U2FAuthRegister"));

  ClearTransaction();
  mTransactionParent = aTransactionParent;
  mTokenManagerImpl = GetTokenManagerImpl();

  if (!mTokenManagerImpl) {
    AbortTransaction(aTransactionId, NS_ERROR_DOM_NOT_ALLOWED_ERR);
    return;
  }

  // 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)) {
    AbortTransaction(aTransactionId, NS_ERROR_DOM_UNKNOWN_ERR);
    return;
  }

  mLastTransactionId = aTransactionId;

  // If the RP request direct attestation, ask the user for permission and
  // store the transaction info until the user proceeds or cancels.
  // Might be overriden by a pref for testing purposes.
  if (aTransactionInfo.RequestDirectAttestation() &&
      !U2FPrefManager::Get()->GetAllowDirectAttestationForTesting()) {
    NS_ConvertUTF16toUTF8 origin(aTransactionInfo.Origin());
    SendPromptNotification(kRegisterDirectPromptNotifcation,
                           aTransactionId,
                           origin.get());

    MOZ_ASSERT(mPendingRegisterInfo.isNothing());
    mPendingRegisterInfo = Some(aTransactionInfo);
  } else {
    DoRegister(aTransactionInfo);
  }
}
Esempio n. 5
0
void
U2FTokenManager::DoRegister(const WebAuthnMakeCredentialInfo& aInfo)
{
  mozilla::ipc::AssertIsOnBackgroundThread();
  MOZ_ASSERT(mLastTransactionId > 0);

  // Show a prompt that lets the user cancel the ongoing transaction.
  NS_ConvertUTF16toUTF8 origin(aInfo.Origin());
  SendPromptNotification(kRegisterPromptNotifcation,
                         mLastTransactionId,
                         origin.get());

  uint64_t tid = mLastTransactionId;
  mozilla::TimeStamp startTime = mozilla::TimeStamp::Now();
  bool requestDirectAttestation = aInfo.RequestDirectAttestation();

  mTokenManagerImpl
    ->Register(aInfo)
    ->Then(GetCurrentThreadSerialEventTarget(), __func__,
          [tid, startTime, requestDirectAttestation](WebAuthnMakeCredentialResult&& aResult) {
            U2FTokenManager* mgr = U2FTokenManager::Get();
            // The token manager implementations set DirectAttestationPermitted
            // to false by default. Override this here with information from
            // the JS prompt.
            aResult.DirectAttestationPermitted() = requestDirectAttestation;
            mgr->MaybeConfirmRegister(tid, aResult);
            Telemetry::ScalarAdd(
              Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
              NS_LITERAL_STRING("U2FRegisterFinish"), 1);
            Telemetry::AccumulateTimeDelta(
              Telemetry::WEBAUTHN_CREATE_CREDENTIAL_MS,
              startTime);
          },
          [tid](nsresult rv) {
            MOZ_ASSERT(NS_FAILED(rv));
            U2FTokenManager* mgr = U2FTokenManager::Get();
            mgr->MaybeAbortRegister(tid, rv);
            Telemetry::ScalarAdd(
              Telemetry::ScalarID::SECURITY_WEBAUTHN_USED,
              NS_LITERAL_STRING("U2FRegisterAbort"), 1);
          })
    ->Track(mRegisterPromise);
}