[WebAuthN] Change the nonce in the CTAP kInit command to weak random values
[WebKit-https.git] / Source / WebKit / UIProcess / WebAuthentication / Mock / MockHidConnection.cpp
index 0b17699bdde9784b4c7863d9d7be9245465f2a64..d86a3a472e6bb77390e3401a6cde82c653a6846e 100644 (file)
@@ -127,43 +127,48 @@ void MockHidConnection::parseRequest()
         if (previousSubStage == Mock::SubStage::Msg)
             m_stage = Mock::Stage::Request;
     }
-    if (m_requestMessage->cmd() == FidoHidDeviceCommand::kCbor)
+    if (m_requestMessage->cmd() == FidoHidDeviceCommand::kCbor || m_requestMessage->cmd() == FidoHidDeviceCommand::kMsg)
         m_subStage = Mock::SubStage::Msg;
 
-    // Set options.
     if (m_stage == Mock::Stage::Request && m_subStage == Mock::SubStage::Msg) {
-        m_requireResidentKey = false;
-        m_requireUserVerification = false;
-
-        auto payload = m_requestMessage->getMessagePayload();
-        ASSERT(payload.size());
-        auto cmd = static_cast<CtapRequestCommand>(payload[0]);
-        payload.remove(0);
-        auto requestMap = CBORReader::read(payload);
-        ASSERT(requestMap);
-
-        if (cmd == CtapRequestCommand::kAuthenticatorMakeCredential) {
-            auto it = requestMap->getMap().find(CBORValue(CtapMakeCredentialRequestOptionsKey)); // Find options.
-            if (it != requestMap->getMap().end()) {
-                auto& optionMap = it->second.getMap();
-
-                auto itr = optionMap.find(CBORValue(kResidentKeyMapKey));
-                if (itr != optionMap.end())
-                    m_requireResidentKey = itr->second.getBool();
-
-                itr = optionMap.find(CBORValue(kUserVerificationMapKey));
-                if (itr != optionMap.end())
-                    m_requireUserVerification = itr->second.getBool();
+        // Make sure we issue different msg cmd for CTAP and U2F.
+        ASSERT(m_configuration.hid->isU2f ^ (m_requestMessage->cmd() != FidoHidDeviceCommand::kMsg));
+
+        // Set options.
+        if (m_requestMessage->cmd() == FidoHidDeviceCommand::kCbor) {
+            m_requireResidentKey = false;
+            m_requireUserVerification = false;
+
+            auto payload = m_requestMessage->getMessagePayload();
+            ASSERT(payload.size());
+            auto cmd = static_cast<CtapRequestCommand>(payload[0]);
+            payload.remove(0);
+            auto requestMap = CBORReader::read(payload);
+            ASSERT(requestMap);
+
+            if (cmd == CtapRequestCommand::kAuthenticatorMakeCredential) {
+                auto it = requestMap->getMap().find(CBORValue(CtapMakeCredentialRequestOptionsKey)); // Find options.
+                if (it != requestMap->getMap().end()) {
+                    auto& optionMap = it->second.getMap();
+
+                    auto itr = optionMap.find(CBORValue(kResidentKeyMapKey));
+                    if (itr != optionMap.end())
+                        m_requireResidentKey = itr->second.getBool();
+
+                    itr = optionMap.find(CBORValue(kUserVerificationMapKey));
+                    if (itr != optionMap.end())
+                        m_requireUserVerification = itr->second.getBool();
+                }
             }
-        }
 
-        if (cmd == CtapRequestCommand::kAuthenticatorGetAssertion) {
-            auto it = requestMap->getMap().find(CBORValue(CtapGetAssertionRequestOptionsKey)); // Find options.
-            if (it != requestMap->getMap().end()) {
-                auto& optionMap = it->second.getMap();
-                auto itr = optionMap.find(CBORValue(kUserVerificationMapKey));
-                if (itr != optionMap.end())
-                    m_requireUserVerification = itr->second.getBool();
+            if (cmd == CtapRequestCommand::kAuthenticatorGetAssertion) {
+                auto it = requestMap->getMap().find(CBORValue(CtapGetAssertionRequestOptionsKey)); // Find options.
+                if (it != requestMap->getMap().end()) {
+                    auto& optionMap = it->second.getMap();
+                    auto itr = optionMap.find(CBORValue(kUserVerificationMapKey));
+                    if (itr != optionMap.end())
+                        m_requireUserVerification = itr->second.getBool();
+                }
             }
         }
     }
@@ -207,8 +212,12 @@ void MockHidConnection::feedReports()
         infoData.insert(0, static_cast<uint8_t>(CtapDeviceResponseCode::kSuccess)); // Prepend status code.
         if (stagesMatch() && m_configuration.hid->error == Mock::Error::WrongChannelId)
             message = FidoHidMessage::create(m_currentChannel - 1, FidoHidDeviceCommand::kCbor, infoData);
-        else
-            message = FidoHidMessage::create(m_currentChannel, FidoHidDeviceCommand::kCbor, infoData);
+        else {
+            if (!m_configuration.hid->isU2f)
+                message = FidoHidMessage::create(m_currentChannel, FidoHidDeviceCommand::kCbor, infoData);
+            else
+                message = FidoHidMessage::create(m_currentChannel, FidoHidDeviceCommand::kError, { static_cast<uint8_t>(CtapDeviceResponseCode::kCtap1ErrInvalidCommand) });
+        }
     }
 
     if (m_stage == Mock::Stage::Request && m_subStage == Mock::SubStage::Msg) {
@@ -223,9 +232,14 @@ void MockHidConnection::feedReports()
             message = FidoHidMessage::create(m_currentChannel, FidoHidDeviceCommand::kCbor, { static_cast<uint8_t>(CtapDeviceResponseCode::kCtap2ErrUnsupportedOption) });
         else {
             Vector<uint8_t> payload;
-            auto status = base64Decode(m_configuration.hid->payloadBase64, payload);
+            ASSERT(!m_configuration.hid->payloadBase64.isEmpty());
+            auto status = base64Decode(m_configuration.hid->payloadBase64[0], payload);
+            m_configuration.hid->payloadBase64.remove(0);
             ASSERT_UNUSED(status, status);
-            message = FidoHidMessage::create(m_currentChannel, FidoHidDeviceCommand::kCbor, payload);
+            if (!m_configuration.hid->isU2f)
+                message = FidoHidMessage::create(m_currentChannel, FidoHidDeviceCommand::kCbor, payload);
+            else
+                message = FidoHidMessage::create(m_currentChannel, FidoHidDeviceCommand::kMsg, payload);
         }
     }