solokeys / solo1 Goto Github PK
View Code? Open in Web Editor NEWSolo 1 firmware in C
Home Page: https://solokeys.com/
License: Other
Solo 1 firmware in C
Home Page: https://solokeys.com/
License: Other
Hi,
just cloned solo and try to build it but failed with a missing setup.py.
Here the output of 'make all'
virtualenv venv
Using base prefix '/usr'
New python executable in /home/ingo/solo/venv/bin/python
Installing setuptools, pip, wheel...done.
./venv/bin/pip install wheel
Requirement already satisfied: wheel in ./venv/lib/python3.7/site-packages (0.32.2)
cd python-fido2/ && ../venv/bin/python setup.py install
../venv/bin/python: can't open file 'setup.py': [Errno 2] No such file or directory
make: *** [Makefile:93: python-fido2] Fehler 2
Any hints?
The provided udev rule sets the uaccess
TAG to allow the logged user to use the key. This is however useless as the name of the rule is 99-solo.rules
.
According to udev man pages:
All rules files are collectively sorted and processed in lexical order, regardless of the directories in which they live.
The udev rule from systemd setting ACL based on the uaccess
tag is 73-seat-late.rules
. Hence, the name of the provided rule should begin with a 2 digit number at most 73. The rule provided by @craftyguy in #45 was originally correct (content and name of the rule).
Looking at the libu2f-udev
package in debian, setting the tag should be enough when using a recent version of udev. Please also note that plugdev group is deprecated.
I however believe that it would be better if we keep in the documentation a rule setting mode and group for user of older udev versions. This should be properly flagged.
Is it possible to protect the key with a PIN like the YubiKey does?
Conor and I will be at Shmoocon. Anyone else at the conf or in DC?
I'm arriving tonight (Thu 17), free for dinner :)
I was watching this hack on the Ledger bootloader verification and wondering if Solo's bootloader is secure against it.
The entire presentation is very interesting and highly recommended.
Building current master on Linux produces HEX files that "don't work".
As a workaround, I created a release based on a Windows build by Conor.
We should obviously fix this ASAP.
...it looks like maybe it's supposed to be run in a different directory? There's no main.c
in the dir next to the Makefile.
Has there already been some thought about using a touch button (cap/res) instead of a push button?
To me it seems quite a nice substitution as it's one moving part less that can break/fail.
Perhaps provide some scripts?
I found in Repo only a PDF with a schematic, but where is the schematic ready to be imported into Eagle?
Apologies for the noise:
.git/config
files at your leisure)Some suggestions that have been made:
I think setting up a Google group might be best for everyone, feel free to suggest otherwise though.
In current documentation, it seems to be implied that a programmer will be required to reflash the device with user-provided code.
The STM32 series has a nice DFU bootloader in ROM. The ability to activate this from USB should rightly be a no-no for security reasons, but AIUI it's activated via the BOOT0 pin, which is currently unconnected.
The SWDIO/SWCLK pins already appear to be broken out, I assume to test pads, on the schematic. Any interest in breaking out BOOT0 as well so people without a STM32 programmer can boot it into DFU mode?
(Security considerations: None, since SWDIO/SWCLK are already present and enable reprogramming for anyone with physical access to the device. This enables someone to reprogram the device only if they have physical access, but without a programmer. Of course, the DFU application in boot ROM doesn't enable code readout protection to be bypassed; erasure must be performed first.)
any chance getting openpgp support added?
Reading through the docs and especially (Readme.md):
Note that our python-fido2 fork will only connect to the software FIDO2 application, not a hardware authenticator. Install Yubico's fork to do that.
I understood that it was possible to build solo as a software virtual authenticator? Is that true? If so, what is the status on that? And how to build solo for PC only? For now I'm getting a lot of undefined functions issues.
Thank you for your help
The current firmware upgrage and extension depend on the U2F API. From my knowledge, U2F is an API supported only in Chrome. In CTAP2 supported by all major browsers, it is not easy to transmit arbitrary extension data with web browser api. If I'm right, is there a way to solve this problem?
The Readme states:
Run example client software. This runs through a registration and authentication.
python python-fido2/examples/credential.py
#33 broke this. I think it's because make is not calling
python-fido2: venv
cd python-fido2/ && ../venv/bin/python setup.py install
Hey,
is there a plan to opensource the hardware too like with the U2FZero? The main page states "easy to solder hardware" but I mean does it include gerbers, KiKad, etc.? I enjoyed that with the U2Fzero.
In the meantime I'll start to get a nucleo board :-)
Thanks!
Since it looks like a modem, the linux daemon ModemManager
will automatically start messing with it. I had to disable it:
systemctl stop ModemManager
Need to find what to change in the USB descriptors to prevent things like this from happening.
https://github.com/solokeys/solo/blob/master/targets/stm32l432/lib/usbd/usbd_composite.c#L100
One issue - which annoys a lot of us, when using touch mode on yubikey (which is a LOT safer) - is that we use https://www.passwordstore.org/ - which keeps each password in its own file - and gpg encrypts that file.
That works great - and when touch is required for each operation, no one can steal my passwords - as it'll just 'blink' and wait for my touch..
However.. for certain operations.. we really would like a way to "longpress".. or "auto touch" for multiple gpg operations..
f.ex. When we want to run ansible (remote operations) on 100+ machines (that only takes ~5-10 seconds to login to them all ) (using ssh-agent feature of gpg-agent)
or when I need to reencrypt my passwordstore (to give access to another person - or remove ones access) - since both times, I need to touch for EVERY server|password.
I would like to be able to setup so "touch for x times.. or for X amount of time.." - enabled "longpress" - where the key will "act as if I am still touching it" for ~10 seconds or so - giving me time to do the operations I need to, without having to touch for every single one (ie. disabling fix setting for that specific operation type (sign, encrypt.. )) for that small timeperiod..
We have been assigned two VID/PID pairs:
I suggest we use 0x1209/0x50B0 for the bootloader, and 0x1209/0x5070 for the hacker build, to distinguish from 0x0483/0xA2CA which we'd continue to use for the locked down regular consumer Solo.
It seems to be a bit more involved than just adding some more defines to lib/usbd/usbd_desc.c
as I managed to brick a key that way :)
If adding following option to navigator.credentials.create function,
authenticatorSelection = {
"authenticatorAttachment": "cross-platform",
"requireResidentKey": true,
"userVerification": "preferred"
};
Solo stopped at CTAP_GET_INFO as following debug output, if I set requireResidentKey to false, it works fine.
[HID]
hello solo
init device
init ctaphid
init ctap
[STOR] Auth state is NOT initialized. Initializing..
[DEBUG] resetting RK
[STOR] pin not set.
recv'ing hid msg
[DUMP2] >> ff ff ff ff 86 00 08 05 c1 a7 6a f0 ca d9 69 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[HID] Recv packet
[HID] CID: ffffffff
[HID] cmd: 86
[HID] length: 8
[HID] adding a new cid
[DUMP2] << ff ff ff ff 86 00 11 05 c1 a7 6a f0 ca d9 69 02 00 00 00 02 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[DUMP2] >> 02 00 00 00 90 00 01 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[HID] Recv packet
[HID] CID: 00000002
[HID] cmd: 90
[HID] length: 1
[HID] CTAPHID_CBOR
[CTAP] cbor input structure: 0 bytes
[DUMP] cbor req:
[CTAP] CTAP_GET_INFO
a5 01 82 66 55 32 46 5f 56 32 68 46 49 44 4f 5f 32 5f 30 03 50 88 76 63 1b d4 a0 42 7f 57 73 0e c7 1c 9e 02 79 05 19 04 b0 06 81 01 04 a4 64 70 6c 61 74 f4 62 72 6b f5 62 75 70 f5 69 63 6c 69 65 6e 74 50 69 6e f4
[CTAP] cbor output structure: 71 bytes. Return 0x00
[DUMP2] << 02 00 00 00 90 00 48 00 a5 01 82 66 55 32 46 5f 56 32 68 46 49 44 4f 5f 32 5f 30 03 50 88 76 63 1b d4 a0 42 7f 57 73 0e c7 1c 9e 02 79 05 19 04 b0 06 81 01 04 a4 64 70 6c 61 74 f4 62 72 6b f5
[DUMP2] << 02 00 00 00 00 62 75 70 f5 69 63 6c 69 65 6e 74 50 69 6e f4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Here's what I did:
pj@raft:~/src/solo$ ./venv/bin/python python-fido2/examples/credential.py
No FIDO device found
pj@raft:~/src/solo$
pj@raft:~/src/solo$ ./main &
[1] 30086
pj@raft:~/src/solo$ state file exists
init device
init ctaphid
init ctap
[STOR] Auth state is initialized
[STOR] pin not set.
recv'ing hid msg
pj@raft:~/src/solo$ ./venv/bin/python python-fido2/examples/credential.py
Traceback (most recent call last):
File "python-fido2/examples/credential.py", line 42, in <module>
dev = next(CtapHidDevice.list_devices(), None)
File "/home/pj/src/solo/venv/lib/python3.6/site-packages/fido2-0.3.1.dev0-py3.6.egg/fido2/hid.py", line 140, in list_devices
yield cls(d, hidtransport.UsbHidTransport(dev))
File "/home/pj/src/solo/venv/lib/python3.6/site-packages/fido2-0.3.1.dev0-py3.6.egg/fido2/_pyu2f/hidtransport.py", line 215, in __init__
self.InternalInit()
File "/home/pj/src/solo/venv/lib/python3.6/site-packages/fido2-0.3.1.dev0-py3.6.egg/fido2/_pyu2f/hidtransport.py", line 235, in InternalInit
r = self.InternalExchange(UsbHidTransport.U2FHID_INIT, nonce)
File "/home/pj/src/solo/venv/lib/python3.6/site-packages/fido2-0.3.1.dev0-py3.6.egg/fido2/_pyu2f/hidtransport.py", line 254, in InternalExchange
ret_cmd, ret_payload = self.InternalRecv()
File "/home/pj/src/solo/venv/lib/python3.6/site-packages/fido2-0.3.1.dev0-py3.6.egg/fido2/_pyu2f/hidtransport.py", line 308, in InternalRecv
first_read = self.InternalReadFrame()
File "/home/pj/src/solo/venv/lib/python3.6/site-packages/fido2-0.3.1.dev0-py3.6.egg/fido2/_pyu2f/hidtransport.py", line 300, in InternalReadFrame
frame = self.hid_device.Read()
File "/home/pj/src/solo/venv/lib/python3.6/site-packages/fido2-0.3.1.dev0-py3.6.egg/fido2/_pyu2f/test.py", line 40, in Read
msg[i] = ord(v)
TypeError: ord() expected string of length 1, but int found
This is built and running on ubuntu18.04.
Hi!
Do you have any reproducible environment (e.g. Docker image, Vagrant VM etc.), where one could build firmware and compare with the binary released on site? If not, could you describe the build environment?
As far as I understand, Solokey is licensed as GPLv3. At the same time (non-hacker) Solokeys can only be updated with signed firmwares but not with user-modified firmware. This restriction violates users' freedom which GPLv3 aims to guarantee. See Tivoization.
https://github.com/SoloKeysSec/solo#how-do-i-get-one is therefore out of date meaning https://solokeys.com/preorder/ is the only way to buy one now
Docs need an update :)
Following Building
make cbor:
make -f application.mk -j8 cbor
make[1]: Entering directory '/Users/$foo/Documents/GitHub/solo/targets/stm32l442'
cd ../../tinycbor/ && make clean
make[2]: Entering directory '/Users/$foo/Documents/GitHub/solo/tinycbor'
make[2]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
Makefile:95: warning: funopen and fopencookie unavailable, open_memstream can not be implemented and conversion to JSON will not work properly!
rm -f src/cborerrorstrings.o src/cborencoder.o src/cborencoder_close_container_checked.o src/cborparser.o src/cborpretty.o src/cborparser_dup_string.o src/cborpretty_stdio.o src/cbortojson.o src/cborvalidation.o
rm -f src/cborerrorstrings.pic.o src/cborencoder.pic.o src/cborencoder_close_container_checked.pic.o src/cborparser.pic.o src/cborpretty.pic.o src/cborparser_dup_string.pic.o src/cborpretty_stdio.pic.o src/cbortojson.pic.o src/cborvalidation.pic.o
rm -f tools/cbordump/cbordump.o
rm -f bin/cbordump
rm -f bin/json2cbor
rm -f lib/libtinycbor.a
rm -f lib/libtinycbor-freestanding.a
rm -f tinycbor.pc
rm -f lib/libtinycbor.so*
test -e tests/Makefile && make -C tests clean || :
make[2]: Leaving directory '/Users/$foo/Documents/GitHub/solo/tinycbor'
cd ../../tinycbor/ && make CC="arm-none-eabi-gcc" AR=arm-none-eabi-ar \
LDFLAGS="-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -L../../tinycbor/lib -specs=nano.specs -specs=nosys.specs -Wl,--gc-sections -u _printf_float -lnosys" \
CFLAGS="-Isrc/ -Isrc/cmsis/ -Ilib/ -Ilib/usbd/ -I../../fido2/ -I../../fido2/extensions -I../../tinycbor/src -I../../crypto/sha256 -I../../crypto/micro-ecc -I../../crypto/tiny-AES-c -c -DDEBUG_LEVEL=0 -DSTM32L442xx -DAES256=1 -DUSE_FULL_LL_DRIVER -DAPP_CONFIG=\"app.h\" -Wall -fdata-sections -ffunction-sections -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -g"
make[2]: Entering directory '/Users/$foo/Documents/GitHub/solo/tinycbor'
make[2]: warning: jobserver unavailable: using -j1. Add '+' to parent make rule.
Makefile:95: warning: funopen and fopencookie unavailable, open_memstream can not be implemented and conversion to JSON will not work properly!
arm-none-eabi-gcc -D_FORTIFY_SOURCE=2 -mmacosx-version-min=10.9 -I./src -std=gnu99 -Isrc/ -Isrc/cmsis/ -Ilib/ -Ilib/usbd/ -I../../fido2/ -I../../fido2/extensions -I../../tinycbor/src -I../../crypto/sha256 -I../../crypto/micro-ecc -I../../crypto/tiny-AES-c -c -DDEBUG_LEVEL=0 -DSTM32L442xx -DAES256=1 -DUSE_FULL_LL_DRIVER -DAPP_CONFIG="app.h" -Wall -fdata-sections -ffunction-sections -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -g -c -o src/cborerrorstrings.o src/cborerrorstrings.c
arm-none-eabi-gcc: error: unrecognized command line option '-mmacosx-version-min=10.9'
make[2]: *** [Makefile:223: src/cborerrorstrings.o] Error 1
make[2]: Leaving directory '/Users/$foo/Documents/GitHub/solo/tinycbor'
make[1]: *** [application.mk:82: cbor] Error 2
make[1]: Leaving directory '/Users/$foo/Documents/GitHub/solo/targets/stm32l442'
make: *** [Makefile:58: cbor] Error 2
arm-none-eabi-gcc --version:
arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Actual MacOS version: 10.14.2
Error message:
arm-none-eabi-gcc: error: unrecognized command line option '-mmacosx-version-min=10.9'
Is it possible to make sure that any write operation to firmware - ALWAYS resets the key (so any private key on the stick is gone) ?
If so - an "updateable" version - where if you update, your private key is lost (and you can re-load it, from backup on f.ex. a LUKS encrypted usb stick or whereever) - so you can firmware upgrade your stick (yes with the hassle of reloading gpg key from backup) - but atleast its possible.. Keeping the spirit of Open Source IMHO.. The freedom to tinker - without it being insane unsecure as the current hacker edition - where anyone who gets hold of the key, can modify firmware and get your gpg key :(
Anyone with an "hacker updatateable key" - should then always ensure to upload new firmware if they insert gpg key on stick.. so they KNOW what the stick is running.
Somewhat overlaps with #6 but a port doesn't necessarily implement all the security features of platform.
I had to add the following udev rule to get the Solo key to be recognized on Linux:
/etc/udev/rules.d/70-solo_key.rules
:
# Solo
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess"
At the moment, the SoloKey will enter a "Breathing" mode with it's green LED when it's plugged in an powered, ie, the LED dims off and on continuously.
While in most scenarios this is fine, I would like it if I could somehow disable this behaviour and have the LED be in a static mode as this animation can be a bit distracting if the environment is dark.
I try to compile solo firmware for STM32L442 (under target/stm32l442):
cd targets/stm32l442
make all
But I got error:
arm-none-eabi-gcc src/main.o src/init.o src/redirect.o src/flash.o src/rng.o src/led.o src/device.o src/fifo.o src/crypto.o src/attestation.o src/startup_stm32l432xx.o src/system_stm32l4xx.o lib/stm32l4xx_ll_rng.o lib/stm32l4xx_ll_gpio.o lib/stm32l4xx_hal_pcd.o lib/stm32l4xx_ll_usb.o lib/stm32l4xx_hal_pcd_ex.o lib/stm32l4xx_ll_pwr.o lib/stm32l4xx_ll_rcc.o lib/stm32l4xx_ll_tim.o lib/stm32l4xx_ll_usart.o lib/stm32l4xx_ll_utils.o lib/usbd/usbd_conf.o lib/usbd/usbd_core.o lib/usbd/usbd_ioreq.o lib/usbd/usbd_hid.o lib/usbd/usbd_desc.o lib/usbd/usbd_ctlreq.o ../../fido2/util.o ../../fido2/u2f.o ../../fido2/test_power.o ../../fido2/stubs.o ../../fido2/log.o ../../fido2/ctaphid.o ../../fido2/ctap.o ../../fido2/ctap_parse.o ../../fido2/main.o ../../crypto/sha256/sha256.o ../../crypto/micro-ecc/uECC.o ../../crypto/tiny-AES-c/aes.o -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -L../../tinycbor/lib -specs=nano.specs -specs=nosys.specs -Wl,--gc-sections -u _printf_float -lnosys -Tstm32l432xx.ld -Wl,-Map=solo.map,--cref -ltinycbor -o solo.elf
../../tinycbor/lib/libtinycbor.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
Makefile:65: recipe for target 'solo.elf' failed
make: *** [solo.elf] Error 1
I run command:
$ file ../../tinycbor/lib/libtinycbor.so
../../tinycbor/lib/libtinycbor.so: symbolic link to libtinycbor.so.0.5.2
$ file ../../tinycbor/lib/libtinycbor.so.0.5.2
../../tinycbor/lib/libtinycbor.so.0.5.2: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f5aa03f58f991617c6660428203c593d1b3883d7, not strippedv
It mean libtinycbor.so.0.5.2 is builded for 64bit machine, not for STM32L442
Please guide me how to compiler this firmware.
Thanks
as already discussed in #67 the GPLv3 does not allow for tiviozation. at the same time Solo needs to be able to distribute signed firmware to most users for security.
therefore Solo is forced to use workarounds in the form of CLAs to assign rights of contributors back to Solo to use however Solo wants to allow signed firmware thereby circumventing the GPLv3.
I think a better way implement this would be to licence under the GPLv2 which is a proper open source licence, but does not explicitly prevent tiviozation which in this case is good, as it allows Solo to distribute signed firmware. This is the path the linux kernel takes, and allows it to be used in secure boot applications.
this has the advantages that contributors are not required to licence their work separately to Solo rather their work remains fully under an FOSS licence, and will will streamline the contribution process.
Opening a ticket as marker that we can improve on what @pjz's #17 started.
Good read: https://jamesmunns.com/blog/hardware-ci-overview
I started work on compiling the firmware on Linux, documented in https://solo.solokeys.io/building.
We need a dual Win/Linux compilation story (plus, the firmware gets stuck on the Nucleo 😜).
I don't have much experience with this but it would be nice to run some static/dynamic analysis security tools on the code base.
Here's a good way to solve the u2f-backup-token problem.
He even forked and patched the u2f-zero repo. So, once there's a PR, it would be easy to expand u2f-zero/solo usefulness.
RFC.
cheers
Documentation can always be improved, at least need the following:
On https://solokeys.com/en/start/ page there is:
1. Visit https://myaccount.google.com and click on Signing in to Google.
2. Click on 2-Step Verification to start the registration process.
I'm not sure if it's just me, or if Google updated it everywhere, but i see a menu on the left side of the "my account" page, and various blocks on right/main side. None of them is "Signing in to Google".
Only after i click on "Security" menu item, i can see "Signing in to Google" section/block (2nd one, after "We keep your account protected" section), which contains "2-Step Verification" link. After clicking it, i see a page with various 2nd steps, one of which is "Security Key" with "Add security key" link.
I know: not much of a difference, especially for, i assume, more "techie" audience of Solo keys at the moment. Still, maybe some "regular" folks will want to try it too :).
https://solokeys.com/en/start/ mentions you can use Solo with Google. However, the 2FA security key page doesn't seem to work.
A Webauthn test page and GitHub work with Solo no issue though, so at the very least, it seems I have the browser support good to go.
Using Firefox 64.0.2 on Fedora Workstation 29. I haven't tested with Chrome, but will give it a try at some point and update how that works.
I am new to Solo! I am trying to build the firmware for the first time following the instructions on Solo's "Build instructions" page. After some effort (installing several Python packages), I am close to the build process. The "make cbor" command works. The "make build-hacker" command fails near the end. Following is the error I am encountering:
arm-none-eabi-objcopy -O ihex solo.elf solo.hex
python ../../tools/solotool.py mergehex solo.hex bootloader.hex all.hex
('merging solo.hex with ', 'bootloader.hex')
Traceback (most recent call last):
File "../../tools/solotool.py", line 996, in
main_mergehex()
File "../../tools/solotool.py", line 952, in main_mergehex
first.tofile(args[len(args) - 1], format='hex')
File "/Library/Python/2.7/site-packages/intelhex/init.py", line 719, in tofile
self.write_hex_file(fobj)
File "/Library/Python/2.7/site-packages/intelhex/init.py", line 685, in write_hex_file
bin[4+i] = self._buf[cur_addr+i]
TypeError: an integer is required
make: *** [build-hacker] Error 1
I will appreciate any help that can be provided to resolve this issue.
Planned languages for the project are C/Assembler/Rust2018 (for firmware) and Python (3.6+, for scripting).
Rust has rustfmt
, C is a... mess, but Python now has black.
Is there any opposition to using (i.e. enforcing) it? Should we allow --skip-string-normalization
?
Issue will be closed if it devolves into too much bikeshedding 😁
When I run "./main", I get some problems:
state file exists [STOR] Auth state is initialized [STOR] pin not set.
I want to know how to solve this problem. Thank you.
Is https://github.com/SoloKeysSec/solo/blob/master/fido2/ctaphid.c#L519 missing a break? I found it by playing with -Wextra, but am not sure enough of the design to be able to tell.
https://solokeys.com/preorder/购买了solo tap。网页只给了我一个订单号,我一直没有收到确认邮件。
Your order number is #103094185. You'll receive an e-mail confirmation shortly for your records.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.