not-webUSB
An alternative to webUSB with better browser support and the ability to restrict which sites can access the device.
The goal is to be a production ready library for use in real devices. However, while it works fine for simple use cases, it is not currently in a state where I would be comfortable deploying this in production.
not-webusb consists of:
- A usb-device class implementation that runs on your microcontroller
- Client code for talking to the microcontroller from a website.
- sample javascript code
- Or, a rust crate for wasm clients (Not implemented yet)
not-webusb is well suited for occasional one time operations like flashing configuration of a device. e.g. setting key mappings for a keyboard.
Constant live communication with a device is possible, but poorly suited. e.g. reading sensor data.
Browser support
Unlike webusb which supports only chrome and edge. not-webusb supports all major browsers, having been tested on:
- Firefox Desktop + Android
- Chrome Desktop + Android
- Edge - TODO test
- Safari Desktop
Downsides
Probably a fair bit slower compared to webusb, since it has to go through a lot of overhead with the U2F protocol. TODO: get some actual measurements done.
Also, most browsers flash the entire window every time a not-webusb transfer occurs. However, on firefox only a small box appears instead.
TODO: Example gif
How does it work though???
not-webusb is built on top of U2F (the legacy part of FIDO) the protocol for security keys.
However instead of implementing a security key, not-webusb smuggles data through the application_parameter and signature fields of the Authenticate messages sent between the browser and the device.
This is a fundamental part of the protocol and cannot be removed by browsers without rendering large numbers of currently working security keys unusable.
The idea comes from the I Cant Believe Its Not WebUSB demo, which uses the same fields to control an LED from the browser.
Examples
With a debugger+pico connected, and probe-rs installed, the examples can be run by one of:
- visiting Github pages
- locally running
./serve.shand then navigating to localhost:8000
and then following the instructions on the page.
Cargo Features
defmt- enable defmt logging
Running integration tests
Install system deps:
# TODO: confirm which are really needed
sudo apt install ninja-build mercurial python-is-python3 g++-14 libudev-dev
Flash the rot13 example firmware to a pico and then run cargo test.
Future work
- Make protocol implementation more robust
- Internal cleanup
- I would love for this project to have a recommended webusb implementation of the fido client protocol, allowing browsers with webusb support to avoid the "touch your security key" pop ups, while keeping fido as a fallback protocol. I have no immediate plans to implement this however.