Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ec52ca2605 | ||
![]() |
5d2acf19f1 | ||
![]() |
6196481b7f |
@ -30,7 +30,7 @@ Solo for Hacker is a special version of Solo that let you customize its firmware
|
||||
|
||||
Check out [solokeys.com](https://solokeys.com), for options on where to buy Solo. Solo Hacker can be converted to a secure version, but normal Solo cannot be converted to a Hacker version.
|
||||
|
||||
If you have a Solo for Hacker, here's how you can load your own code on it. You can find more details, including how to permanently lock it, in our [documentation](https://docs.solokeys.dev/building/). We support Python3.
|
||||
If you have a Solo for Hacker, here's how you can load your own code on it. You can find more details, including how to permanently lock it, in our [documentation](https://docs.solokeys.io/solo/building/). We support Python3.
|
||||
|
||||
For example, if you want to turn off any blue light emission, you can edit [`led_rgb()`](https://github.com/solokeys/solo/blob/master/targets/stm32l432/src/app.h#L48) and change `LED_INIT_VALUE`
|
||||
to be a different hex color.
|
||||
@ -63,7 +63,7 @@ git submodule update --init --recursive
|
||||
|
||||
## Installing the toolchain and applying updates
|
||||
|
||||
In order to compile ARM code, you need the ARM compiler and other things like bundling bootloader and firmware require the [solo-python](https://github.com/solokeys/solo-python) python package. Check our [documentation](https://docs.solokeys.dev/) for details.
|
||||
In order to compile ARM code, you need the ARM compiler and other things like bundling bootloader and firmware require the [solo-python](https://github.com/solokeys/solo-python) python package. Check our [documentation](https://docs.solokeys.io/solo/) for details.
|
||||
|
||||
You can update your solokey after running `pip3 install solo-python` with `solo key update` for the latest version. To apply a custom image use `solo program bootloader <file>(.json|.hex)`.
|
||||
|
||||
@ -122,12 +122,12 @@ Run the Solo application:
|
||||
|
||||
In another shell, you can run our [test suite](https://github.com/solokeys/fido2-tests).
|
||||
|
||||
You can find more details in our [documentation](https://docs.solokeys.dev/), including how to build on the the NUCLEO-L432KC development board.
|
||||
You can find more details in our [documentation](https://docs.solokeys.io/solo/), including how to build on the the NUCLEO-L432KC development board.
|
||||
|
||||
|
||||
# Documentation
|
||||
|
||||
Check out our [official documentation](https://docs.solokeys.dev/).
|
||||
Check out our [official documentation](https://docs.solokeys.io/solo/).
|
||||
|
||||
|
||||
# Contributors ✨
|
||||
|
@ -21,7 +21,7 @@ To report vulnerabilities you have found:
|
||||
- preferably contact [@conor1](https://keybase.io/conor1), [@0x0ece](https://keybase.io/0x0ece) or [@nickray](https://keybase.io/nickray) via Keybase, or
|
||||
- send us e-mail using OpenPGP to [security@solokeys.com](mailto:security@solokeys.com).
|
||||
|
||||
<https://keys.openpgp.org/vks/v1/by-fingerprint/BFA3F5387D025E8945CF907FC2F2505A63868DFA>
|
||||
<https://keys.openpgp.org/vks/v1/by-fingerprint/85AFA2769F4381E5712C36A04DDFC46FEF1F7F3F>
|
||||
|
||||
We do not currently run a paid bug bounty program, but are happy to provide you with a bunch of Solo keys in recognition of your findings.
|
||||
|
||||
|
@ -1 +1 @@
|
||||
4.0.0
|
||||
3.2.0
|
||||
|
27
default.nix
@ -1,27 +0,0 @@
|
||||
let
|
||||
pkgs = import (fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/20.03.tar.gz"; sha256 = "0182ys095dfx02vl2a20j1hz92dx3mfgz2a6fhn31bqlp1wa8hlq"; }) { };
|
||||
pyPackages = (python-packages: with python-packages; ([
|
||||
solo-python
|
||||
pytest
|
||||
] ++ (with builtins; map (d: getAttr d python-packages) (filter (d: stringLength d > 0) (pkgs.lib.splitString "\n" (builtins.readFile ./tools/requirements.txt))))));
|
||||
python-with-my-packages = pkgs.python3.withPackages pyPackages;
|
||||
src = with pkgs.lib; builtins.filterSource (path: type: !(hasSuffix path "hex" || hasSuffix path "sha256" || baseNameOf path == "result")) ./.;
|
||||
in
|
||||
with pkgs; stdenv.mkDerivation {
|
||||
name = "solo";
|
||||
outputs = [ "out" ];
|
||||
inherit src;
|
||||
buildInputs = [ src gnumake gcc gcc-arm-embedded-8 git python-with-my-packages ];
|
||||
phases = [ "unpackPhase" "configurePhase" "buildPhase" "installPhase" ];
|
||||
installPhase = ''
|
||||
mkdir -p $out/firmware $out/standalone/bin
|
||||
make
|
||||
cp main $out/standalone/bin/
|
||||
cd targets/stm32l432
|
||||
make cbor
|
||||
make build-hacker
|
||||
cp *.hex *.sha256 *.elf cubeconfig_stm32l442.ioc $out/firmware/
|
||||
ln -s ${src} $out/src
|
||||
'';
|
||||
keepDebugInfo = true;
|
||||
}
|
@ -1 +0,0 @@
|
||||
/solo/* /:splat 302
|
@ -1 +0,0 @@
|
||||
../README.md
|
@ -10,7 +10,7 @@ If your Solo is a bit older (<=2.5.3) You can put Solo into bootloader mode by u
|
||||
Hold down button while plugging in Solo. After 2 seconds, bootloader mode will activate.
|
||||
You'll see a yellowish flashing light and you can let go of the button.
|
||||
|
||||
Now Solo is ready to [accept firmware updates](/signed-updates). If the Solo is a secured model, it can only accept signed updates, typically in the `firmware-*.json` format.
|
||||
Now Solo is ready to [accept firmware updates](/solo/signed-updates). If the Solo is a secured model, it can only accept signed updates, typically in the `firmware-*.json` format.
|
||||
|
||||
# The boot stages of Solo
|
||||
|
@ -131,7 +131,7 @@ solo mergehex \
|
||||
bundle.hex
|
||||
```
|
||||
|
||||
See [here for more information on custom attestation](/customization/).
|
||||
See [here for more information on custom attestation](/solo/customization/).
|
||||
|
||||
To learn more about normal updates or a "full" update, you should [read more on Solo's boot stages](/bootloader-mode).
|
||||
To learn more about normal updates or a "full" update, you should [read more on Solo's boot stages](/solo/bootloader-mode).
|
||||
|
@ -19,7 +19,7 @@ and program it.
|
||||
### Creating your attestation key pair
|
||||
|
||||
Since we are generating keys, it's important to use a good entropy source.
|
||||
You can use the [True RNG on your Solo](/solo-extras) to generate some good random numbers.
|
||||
You can use the [True RNG on your Solo](/solo/solo-extras) to generate some good random numbers.
|
||||
|
||||
```
|
||||
# Run for 1 second, then hit control-c
|
||||
@ -114,7 +114,7 @@ If the checks succeed, you are ready to program the device attestation key and c
|
||||
|
||||
### Programming an attestation key and certificate
|
||||
|
||||
First, [Build your solo application and bootloader](/building).
|
||||
First, [Build your solo application and bootloader](/solo/building).
|
||||
|
||||
Print your attestation key in a hex string format. Using our utility script:
|
||||
|
||||
@ -137,6 +137,6 @@ solo mergehex \
|
||||
**Warning**: Using the `--lock` flag prevents the DFU from being accessed on the device again. It's recommended to try first without the `--lock` flag to make sure it works.
|
||||
|
||||
Now you have a newly created `bundle.hex` file with a custom attestation key and cert. You can [program this `bundle.hex` file
|
||||
with Solo in DFU mode](/programming#procedure).
|
||||
with Solo in DFU mode](/solo/programming#procedure).
|
||||
|
||||
Are you interested in customizing in bulk? Contact hello@solokeys.com and we can help.
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 134 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 129 KiB |
@ -64,7 +64,7 @@ In that case the mentioned patch would not be required.
|
||||
|
||||
Environment: Fedora 29 x64, Linux 4.19.9
|
||||
|
||||
See <https://docs.solokeys.dev/building/> for the original guide. Here details not included there will be covered.
|
||||
See <https://docs.solokeys.io/solo/building/> for the original guide. Here details not included there will be covered.
|
||||
|
||||
### Install ARM tools Linux
|
||||
|
||||
@ -102,7 +102,7 @@ export PATH="/Applications/STMicroelectronics/STM32Cube/STM32CubeProgrammer/STM3
|
||||
|
||||
### Building
|
||||
|
||||
Please follow <https://docs.solokeys.dev/building/>, as the build way changes rapidly.
|
||||
Please follow <https://docs.solokeys.io/solo/building/>, as the build way changes rapidly.
|
||||
Currently (8.1.19) to build the firmware, following lines should be executed
|
||||
|
||||
```bash
|
@ -13,7 +13,7 @@ pip3 install solo-python
|
||||
## Updating the firmware
|
||||
|
||||
If you just want to update the firmware, you can run one of the following commands.
|
||||
Make sure your key [is in bootloader mode](/bootloader-mode#solo-bootloader) first.
|
||||
Make sure your key [is in bootloader mode](/solo/bootloader-mode#solo-bootloader) first.
|
||||
|
||||
```bash
|
||||
solo key update <--secure | --hacker>
|
||||
@ -26,11 +26,11 @@ solo program bootloader <firmware.hex | firmware.json>
|
||||
```
|
||||
|
||||
Note you won't be able to use `all.hex` or the `bundle-*.hex` builds, as these include the solo bootloader. You shouldn't
|
||||
risk changing the Solo bootloader unless you want to make it a secure device, or [make other customizations](/customization/).
|
||||
risk changing the Solo bootloader unless you want to make it a secure device, or [make other customizations](/solo/customization/).
|
||||
|
||||
## Updating a Hacker to a Secure Solo
|
||||
|
||||
Updating a hacker to be a secure build overwrites the [Solo bootloader](/bootloader-mode#solo-bootloader).
|
||||
Updating a hacker to be a secure build overwrites the [Solo bootloader](/solo/bootloader-mode#solo-bootloader).
|
||||
So it's important to not mess this up or you may brick your device.
|
||||
|
||||
You can use a firmware build from the [latest release](https://github.com/solokeys/solo/releases) or use
|
||||
@ -41,8 +41,8 @@ This means using the `bundle-*.hex` file or the `bundle.hex` from your build.
|
||||
|
||||
#### *Warning*
|
||||
|
||||
* **Any DFU update erases everything! If you overwrite the Solo flash with a missing bootloader, it will be bricked.**
|
||||
* **If you program bootloader and firmware with no attestation, you will run into FIDO registration issues.**
|
||||
* **If you overwrite the Solo flash with a missing bootloader, it will be bricked**.
|
||||
* **If you program bootloader and firmware with no attestation, you will run into FIDO registration issues**
|
||||
|
||||
We provide two types of bundled builds. The `bundle-hacker-*.hex` build is the hacker build. If you update with this,
|
||||
you will update the bootloader and application, but nothing will be secured. The `bundle-secure-non-solokeys.hex`
|
1
docs/solo/repo-readme.md
Symbolic link
@ -0,0 +1 @@
|
||||
../../README.md
|
@ -4,12 +4,17 @@ On Linux, by default USB dongles can't be accessed by users, for security reason
|
||||
|
||||
For some users, things will work automatically:
|
||||
|
||||
- Recent Linux distributions (such as Ubuntu Focal, Fedora 32, [Arch Linux](https://wiki.archlinux.org/index.php/Solo)) with systemd 244 or higher automatically detect FIDO devices (check with `systemctl --version`)
|
||||
- Fedora seems to use a ["universal" udev rule for FIDO devices](https://github.com/amluto/u2f-hidraw-policy)
|
||||
- Our udev rule made it into [libu2f-host](https://github.com/Yubico/libu2f-host/) v1.1.10
|
||||
- Arch Linux [has this package](https://www.archlinux.org/packages/community/x86_64/libu2f-host/)
|
||||
- [Debian sid](https://packages.debian.org/sid/libu2f-udev) and [Ubuntu Eon](https://packages.ubuntu.com/eoan/libu2f-udev) can use the `libu2f-udev` package
|
||||
- Debian Buster and Ubuntu Disco still distribute v1.1.10, so need the manual rule
|
||||
- FreeBSD has support in [u2f-devd](https://github.com/solokeys/solo/issues/144#issuecomment-500216020)
|
||||
|
||||
There is hope that `udev` itself will adopt the Fedora approach (which is to check for HID usage page `F1D0`, and avoids manually whitelisting each U2F/FIDO2 key): <https://github.com/systemd/systemd/issues/11996>.
|
||||
|
||||
Further progress is tracked in: <https://github.com/solokeys/solo/issues/144>.
|
||||
|
||||
If you still need to setup a rule, a simple way to do it is:
|
||||
|
||||
```
|
@ -1,219 +0,0 @@
|
||||
# Tutorial: Getting started with the solo hacker
|
||||
|
||||
This is small guide to let you get started with the solo hacker key. In the end you will have set up everything you need and changed the LED from green to red.
|
||||
|
||||
## Some additional ressources
|
||||
|
||||
This tutorial will take you through all the necessary steps needed to install and get the solo key running. Before we start, I will just list you additional ressources, which might have important information for you:
|
||||
|
||||
* [The git repository](https://github.com/solokeys/solo): Here you will find all the code and a quick readme.
|
||||
* [The Documenation](https://docs.solokeys.io/solo/building/): The official documentation. Especially the [build instructions](https://docs.solokeys.io/solo/building/) are worth a look, if you got stuck.
|
||||
|
||||
## Getting the prerequisites
|
||||
|
||||
There are two main tools you will need to work on your solo hacker:
|
||||
|
||||
* ARM Compiler tool chain
|
||||
* Solo python tool
|
||||
|
||||
The ARM Compiler is used to compile your C-code to a hex file, which can then be deployed onto your solo hacker. The solo tool helps with deploying, updating etc. of the solo hacker. It is a python3 tool. So make sure, that you got Python3 installed on your system \([pip](https://pip.pypa.io/en/stable/) might also come in handy\).
|
||||
|
||||
Besides that, you will also need to get the [solo code](https://github.com/solokeys/solo).
|
||||
|
||||
### Get the code
|
||||
|
||||
The codebase for the solo hacker and other solo keys, can be found at this [git repository](https://github.com/solokeys/solo). So just clone this into your development folder. Make sure, that all the submodules are loaded by using the following command. I forgot to get all the submoules at my first try and the make command failed \(I got an error message telling me, that no solo.elf target can be found\).
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/solokeys/solo
|
||||
```
|
||||
|
||||
### Getting the ARM Compiler tool chain
|
||||
|
||||
Download the Compiler tool chain for your system [here](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads). After you have downloaded it, you will have to unzip it and add the path to the installation folder.
|
||||
|
||||
**Readme**
|
||||
There is a readme.txt __ in _gcc-arm-none-eabi-x-yyyy-dd-major/share/doc/gcc-arm-none-eabi_. It contains installation guides for Linux, Windows and Mac.
|
||||
|
||||
**Installation**
|
||||
As I used Mac, I will guide you through the installation using MacOS. If you have unpacked the folder already, you can skip the first step.
|
||||
|
||||
```bash
|
||||
#Unzip the tarball
|
||||
cd $install_dir && tar xjf gcc-arm-none-eabi-*-yyyymmdd-mac.tar.bz2
|
||||
|
||||
#Set path
|
||||
export PATH=$PATH:$install_dir/gcc-arm-none-eabi-*/bin
|
||||
|
||||
#Test if it works
|
||||
arm-none-eabi-gcc
|
||||
```
|
||||
|
||||
If everything worked your output should like this:
|
||||
|
||||
```bash
|
||||
arm-none-eabi-gcc: fatal error: no input files
|
||||
compilation terminated.
|
||||
```
|
||||
|
||||
### Getting the solo tool
|
||||
|
||||
There are several ways, which are listed at the [build instructions](https://docs.solokeys.io/solo/building/). If you are familiar with pip, just use this.
|
||||
|
||||
```bash
|
||||
pip install solo-python
|
||||
|
||||
#Or
|
||||
pip3 install solo-python
|
||||
```
|
||||
|
||||
**Install all other requirements**
|
||||
|
||||
To do this either do it in the virtual env or directly on your machine. The requirements can be found in the source folder in requirements.txt.
|
||||
|
||||
```bash
|
||||
#Move to source folder
|
||||
cd solo
|
||||
|
||||
#Install requirements, use pip3 otherwise
|
||||
pip install -r solo/tools/requirements.txt
|
||||
```
|
||||
|
||||
## Let's get a red light blinking
|
||||
|
||||
You will find the code for the key in _/solo/targets/stm32l432_ \(The target might have another id for you, so just use that id\). The LED colors can be found in [_/solo/targets/stm32l432 /src/app.h_](https://github.com/solokeys/solo/blob/master/targets/stm32l432/src/app.h)_._ To change the color we will just have to change the hex-value. Out of the box it should look like this:
|
||||
|
||||
```c
|
||||
// 0xRRGGBB
|
||||
#define LED_INIT_VALUE 0x000800
|
||||
#define LED_WINK_VALUE 0x000010
|
||||
#define LED_MAX_SCALER 15
|
||||
#define LED_MIN_SCALER 1
|
||||
```
|
||||
|
||||
_LED\_INIT\_VALUE_ is the color, that the LED shows whenever it is plugged in. It normally is a green light. So let's change it to red:
|
||||
|
||||
```c
|
||||
// 0xRRGGBB
|
||||
#define LED_INIT_VALUE 0xFF0800
|
||||
#define LED_WINK_VALUE 0x000010
|
||||
#define LED_MAX_SCALER 15
|
||||
#define LED_MIN_SCALER 1
|
||||
```
|
||||
|
||||
_LED\_WINK\_VALUE_ is the color, which is shown, whenever the bottom is pressed. It normally is a blue tone, but let's change it to a yellow:
|
||||
|
||||
```c
|
||||
// 0xRRGGBB
|
||||
#define LED_INIT_VALUE 0xFF0800
|
||||
#define LED_WINK_VALUE 0xFFFF00
|
||||
#define LED_MAX_SCALER 15
|
||||
#define LED_MIN_SCALER 1
|
||||
```
|
||||
|
||||
Save the file and then let's try to get the code onto the stick.
|
||||
|
||||
## Move code to solo hacker
|
||||
|
||||
First we have to build cbor. To do this change into the target folder and use the corresponding command.
|
||||
|
||||
```bash
|
||||
#Change into correct directory
|
||||
cd solo/targets/stm32l432/
|
||||
|
||||
#Make cbor
|
||||
make cbor
|
||||
```
|
||||
|
||||
You should also make sure to check, that your key has the newest solo firmware installed. To check the firmware on the device, use this command:
|
||||
|
||||
```bash
|
||||
solo key version
|
||||
```
|
||||
|
||||
To update to the newest version, use this command:
|
||||
|
||||
```bash
|
||||
solo key version
|
||||
```
|
||||
|
||||
**Note:** Sometimes the connection between Mac and key seemed to be broken and you might get an error stating: _No solo found_. Just unplug the key and plug it back in.
|
||||
|
||||
### General deployment cycle
|
||||
|
||||
In general we will always have to go through these steps:
|
||||
|
||||
* Compile code and generate new firmware
|
||||
* Change device into bootloader mode
|
||||
* Deploy code to device
|
||||
|
||||
#### Compile code
|
||||
|
||||
To compile the code, we will again have to change into our target directory:
|
||||
|
||||
```bash
|
||||
#Change into correct directory
|
||||
cd solo/targets/stm32l432/
|
||||
```
|
||||
|
||||
It is important to choose the correct build target. Most explanations focus on the build of the firmware and use:
|
||||
|
||||
```bash
|
||||
make firmware
|
||||
```
|
||||
|
||||
As we are using the solo hacker, we will need to use:
|
||||
|
||||
```bash
|
||||
make build-hacker
|
||||
```
|
||||
|
||||
This will generate a file _solo.hex_, which has the compiled code on it. If you later need to change the bootloader itself, please refer to [the documentation](https://docs.solokeys.io/solo/building/).
|
||||
|
||||
#### Deploy code
|
||||
|
||||
To deploy the code make sure you are back at the source root.
|
||||
|
||||
```bash
|
||||
cd ../..
|
||||
```
|
||||
|
||||
First we will have to change into bootload modus:
|
||||
|
||||
```bash
|
||||
solo program aux enter-bootloader
|
||||
```
|
||||
|
||||
This is needed to be able to load the new firmware on the device. If we forget this step, the solo tool will do it for us in the next step.
|
||||
|
||||
This is the moment of truth. We delete the old firmware and deploy the new one with the changed LED lights to the solo key. For this step we will also stay in the source root.
|
||||
|
||||
```bash
|
||||
solo program bootloader targets/stm32l432/solo.hex
|
||||
```
|
||||
|
||||
If there is another hex-File, that you want to load, you can just exchange the last argument.
|
||||
|
||||
And that's it, now your LED should be red.
|
||||
|
||||
To summarize, here are again the steps to update your solo:
|
||||
|
||||
1. Change code
|
||||
2. Run these commands
|
||||
|
||||
```bash
|
||||
#Change into correct directory
|
||||
cd solo/targets/stm32l432/
|
||||
|
||||
#Compile code
|
||||
make build-hacker
|
||||
|
||||
#Change to root
|
||||
cd ../..
|
||||
|
||||
#Enter bootload mode
|
||||
solo program aux enter-bootloader
|
||||
|
||||
#Deploy code
|
||||
solo program bootloader targets/stm32l432/solo.hex
|
||||
```
|
@ -1,205 +0,0 @@
|
||||
# Tutorial: Writing an extension for the solo stick
|
||||
A short overview about, where and how you should implement your extension into the solo stick code base. In this tutorial we will add a small extension, that will engage in a "ping"-"pong" exchange.
|
||||
|
||||
## Make it visible
|
||||
We need to make it visible, that the key now supports a new extension.
|
||||
This is done in the function _ctap_get_info_ in [ctap.c](https://github.com/solokeys/solo/blob/master/fido2/ctap.c). This function creates a map with all the information about the solo key. You should therefore add your extension identifier here, too.
|
||||
```c
|
||||
uint8_t ctap_get_info(CborEncoder * encoder){
|
||||
//[...]
|
||||
ret = cbor_encode_uint(&map, RESP_extensions);
|
||||
check_ret(ret);
|
||||
{
|
||||
ret = cbor_encoder_create_array(&map, &array, 3);
|
||||
check_ret(ret);
|
||||
{
|
||||
ret = cbor_encode_text_stringz(&array, "hmac-secret");
|
||||
check_ret(ret);
|
||||
|
||||
ret = cbor_encode_text_stringz(&array, "credProtect");
|
||||
check_ret(ret);
|
||||
|
||||
//Add it here
|
||||
}
|
||||
ret = cbor_encoder_close_container(&map, &array);
|
||||
check_ret(ret);
|
||||
}
|
||||
//[...]
|
||||
}
|
||||
```
|
||||
After you have added your identifier it should look similiar to this:
|
||||
```c
|
||||
uint8_t ctap_get_info(CborEncoder * encoder){
|
||||
//[...]
|
||||
ret = cbor_encode_uint(&map, RESP_extensions);
|
||||
check_ret(ret);
|
||||
{
|
||||
ret = cbor_encoder_create_array(&map, &array, 3); //This number should reflect the number of supported extensions
|
||||
check_ret(ret);
|
||||
{
|
||||
ret = cbor_encode_text_stringz(&array, "hmac-secret");
|
||||
check_ret(ret);
|
||||
|
||||
ret = cbor_encode_text_stringz(&array, "credProtect");
|
||||
check_ret(ret);
|
||||
|
||||
//Add it here
|
||||
ret = cbor_encode_text_stringz(&array, "ping-pong");
|
||||
check_ret(ret);
|
||||
}
|
||||
ret = cbor_encoder_close_container(&map, &array);
|
||||
check_ret(ret);
|
||||
}
|
||||
//[...]
|
||||
}
|
||||
|
||||
```
|
||||
Important: make sure to change the size of the created array to the correct number of elements.
|
||||
|
||||
## Let's get our extension parsed
|
||||
As with all incoming messages, the extension has to be parsed and depending on the incoming message the reply has to be constructed. For this the function _ctap_parse_extensions_ in [ctap_parse.c](https://github.com/solokeys/solo/blob/master/fido2/ctap_parse.c) is used.
|
||||
In this function the extension identifier is checked. So, if we want to add our ping-pong extension, we need to compare the incoming identifier to our identifier "ping-pong".
|
||||
```c
|
||||
uint8_t ctap_parse_extensions(CborValue * val, CTAP_extensions * ext){
|
||||
//[...]
|
||||
|
||||
if (strncmp(key, "hmac-secret",11) == 0){
|
||||
//[...]
|
||||
}else if (strncmp(key, "credProtect",11) == 0) {
|
||||
//[...]
|
||||
else if (strncmp(key, "ping-pong",9) == 0) {
|
||||
//Logic should be placed here
|
||||
}
|
||||
//[...]
|
||||
}
|
||||
```
|
||||
What happens then, depends on your extension. You should make sure, to check incoming values for correctness, though. As hmac-secret and credProtect are already implemented, you could have a look at their implementations for a kind of guideline.
|
||||
At this stage we can use the extension struct, which can be found in [ctap.h](https://github.com/solokeys/solo/blob/master/fido2/ctap.h).
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
uint8_t hmac_secret_present;
|
||||
CTAP_hmac_secret hmac_secret;
|
||||
|
||||
uint32_t cred_protect;
|
||||
} CTAP_extensions;
|
||||
```
|
||||
This struct already contains important values for the other extensions, so we are going to add two for our extension. The first "ping_pong_present" should indicate if the key received a message with a ping-pong extension. The response should then contain the correct response.
|
||||
```c
|
||||
typedef struct
|
||||
{
|
||||
uint8_t hmac_secret_present;
|
||||
CTAP_hmac_secret hmac_secret;
|
||||
|
||||
uint32_t cred_protect;
|
||||
|
||||
uint8_t ping_pong_present;
|
||||
char ping_pong_response[4];
|
||||
} CTAP_extensions;
|
||||
```
|
||||
Now we have to parse our message accordingly.
|
||||
```c
|
||||
uint8_t ctap_parse_extensions(CborValue * val, CTAP_extensions * ext){
|
||||
//[...]
|
||||
|
||||
if (strncmp(key, "hmac-secret",11) == 0){
|
||||
//[...]
|
||||
}else if (strncmp(key, "credProtect",11) == 0) {
|
||||
//[...]
|
||||
else if (strncmp(key, "ping-pong",9) == 0) {
|
||||
if (cbor_value_get_type(&map) == CborTextStringType)
|
||||
{
|
||||
//Cop incoming message
|
||||
uint8_t txt[5];
|
||||
sz = sizeof(txt);
|
||||
ret = cbor_value_copy_text_string(&map, (char *)txt, &sz, NULL);
|
||||
check_ret(ret);
|
||||
|
||||
if(strcmp((const char*)txt, "ping") == 0) {
|
||||
ext->ping_pong_present = 0x01;
|
||||
strcpy((char *)ext->ping_pong_response, "pong");
|
||||
}else if(strcmp((const char*)txt, "pong") == 0) {
|
||||
ext->ping_pong_present = 0x01;
|
||||
strcpy((char *)ext->ping_pong_response, "ping");
|
||||
}else{
|
||||
printf2(TAG_ERR, "Wrong parameter requested. Got %s.\r\n", txt);
|
||||
return CTAP2_ERR_INVALID_OPTION;
|
||||
}
|
||||
}else{
|
||||
printf1(TAG_RED, "warning: ping-pong request ignored for being wrong type\r\n");
|
||||
}
|
||||
}
|
||||
//[...]
|
||||
}
|
||||
```
|
||||
Here we are doing the following:
|
||||
1. Check if we got a message with either "ping" or "pong"
|
||||
2. Set the correct value, to note, that we received a message using the ping-pong extension
|
||||
3. Set the correct response ("pong" for "ping" and vice versa)
|
||||
|
||||
|
||||
## Create a reply
|
||||
Now, that we have parsed the correct message, we have to construct the correct reply. That is done in the function _ctap_make_extensions_ in [ctap.c](https://github.com/solokeys/solo/blob/master/fido2/ctap.c). We will use the before filled _CTAP_extensions_ in here.
|
||||
We have to do two things here:
|
||||
1. Check, if a message using the ping-pong extension
|
||||
2. Set the correct response according to our parsed incoming message
|
||||
```c
|
||||
static int ctap_make_extensions(CTAP_extensions * ext, uint8_t * ext_encoder_buf, unsigned int * ext_encoder_buf_size){
|
||||
//[...]
|
||||
|
||||
if (ext->hmac_secret_present == EXT_HMAC_SECRET_PARSED)
|
||||
{
|
||||
//[...]
|
||||
}
|
||||
else if (ext->hmac_secret_present == EXT_HMAC_SECRET_REQUESTED)
|
||||
{
|
||||
//[...]
|
||||
}
|
||||
if (ext->cred_protect != EXT_CRED_PROTECT_INVALID) {
|
||||
//[...]
|
||||
}
|
||||
|
||||
if(ext->ping_pong_present){
|
||||
extensions_used += 1;
|
||||
ping_pong_is_valid = 1;
|
||||
}
|
||||
|
||||
if (extensions_used > 0)
|
||||
{
|
||||
//[...]
|
||||
if (hmac_secret_output_is_valid) {
|
||||
{
|
||||
//[...]
|
||||
}
|
||||
}
|
||||
if (hmac_secret_requested_is_valid) {
|
||||
{
|
||||
//[...]
|
||||
}
|
||||
}
|
||||
if (cred_protect_is_valid) {
|
||||
{
|
||||
//[...]
|
||||
}
|
||||
}
|
||||
if (ping_pong_is_valid) {
|
||||
{
|
||||
ret = cbor_encode_text_stringz(&extension_output_map, "ping-pong");
|
||||
check_ret(ret);
|
||||
|
||||
//Set the response message
|
||||
ret = cbor_encode_text_stringz(&extension_output_map, (const char*)ext->ping_pong_response);
|
||||
check_ret(ret);
|
||||
}
|
||||
}
|
||||
//[...]
|
||||
}
|
||||
//[...]
|
||||
}
|
||||
```
|
||||
|
||||
## Recap
|
||||
To create a new extension, you would have to take the following three steps:
|
||||
- Make sure, that the new extension will be made visible through a call of get_info
|
||||
- Parse incoming messages correctly
|
||||
- Construct the correct reply
|
19
fido2/ctap.c
@ -1586,15 +1586,18 @@ static int scan_for_next_rk(int index, uint8_t * initialRpIdHash){
|
||||
|
||||
if (initialRpIdHash != NULL) {
|
||||
memmove(lastRpIdHash, initialRpIdHash, 32);
|
||||
index = -1;
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ctap_load_rk(index, &rk);
|
||||
memmove(lastRpIdHash, rk.id.rpIdHash, 32);
|
||||
index++;
|
||||
}
|
||||
|
||||
do
|
||||
ctap_load_rk(index, &rk);
|
||||
|
||||
while ( memcmp( rk.id.rpIdHash, lastRpIdHash, 32 ) != 0 )
|
||||
{
|
||||
index++;
|
||||
if ((unsigned int)index >= ctap_rk_size())
|
||||
@ -1603,7 +1606,6 @@ static int scan_for_next_rk(int index, uint8_t * initialRpIdHash){
|
||||
}
|
||||
ctap_load_rk(index, &rk);
|
||||
}
|
||||
while ( memcmp( rk.id.rpIdHash, lastRpIdHash, 32 ) != 0 );
|
||||
|
||||
return index;
|
||||
}
|
||||
@ -1749,7 +1751,7 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (GA.pinAuthEmpty && GA.up)
|
||||
if (GA.pinAuthEmpty)
|
||||
{
|
||||
ret = ctap2_user_presence_test();
|
||||
check_retr(ret);
|
||||
@ -2442,15 +2444,6 @@ uint8_t ctap_is_pin_set()
|
||||
*/
|
||||
void ctap_update_pin(uint8_t * pin, int len)
|
||||
{
|
||||
|
||||
// Remove PIN if the new PIN is either "" or 4321
|
||||
if (len == 0 || strncmp(pin, "4321", len) == 0) {
|
||||
STATE.is_pin_set = 0;
|
||||
memset(STATE.PIN_CODE_HASH, 0, sizeof(STATE.PIN_CODE_HASH));
|
||||
authenticator_write_state(&STATE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (len >= NEW_PIN_ENC_MIN_SIZE || len < 4)
|
||||
{
|
||||
printf2(TAG_ERR, "Update pin fail length\n");
|
||||
|
42
mkdocs.yml
Executable file → Normal file
@ -1,36 +1,34 @@
|
||||
site_name: Solo Technical Documentation
|
||||
site_author: SoloKeys
|
||||
site_description: 'Documentation for the SoloKeys solo software'
|
||||
site_url: 'https://docs.solokeys.dev/'
|
||||
site_url: 'https://docs.solokeys.io/solo/'
|
||||
repo_url: 'https://github.com/solokeys/solo'
|
||||
repo_name: 'solokeys/solo'
|
||||
copyright: 'Copyright © 2018 - 2019 SoloKeys'
|
||||
|
||||
nav:
|
||||
- Home: index.md
|
||||
- FIDO2 Implementation: fido2-impl.md
|
||||
- Metadata Statements: metadata-statements.md
|
||||
- Build instructions: building.md
|
||||
- Programming instructions: programming.md
|
||||
- Bootloader mode: bootloader-mode.md
|
||||
- Customization: customization.md
|
||||
- Solo Extras: solo-extras.md
|
||||
- Application Ideas: application-ideas.md
|
||||
- Running on Nucleo32 board: nucleo32-board.md
|
||||
- Signed update process: signed-updates.md
|
||||
- Usage and Porting guide: porting.md
|
||||
- Tutorial – Getting Started: tutorial-getting-started.md
|
||||
- Tutorial - Writing extensions: tutorial-writing-extensions.md
|
||||
- Code documentation: code-overview.md
|
||||
- Contributing Code: contributing.md
|
||||
- Contributing Docs: documenting.md
|
||||
- udev Rules: udev.md
|
||||
- About: repo-readme.md
|
||||
- Home: solo/index.md
|
||||
- FIDO2 Implementation: solo/fido2-impl.md
|
||||
- Metadata Statements: solo/metadata-statements.md
|
||||
- Build instructions: solo/building.md
|
||||
- Programming instructions: solo/programming.md
|
||||
- Bootloader mode: solo/bootloader-mode.md
|
||||
- Customization: solo/customization.md
|
||||
- Solo Extras: solo/solo-extras.md
|
||||
- Application Ideas: solo/application-ideas.md
|
||||
- Running on Nucleo32 board: solo/nucleo32-board.md
|
||||
- Signed update process: solo/signed-updates.md
|
||||
- Usage and Porting guide: solo/porting.md
|
||||
- Code documentation: solo/code-overview.md
|
||||
- Contributing Code: solo/contributing.md
|
||||
- Contributing Docs: solo/documenting.md
|
||||
- udev Rules: solo/udev.md
|
||||
- About: solo/repo-readme.md
|
||||
|
||||
theme:
|
||||
name: material
|
||||
logo: 'images/logo.svg'
|
||||
favicon: 'images/favicon.ico'
|
||||
logo: 'solo/images/logo.svg'
|
||||
favicon: 'solo/images/favicon.ico'
|
||||
|
||||
markdown_extensions:
|
||||
- markdown_include.include
|
||||
|
13
shell.nix
@ -1,13 +0,0 @@
|
||||
let
|
||||
nixpkgs_tar = fetchTarball { url = "https://github.com/NixOS/nixpkgs/archive/20.03.tar.gz"; sha256 = "0182ys095dfx02vl2a20j1hz92dx3mfgz2a6fhn31bqlp1wa8hlq"; };
|
||||
pkgs = import "${nixpkgs_tar}" {};
|
||||
pyPackages = (python-packages: with python-packages; ([
|
||||
solo-python pytest
|
||||
] ++ (with builtins; map (d: getAttr d python-packages) (filter (d: stringLength d > 0) (pkgs.lib.splitString "\n" (builtins.readFile ./tools/requirements.txt))))));
|
||||
python-with-my-packages = pkgs.python3.withPackages pyPackages;
|
||||
in
|
||||
with pkgs;
|
||||
stdenv.mkDerivation {
|
||||
name = "solo";
|
||||
buildInputs = [ gnumake gcc gcc-arm-embedded-8 python-with-my-packages ];
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
# STM32L432 Solo
|
||||
|
||||
Check out our [official documentation](https://docs.solokeys.dev/building/)
|
||||
Check out our [official documentation](https://docs.solokeys.io/solo/building/)
|
||||
for instructions on building and programming!
|
||||
|