not-webusb 0.1.0

Communicate between a webpage and a usb device without webusb
Documentation

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.

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
  • Chrome Desktop
  • Chrome Mobile - TODO Fix
  • 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:

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.