Compare commits

...

14 Commits

Author SHA1 Message Date
f74dba7ff0 enforce ascending writes in bootloader update 2020-02-06 13:05:57 -05:00
794accf3dc Added how to setup Manjaro 18.x.
Added Manjaro setup for passwordless and second factor login to
documentation of applcation ideas. Also did some text formating.
2020-02-06 12:47:36 -05:00
2ca0ced808 Update programming.md 2020-01-22 12:41:39 -05:00
17b430fd44 Remove stale python-fido2 dependency 2020-01-16 10:35:22 +01:00
0d4197fb2c Merge pull request #356 from jnaulty/jnaulty/no-root-artifacts
Use current user at build container runtime
2020-01-15 21:17:53 +01:00
f74a77d80b Use current user at build container runtime
Using the current user id and group removes the need to use `sudo` when
cleaning up build artifacts from the docker build stage.

Issue: #355
2020-01-06 01:55:47 -08:00
5f1d61a3ba bump 2019-12-01 18:25:45 -05:00
46f2920e63 bugfix hid cancel 2019-12-01 18:09:08 -05:00
53427c4279 update metadata statements 2019-12-01 18:09:08 -05:00
ac10933379 pin fido2 dependency 2019-12-01 18:09:08 -05:00
8a44d14fef adjust default impl 2019-12-01 18:09:08 -05:00
1d59bbfdd4 support different aaguid's in cert for different solo models 2019-12-01 18:09:08 -05:00
54c66d80b6 overwrite x509 fields for tap or somu 2019-12-01 18:09:08 -05:00
6217fc34b9 update solo_cert to include aaguid field 2019-12-01 18:09:08 -05:00
18 changed files with 282 additions and 72 deletions

View File

@ -103,6 +103,7 @@ uncached-docker-build-toolchain:
docker-build-all:
docker run --rm -v "$(CURDIR)/builds:/builds" \
-v "$(CURDIR):/solo" \
-u $(shell id -u ${USER}):$(shell id -g ${USER}) \
$(DOCKER_TOOLCHAIN_IMAGE) "solo/in-docker-build.sh" ${SOLO_VERSION_FULL}
CPPCHECK_FLAGS=--quiet --error-exitcode=2

View File

@ -1 +1 @@
3.0.0
3.0.1

View File

@ -1,16 +1,23 @@
# Using Solo for passwordless or second factor login on Linux
## Setup on Ubuntu 18.04
## Setup on Ubuntu and Manjaro
Before you can use Solo for passwordless or second factor login in your Linux system you have to install some packages.
This was tested under **Linux Mint 19.2**.
This was tested on **Linux Mint 19.3** and on **Manjaro 18.x**
First you have to install PAM modules for u2f.
**Ubuntu (Linux Mint):**
```
sudo apt install libpam-u2f pamu2fcfg
```
**Manjaro**
```
pacman -Syu pam-u2f
```
## Setting up key
To use Solo as passwordless or second factor login, you have to setup your system with your Solo.
First create a new folder named **Yubico** in your **.config** folder in your **home** directory
@ -28,35 +35,57 @@ If you want to register an additional key use this command instead:
pamu2fcfg >> ~/.config/Yubico/u2f_keys
```
Now press the button on your Solo.
<br>
<br>
If you can't generate your key (error message), you may add Yubico Team from PPA and install latest libpam-u2f and pamu2fcfg and try again.
If you can't generate your key on **Ubuntu** (error message), you may add Yubico Team from PPA and install latest libpam-u2f and pamu2fcfg and try again.
```
sudo add-apt-repository ppa:yubico/stable
sudo apt-get update
sudo apt-get upgrade
```
**Manjaro** should work without problems.
## Login into Linux
### Passwordless
To login passwordless into your Linux system, you have to edit the file **lightdm** (or **gdm** or which display manager you prefered).
In case of lightdm:
In case of lightdm and VIM as editor:
```
sudo vim /etc/pam.d/lightdm
sudo vim /etc/pam.d/lightdm
```
Now search following entry:
**On Ubuntu:**<br>
Search following entry:
```
@include common-auth
@include common-auth
```
and add
```
auth sufficient pam_u2f.so
auth sufficient pam_u2f.so
```
**before** @include common-auth.
**before** *@include common-auth.*
<br>
<br>
Save the file and test it.<br>
**On Manjaro**<br>
Search following enrty
```
auth include system-login
```
and add
```
auth sufficient pam_u2f.so
```
** before** *auth include system-login*.
<br>
<br>
Now save the file and test it.<br>
Insert Solo in your USB port and logout.
Now you should be able to login into Linux without password, only with pressing your button on Solo and press enter.
@ -65,7 +94,7 @@ Why **sufficient**? The difference between the keyword sufficient and required i
The login mechanism can be also used for additional features like:
: - Login after screen timeout - edit /etc/pam.d/mate-screensaver (or kde-screensaver, ...)
- Login after screen timeout - edit /etc/pam.d/mate-screensaver (or kde-screensaver, ...)
- Passwordless sudo - edit /etc/pam.d/sudo
Check out your folder **/etc/pam.d/** and do some experiments.
@ -78,17 +107,36 @@ The login passwordless won't make your system more secure, but maybe more comfor
To use Solo as second factor, for login into your Linux system, is nearly the same.
```
sudo vim /etc/pam.d/lightdm
sudo vim /etc/pam.d/lightdm
```
Now search following entry:
**On Ubuntu**<br>
Search following entry:
```
@include common-auth
@include common-auth
```
and add
```
auth required pam_u2f.so
auth required pam_u2f.so
```
**after** @include common-auth.
**after** *@include common-auth*.
<br>
<br>
**On Manjaro**<br>
Search following entry:
```
auth include system-login
```
Add following entry
```
auth required pam_u2f.so
```
**after** *auth include system-login*.
<br>
<br>
Save the file and test it. <br>
In case your Solo is not present, your password will be incrorrect. If Solo is plugged into your USB port, it will signal pressing the button and you will be able to login into Linux.

View File

@ -36,9 +36,13 @@ 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
a build that you made yourself.
You need to use a firmware file that has the combined bootloader and application (or at the very least just the bootloader).
This means using the `bundle-*.hex` file or the `bundle.hex` from your build. If you overwrite the Solo flash with a missing bootloader,
it will be bricked.
You need to use a firmware file that has the combined bootloader, application, and attestation key pair (bootloader + firmware + key).
This means using the `bundle-*.hex` file or the `bundle.hex` from your build.
#### *Warning*
* **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`

View File

@ -69,6 +69,8 @@ uint8_t ctap_get_info(CborEncoder * encoder)
CborEncoder map;
CborEncoder options;
CborEncoder pins;
uint8_t aaguid[16];
device_read_aaguid(aaguid);
ret = cbor_encoder_create_map(encoder, &map, 6);
check_ret(ret);
@ -105,7 +107,7 @@ uint8_t ctap_get_info(CborEncoder * encoder)
ret = cbor_encode_uint(&map, RESP_aaguid);
check_ret(ret);
{
ret = cbor_encode_byte_string(&map, CTAP_AAGUID, 16);
ret = cbor_encode_byte_string(&map, aaguid, 16);
check_ret(ret);
}
@ -505,7 +507,7 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
cbor_encoder_init(&cose_key, cose_key_buf, *len - sizeof(CTAP_authData), 0);
memmove(authData->attest.aaguid, CTAP_AAGUID, 16);
device_read_aaguid(authData->attest.aaguid);
authData->attest.credLenL = sizeof(CredentialId) & 0x00FF;
authData->attest.credLenH = (sizeof(CredentialId) & 0xFF00) >> 8;
@ -630,11 +632,17 @@ int ctap_calculate_signature(uint8_t * data, int datalen, uint8_t * clientDataHa
uint8_t ctap_add_attest_statement(CborEncoder * map, uint8_t * sigder, int len)
{
int ret;
uint8_t cert[1024];
uint16_t cert_size = device_attestation_cert_der_get_size();
if (cert_size > sizeof(cert)){
printf2(TAG_ERR,"Certificate is too large for CTAP2 buffer\r\n");
return CTAP2_ERR_PROCESSING;
}
device_attestation_read_cert_der(cert);
CborEncoder stmtmap;
CborEncoder x5carr;
ret = cbor_encode_int(map,RESP_attStmt);
check_ret(ret);
ret = cbor_encoder_create_map(map, &stmtmap, 3);
@ -657,7 +665,7 @@ uint8_t ctap_add_attest_statement(CborEncoder * map, uint8_t * sigder, int len)
ret = cbor_encoder_create_array(&stmtmap, &x5carr, 1);
check_ret(ret);
{
ret = cbor_encode_byte_string(&x5carr, attestation_cert_der, device_attestation_cert_der_get_size());
ret = cbor_encode_byte_string(&x5carr, cert, device_attestation_cert_der_get_size());
check_ret(ret);
ret = cbor_encoder_close_container(&stmtmap, &x5carr);
check_ret(ret);

View File

@ -19,9 +19,6 @@
#define CTAP_VENDOR_FIRST 0x40
#define CTAP_VENDOR_LAST 0xBF
// AAGUID For Solo
#define CTAP_AAGUID ((uint8_t*)"\x88\x76\x63\x1b\xd4\xa0\x42\x7f\x57\x73\x0e\xc7\x1c\x9e\x02\x79")
#define MC_clientDataHash 0x01
#define MC_rp 0x02
#define MC_user 0x03

View File

@ -635,6 +635,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
status = ctap_request(ctap_buffer, len, &ctap_resp);
wb.bcnt = (ctap_resp.length+1);
wb.cid = cid;
wb.cmd = cmd;
timestamp();
@ -665,6 +668,9 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
u2f_request((struct u2f_request_apdu*)ctap_buffer, &ctap_resp);
wb.bcnt = (ctap_resp.length);
wb.cid = cid;
wb.cmd = cmd;
ctaphid_write(&wb, ctap_resp.data, ctap_resp.length);
ctaphid_write(&wb, NULL, 0);

View File

@ -59,7 +59,10 @@ static uint8_t _attestation_cert_der[] =
"\x06\xf1\xe3\xab\x16\x21\x8e\xd8\xc0\x14\xaf\x09\x4f\x5b\x73\xef\x5e\x9e\x4b\xe7"
"\x35\xeb\xdd\x9b\x6d\x8f\x7d\xf3\xc4\x3a\xd7";
__attribute__((weak)) const uint8_t * attestation_cert_der = _attestation_cert_der;
__attribute__((weak)) void device_attestation_read_cert_der(uint8_t * dst){
memmove(dst, _attestation_cert_der, device_attestation_cert_der_get_size());
}
__attribute__((weak)) uint8_t * device_get_attestation_key(){
static uint8_t attestation_key[] =
@ -199,3 +202,8 @@ __attribute__((weak)) void ctap_overwrite_rk(int index, CTAP_residentKey * rk)
}
}
__attribute__((weak)) void device_read_aaguid(uint8_t * dst){
uint8_t * aaguid = (uint8_t *)"\x00\x76\x63\x1b\xd4\xa0\x42\x7f\x57\x73\x0e\xc7\x1c\x9e\x02\x79";
memmove(dst, aaguid, 16);
}

View File

@ -199,13 +199,21 @@ int device_is_nfc();
*/
uint8_t * device_get_attestation_key();
/** Pointer to a ASN.1/DER encoded byte array of the attestation certificate.
/** Read the device's attestation certificate into buffer @dst.
* @param dst the destination to write the certificate.
*
* The size of the certificate can be retrieved using `device_attestation_cert_der_get_size()`.
*/
extern const uint8_t * attestation_cert_der;
void device_attestation_read_cert_der(uint8_t * dst);
/** Returns the size in bytes of attestation_cert_der.
* @return number of bytes in attestation_cert_der, not including any C string null byte.
*/
uint16_t device_attestation_cert_der_get_size();
/** Read the device's 16 byte AAGUID into a buffer.
* @param dst buffer to write 16 byte AAGUID into.
* */
void device_read_aaguid(uint8_t * dst);
#endif

View File

@ -299,7 +299,7 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
static int16_t u2f_register(struct u2f_register_request * req)
{
uint8_t i[] = {0x0,U2F_EC_FMT_UNCOMPRESSED};
uint8_t cert[1024];
struct u2f_key_handle key_handle;
uint8_t pubkey[64];
uint8_t hash[32];
@ -308,6 +308,11 @@ static int16_t u2f_register(struct u2f_register_request * req)
const uint16_t attest_size = device_attestation_cert_der_get_size();
if (attest_size > sizeof(cert)){
printf2(TAG_ERR,"Certificate is too large for buffer\r\n");
return U2F_SW_INSUFFICIENT_MEMORY;
}
if ( ! ctap_user_presence_test(750))
{
return U2F_SW_CONDITIONS_NOT_SATISFIED;
@ -341,7 +346,8 @@ static int16_t u2f_register(struct u2f_register_request * req)
u2f_response_writeback(i,1);
u2f_response_writeback((uint8_t*)&key_handle,U2F_KEY_HANDLE_SIZE);
u2f_response_writeback(attestation_cert_der,attest_size);
device_attestation_read_cert_der(cert);
u2f_response_writeback(cert,attest_size);
dump_signature_der(sig);

View File

@ -15,8 +15,7 @@
"authenticationAlgorithm": 1,
"publicKeyAlgAndEncoding": 260,
"attestationTypes": [
15879,
15880
15879
],
"userVerificationDetails": [
[

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -50,12 +50,15 @@ typedef struct {
uint8_t payload[255 - 10];
} __attribute__((packed)) BootloaderReq;
uint8_t * last_written_app_address;
/**
* Erase all application pages. **APPLICATION_END_PAGE excluded**.
*/
static void erase_application()
{
int page;
last_written_app_address = (uint8_t*) APPLICATION_START_ADDR;
for(page = APPLICATION_START_PAGE; page < APPLICATION_END_PAGE; page++)
{
flash_erase_page(page);
@ -106,7 +109,6 @@ int is_bootloader_disabled()
uint32_t * auth = (uint32_t *)(AUTH_WORD_ADDR+4);
return *auth == 0;
}
uint8_t * last_written_app_address;
#include "version.h"
bool is_firmware_version_newer_or_equal()
@ -116,7 +118,7 @@ bool is_firmware_version_newer_or_equal()
current_firmware_version.major, current_firmware_version.minor, current_firmware_version.patch, current_firmware_version.reserved,
current_firmware_version.major, current_firmware_version.minor, current_firmware_version.patch, current_firmware_version.reserved
);
volatile version_t * new_version = ((volatile version_t *) last_written_app_address);
volatile version_t * new_version = ((volatile version_t *) (last_written_app_address-8+4));
printf1(TAG_BOOT,"Uploaded firmware version: %u.%u.%u.%u (%02x.%02x.%02x.%02x)\r\n",
new_version->major, new_version->minor, new_version->patch, new_version->reserved,
new_version->major, new_version->minor, new_version->patch, new_version->reserved
@ -170,6 +172,7 @@ int bootloader_bridge(int klen, uint8_t * keyh)
uint32_t addr = ((*((uint32_t*)req->addr)) & 0xffffff) | 0x8000000;
uint32_t * ptr = (uint32_t *)addr;
uint32_t current_address;
switch(req->op){
case BootWrite:
@ -196,9 +199,16 @@ int bootloader_bridge(int klen, uint8_t * keyh)
printf2(TAG_ERR, "Error, boot check bypassed\n");
exit(1);
}
current_address = addr + len;
if (current_address < (uint32_t) last_written_app_address) {
printf2(TAG_ERR, "Error, only ascending writes allowed.\n");
has_erased = 0;
return CTAP2_ERR_NOT_ALLOWED;
}
last_written_app_address = (uint8_t*) current_address;
// Do the actual write
flash_write((uint32_t)ptr,req->payload, len);
last_written_app_address = (uint8_t *)ptr + len - 8 + 4;
break;
case BootDone:
// Writing to flash finished. Request code validation.

View File

@ -5,12 +5,16 @@
// http://opensource.org/licenses/MIT>, at your option. This file may not be
// copied, modified, or distributed except according to those terms.
#include <stdint.h>
#include <string.h>
#include "crypto.h"
#include "memory_layout.h"
#include "device.h"
#include "sense.h"
#include "log.h"
const uint8_t attestation_solo_cert_der[] =
"\x30\x82\x02\xe1\x30\x82\x02\x88\xa0\x03\x02\x01\x02\x02\x01\x01\x30\x0a\x06\x08"
"\x30\x82\x03\x03\x30\x82\x02\xaa\xa0\x03\x02\x01\x02\x02\x01\x01\x30\x0a\x06\x08"
"\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x81\x80\x31\x0b\x30\x09\x06\x03\x55\x04\x06"
"\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4d\x61\x72\x79\x6c"
"\x61\x6e\x64\x31\x12\x30\x10\x06\x03\x55\x04\x0a\x0c\x09\x53\x6f\x6c\x6f\x20\x4b"
@ -18,36 +22,37 @@ const uint8_t attestation_solo_cert_der[] =
"\x41\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0c\x0c\x73\x6f\x6c\x6f\x6b\x65\x79\x73"
"\x2e\x63\x6f\x6d\x31\x21\x30\x1f\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01\x16"
"\x12\x68\x65\x6c\x6c\x6f\x40\x73\x6f\x6c\x6f\x6b\x65\x79\x73\x2e\x63\x6f\x6d\x30"
"\x20\x17\x0d\x31\x38\x31\x31\x31\x31\x31\x32\x35\x32\x30\x30\x5a\x18\x0f\x32\x30"
"\x36\x38\x31\x30\x32\x39\x31\x32\x35\x32\x30\x30\x5a\x30\x81\x92\x31\x0b\x30\x09"
"\x20\x17\x0d\x31\x39\x31\x32\x30\x31\x31\x39\x32\x33\x34\x39\x5a\x18\x0f\x32\x30"
"\x36\x39\x31\x31\x31\x38\x31\x39\x32\x33\x34\x39\x5a\x30\x81\x91\x31\x0b\x30\x09"
"\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08"
"\x4d\x61\x72\x79\x6c\x61\x6e\x64\x31\x12\x30\x10\x06\x03\x55\x04\x0a\x0c\x09\x53"
"\x6f\x6c\x6f\x20\x4b\x65\x79\x73\x31\x22\x30\x20\x06\x03\x55\x04\x0b\x0c\x19\x41"
"\x75\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72\x20\x41\x74\x74\x65\x73\x74\x61"
"\x74\x69\x6f\x6e\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0c\x0c\x73\x6f\x6c\x6f\x6b"
"\x65\x79\x73\x2e\x63\x6f\x6d\x31\x21\x30\x1f\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01"
"\x09\x01\x16\x12\x68\x65\x6c\x6c\x6f\x40\x73\x6f\x6c\x6f\x6b\x65\x79\x73\x2e\x63"
"\x6f\x6d\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48"
"\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x22\xfe\x0f\xb5\x2a\x78\xbe\xc6\x45\x37\x1a"
"\x28\xa7\x57\x43\x49\xa4\x6f\x85\x4d\xca\x4e\x25\x1c\x9f\x75\x30\x3d\xbf\x10\xd5"
"\xd2\xd2\x0b\xb9\x69\x2c\xdd\xb2\x5c\x14\xd8\x39\x85\x12\xf6\x23\xee\x91\xba\xc6"
"\xac\xff\x4a\x1a\x27\xef\xe0\xc1\x54\x3f\xd4\xd9\xc5\xa3\x81\xdc\x30\x81\xd9\x30"
"\x1d\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x3b\xe6\xd2\xc0\x6f\xf2\xe7\xb0\x7c\x9d"
"\x9e\x28\xc0\x20\xb0\x0d\x07\xc8\x15\xc8\x30\x81\x9f\x06\x03\x55\x1d\x23\x04\x81"
"\x97\x30\x81\x94\xa1\x81\x86\xa4\x81\x83\x30\x81\x80\x31\x0b\x30\x09\x06\x03\x55"
"\x04\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4d\x61\x72"
"\x79\x6c\x61\x6e\x64\x31\x12\x30\x10\x06\x03\x55\x04\x0a\x0c\x09\x53\x6f\x6c\x6f"
"\x20\x4b\x65\x79\x73\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x52\x6f\x6f\x74"
"\x20\x43\x41\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0c\x0c\x73\x6f\x6c\x6f\x6b\x65"
"\x4d\x61\x72\x79\x6c\x61\x6e\x64\x31\x11\x30\x0f\x06\x03\x55\x04\x0a\x0c\x08\x53"
"\x6f\x6c\x6f\x4b\x65\x79\x73\x31\x22\x30\x20\x06\x03\x55\x04\x0b\x0c\x19\x41\x75"
"\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72\x20\x41\x74\x74\x65\x73\x74\x61\x74"
"\x69\x6f\x6e\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0c\x0c\x73\x6f\x6c\x6f\x6b\x65"
"\x79\x73\x2e\x63\x6f\x6d\x31\x21\x30\x1f\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09"
"\x01\x16\x12\x68\x65\x6c\x6c\x6f\x40\x73\x6f\x6c\x6f\x6b\x65\x79\x73\x2e\x63\x6f"
"\x6d\x82\x09\x00\xc4\x47\x63\x92\x8f\xf4\xbe\x8c\x30\x09\x06\x03\x55\x1d\x13\x04"
"\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04\x04\x03\x02\x04\xf0\x30\x0a\x06\x08"
"\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x47\x00\x30\x44\x02\x20\x71\x10\x46\x2c\xf5"
"\x16\x18\x97\x55\xca\x64\x50\x3b\x69\xb2\xdf\x17\x71\xab\xad\x8e\xc0\xd6\xa6\x07"
"\x3d\x66\x8a\x3b\xbb\xfe\x61\x02\x20\x1e\x82\xef\xeb\x5e\x4e\x3a\x00\x84\x64\xd2"
"\xf8\x84\xc3\x78\x35\x93\x63\x81\x2e\xbe\xa6\x12\x32\x6e\x29\x90\xc8\x91\x4b\x71"
"\x52"
"\x6d\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce"
"\x3d\x03\x01\x07\x03\x42\x00\x04\x22\xfe\x0f\xb5\x2a\x78\xbe\xc6\x45\x37\x1a\x28"
"\xa7\x57\x43\x49\xa4\x6f\x85\x4d\xca\x4e\x25\x1c\x9f\x75\x30\x3d\xbf\x10\xd5\xd2"
"\xd2\x0b\xb9\x69\x2c\xdd\xb2\x5c\x14\xd8\x39\x85\x12\xf6\x23\xee\x91\xba\xc6\xac"
"\xff\x4a\x1a\x27\xef\xe0\xc1\x54\x3f\xd4\xd9\xc5\xa3\x81\xff\x30\x81\xfc\x30\x1d"
"\x06\x03\x55\x1d\x0e\x04\x16\x04\x14\x3b\xe6\xd2\xc0\x6f\xf2\xe7\xb0\x7c\x9d\x9e"
"\x28\xc0\x20\xb0\x0d\x07\xc8\x15\xc8\x30\x81\x9f\x06\x03\x55\x1d\x23\x04\x81\x97"
"\x30\x81\x94\xa1\x81\x86\xa4\x81\x83\x30\x81\x80\x31\x0b\x30\x09\x06\x03\x55\x04"
"\x06\x13\x02\x55\x53\x31\x11\x30\x0f\x06\x03\x55\x04\x08\x0c\x08\x4d\x61\x72\x79"
"\x6c\x61\x6e\x64\x31\x12\x30\x10\x06\x03\x55\x04\x0a\x0c\x09\x53\x6f\x6c\x6f\x20"
"\x4b\x65\x79\x73\x31\x10\x30\x0e\x06\x03\x55\x04\x0b\x0c\x07\x52\x6f\x6f\x74\x20"
"\x43\x41\x31\x15\x30\x13\x06\x03\x55\x04\x03\x0c\x0c\x73\x6f\x6c\x6f\x6b\x65\x79"
"\x73\x2e\x63\x6f\x6d\x31\x21\x30\x1f\x06\x09\x2a\x86\x48\x86\xf7\x0d\x01\x09\x01"
"\x16\x12\x68\x65\x6c\x6c\x6f\x40\x73\x6f\x6c\x6f\x6b\x65\x79\x73\x2e\x63\x6f\x6d"
"\x82\x09\x00\xc4\x47\x63\x92\x8f\xf4\xbe\x8c\x30\x09\x06\x03\x55\x1d\x13\x04\x02"
"\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04\x04\x03\x02\x04\xf0\x30\x21\x06\x0b\x2b"
"\x06\x01\x04\x01\x82\xe5\x1c\x01\x01\x04\x04\x12\x04\x10\x88\x76\x63\x1b\xd4\xa0"
"\x42\x7f\x57\x73\x0e\xc7\x1c\x9e\x02\x79\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04"
"\x03\x02\x03\x47\x00\x30\x44\x02\x20\x4d\xea\x09\x15\x6c\x86\x48\x57\x2a\xa8\x8d"
"\x87\xc3\xfa\xb6\x6b\x29\x9b\xfb\x8b\x4d\x4d\x29\x77\x5b\xa1\x04\x4c\x7f\x12\x8d"
"\x71\x02\x20\x47\x4c\x3d\xb2\xa1\x74\xe3\x9c\xfe\xe1\x23\xbf\xec\x47\x96\xf4\xe5"
"\x9b\x65\x76\xac\xc8\x69\x1d\xe2\x74\xff\x4e\xa4\xcf\x02\x6d"
;
const uint8_t attestation_hacker_cert_der[] =
@ -95,7 +100,6 @@ const uint8_t attestation_hacker_cert_der[] =
const uint16_t attestation_solo_cert_der_size = sizeof(attestation_solo_cert_der)-1;
const uint16_t attestation_hacker_cert_der_size = sizeof(attestation_hacker_cert_der)-1;
const uint8_t * attestation_cert_der = ((flash_attestation_page *)ATTESTATION_PAGE_ADDR)->attestation_cert;
uint8_t * device_get_attestation_key(){
flash_attestation_page * page =(flash_attestation_page *)ATTESTATION_PAGE_ADDR;
@ -106,3 +110,22 @@ uint16_t device_attestation_cert_der_get_size(){
uint16_t sz = (uint16_t)((flash_attestation_page *)ATTESTATION_PAGE_ADDR)->attestation_cert_size;
return sz;
}
void device_attestation_read_cert_der(uint8_t * dst){
const uint8_t * der = ((flash_attestation_page *)ATTESTATION_PAGE_ADDR)->attestation_cert;
uint16_t sz = device_attestation_cert_der_get_size();
memmove(dst, der, sz);
// Overwrite respective x509 fields if Tap or Somu.
if (memcmp(dst + 0x2c6, "\xea\x09\x15\x6c\x86\x48\x57\x2a\xa8\x8d", 10) == 0){
if (device_is_nfc()){
dst[0x2a2] = 0x89;//tap aaguid byte
memmove(dst + 0xac, "\x34\x33\x38\x5a\x18\x0f\x32\x30\x36\x39\x31\x31\x31\x38\x31\x39\x32\x34\x33\x38", 20);//tap-id
memmove(dst + 0x2c5, "\x6d\x7b\x41\x2b\xff\x57\xf0\x03\xbd\x5b\x39\x4a\xf7\xa9\x2d\x6d\xcb\x9e\x2d\x88\xbf\xb3\x93\xc5\x66\x3b\xd1\xbc\x34\xfa\x5c\x4c\x02\x20\x59\x01\x49\x39\x1b\xb7\xa9\x1c\xed\x49\x78\x4f\x92\xa9\x61\x14\xa5\x6e\x96\x3f\x29\x02\x93\xe0\x5d\xe2\x75\xd0\x60\xd9\x74\xc2", 66);//tap-sig
} else if (tsc_sensor_exists()) {
dst[0x2a2] = 0x98;//somu aaguid byte
memmove(dst + 0xac, "\x35\x30\x32\x5a\x18\x0f\x32\x30\x36\x39\x31\x31\x31\x38\x31\x39\x32\x35\x30\x32", 20);//somu-id
memmove(dst + 0x2c5, "\x4d\x08\xc8\x9d\xc4\x50\x49\x70\x48\x4d\xd0\x12\xd9\x7c\x62\x5e\x6b\xd3\x84\xd5\x36\x42\xfe\x86\x8e\x7a\x23\x59\xa0\x20\xf0\xc5\x02\x20\x5f\x70\x93\x61\x5a\xe4\x20\xcf\xb9\x8a\xf5\xdd\x87\xd0\x48\x6d\x7d\x59\xef\x9e\x0e\x11\xa3\x8e\xf7\xe3\xe2\xf5\x35\x37\x99\x1a", 66);//somu-sig
}
}
}

View File

@ -859,6 +859,17 @@ void boot_solo_bootloader(void)
}
void device_read_aaguid(uint8_t * dst){
uint8_t * aaguid = (uint8_t *)"\x88\x76\x63\x1b\xd4\xa0\x42\x7f\x57\x73\x0e\xc7\x1c\x9e\x02\x79";
memmove(dst, aaguid, 16);
if (device_is_nfc()){
dst[0] = 0x89;
}
else if (tsc_sensor_exists()){
dst[0] = 0x98;
}
dump_hex1(TAG_GREEN,dst, 16);
}
void _Error_Handler(char *file, int line)

View File

@ -67,7 +67,7 @@ typedef struct flash_memory_st flash_memory_st;
#include <assert.h>
static_assert(sizeof(flash_memory_st) == 256*1024, "Data structure doesn't match flash size");
#define ATTESTATION_CONFIGURED_TAG 0xaa551e78
#define ATTESTATION_CONFIGURED_TAG 0xaa551e79
struct flash_attestation_page{
uint8_t attestation_key[32];

View File

@ -1,5 +1,4 @@
ecdsa
fido2
intelhex
pyserial
solo-python