Bug 1442557 - [u2f-hid-rs] Keep polling excluded devices when creating credentials r=jcj
authorTim Taubert <ttaubert@mozilla.com>
Fri, 02 Mar 2018 16:03:33 +0100
changeset 461386 5eac7178cb0a4ffd965cc999928a9302ca377f69
parent 461385 9bd114008fd7658e6bc356f6b9d94431d323bc85
child 461387 d85679eb427513cb18650f3d4e7d37a6ccbefbab
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjcj
bugs1442557
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1442557 - [u2f-hid-rs] Keep polling excluded devices when creating credentials r=jcj Reviewers: jcj Reviewed By: jcj Bug #: 1442557 Differential Revision: https://phabricator.services.mozilla.com/D670
dom/webauthn/u2f-hid-rs/src/statemachine.rs
--- a/dom/webauthn/u2f-hid-rs/src/statemachine.rs
+++ b/dom/webauthn/u2f-hid-rs/src/statemachine.rs
@@ -82,29 +82,36 @@ impl StateMachine {
             // Technically, this is a ConstraintError because we shouldn't talk
             // to this authenticator in the first place. But the result is the
             // same anyway.
             if !flags.is_empty() {
                 return;
             }
 
             // Iterate the exclude list and see if there are any matches.
-            // Abort the state machine if we found a valid key handle.
-            if key_handles.iter().any(|key_handle| {
+            // If so, we'll keep polling the device anyway to test for user
+            // consent, to be consistent with CTAP2 device behavior.
+            let excluded = key_handles.iter().any(|key_handle| {
                 is_valid_transport(key_handle.transports)
                     && u2f_is_keyhandle_valid(dev, &challenge, &application, &key_handle.credential)
                         .unwrap_or(false) /* no match on failure */
-            }) {
-                return;
-            }
+            });
 
             while alive() {
-                if let Ok(bytes) = u2f_register(dev, &challenge, &application) {
-                    callback.call(Ok(bytes));
-                    break;
+                if excluded {
+                    let blank = vec![0u8; PARAMETER_SIZE];
+                    if let Ok(_) = u2f_register(dev, &blank, &blank) {
+                        callback.call(Err(io_err("duplicate registration")));
+                        break;
+                    }
+                } else {
+                    if let Ok(bytes) = u2f_register(dev, &challenge, &application) {
+                        callback.call(Ok(bytes));
+                        break;
+                    }
                 }
 
                 // Sleep a bit before trying again.
                 thread::sleep(Duration::from_millis(100));
             }
         });
 
         self.transaction = Some(try_or!(transaction, |_| cbc.call(Err(io_err(