diff --git a/.gitignore b/.gitignore
index 37aba31..54da40e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,6 @@ obj/*
U2F_Priv_Keys.txt
.ccls-cache
compile_commands.json
+Certificates.hpp
+Certificates.cpp
+Keys/*
diff --git a/Certificates.cpp b/Certificates.cpp
deleted file mode 100644
index dd2d95d..0000000
--- a/Certificates.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-U2FDevice - A program to allow Raspberry Pi Zeros to act as U2F tokens
-Copyright (C) 2018 Michael Kuc
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-#include "Certificates.hpp"
-
-// You may not actually want to use these values -
-// having been shared publicly, these may be vulnerable to exploits.
-// However, generating your own attestation certificate makes your device
-// uniquely identifiable across platforms / services, etc.
-// You can generate your own using the method detailed in the README.
-
-uint8_t attestCert[] = {
- 0x30, 0x82, 0x02, 0x29, 0x30, 0x82, 0x01, 0xd0, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
- 0x8a, 0xe2, 0x21, 0x3f, 0x2f, 0x8b, 0x72, 0x52, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
- 0x3d, 0x04, 0x03, 0x02, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
- 0x02, 0x55, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f,
- 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04,
- 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
- 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x29, 0x30, 0x27, 0x06,
- 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x55, 0x32, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x74, 0x50,
- 0x46, 0x53, 0x71, 0x54, 0x71, 0x6f, 0x5a, 0x6d, 0x62, 0x37, 0x38, 0x61, 0x6a, 0x6f, 0x2f, 0x75,
- 0x58, 0x50, 0x73, 0x51, 0x3d, 0x3d, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x38, 0x30, 0x36, 0x33, 0x30,
- 0x31, 0x39, 0x30, 0x37, 0x35, 0x31, 0x5a, 0x17, 0x0d, 0x32, 0x38, 0x30, 0x36, 0x32, 0x37, 0x31,
- 0x39, 0x30, 0x37, 0x35, 0x31, 0x5a, 0x30, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
- 0x06, 0x13, 0x02, 0x55, 0x4b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a,
- 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03,
- 0x55, 0x04, 0x0a, 0x0c, 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69,
- 0x64, 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x29, 0x30,
- 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x55, 0x32, 0x46, 0x20, 0x4b, 0x65, 0x79, 0x20,
- 0x74, 0x50, 0x46, 0x53, 0x71, 0x54, 0x71, 0x6f, 0x5a, 0x6d, 0x62, 0x37, 0x38, 0x61, 0x6a, 0x6f,
- 0x2f, 0x75, 0x58, 0x50, 0x73, 0x51, 0x3d, 0x3d, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
- 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
- 0x42, 0x00, 0x04, 0x32, 0x41, 0xc3, 0xb8, 0x96, 0x97, 0xd8, 0x90, 0x66, 0x41, 0x88, 0x96, 0xd4,
- 0x73, 0xb6, 0x37, 0xf7, 0x85, 0x29, 0xaf, 0x3b, 0x15, 0x0f, 0x83, 0x61, 0x67, 0xea, 0xc9, 0xb2,
- 0xdb, 0x82, 0xb3, 0x2c, 0x99, 0x60, 0x8a, 0x98, 0x7c, 0xd4, 0x04, 0xa0, 0x92, 0x22, 0x05, 0xaa,
- 0xf7, 0x7a, 0x91, 0x02, 0x03, 0xdd, 0x15, 0x88, 0x87, 0x6a, 0x26, 0xe9, 0xee, 0xcf, 0x99, 0xb1,
- 0x66, 0xc0, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
- 0x04, 0x14, 0xcf, 0x7f, 0xfa, 0x7d, 0xc4, 0x8d, 0xba, 0x60, 0x52, 0x4c, 0xb6, 0x16, 0x2e, 0x88,
- 0x62, 0xc7, 0x8c, 0xfc, 0xe0, 0x63, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
- 0x16, 0x80, 0x14, 0xcf, 0x7f, 0xfa, 0x7d, 0xc4, 0x8d, 0xba, 0x60, 0x52, 0x4c, 0xb6, 0x16, 0x2e,
- 0x88, 0x62, 0xc7, 0x8c, 0xfc, 0xe0, 0x63, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
- 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce,
- 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x72, 0x25, 0x89, 0xc1, 0x32,
- 0x54, 0x66, 0xf8, 0x0e, 0x58, 0x77, 0xe3, 0xb5, 0x62, 0x47, 0x33, 0x18, 0x5a, 0xdc, 0x28, 0x6a,
- 0x4a, 0x56, 0xcb, 0x58, 0x63, 0xe3, 0xa1, 0x02, 0x6a, 0xf0, 0xd8, 0x02, 0x20, 0x65, 0x26, 0x84,
- 0x7c, 0xc3, 0x3b, 0x7d, 0x6a, 0x22, 0x0c, 0x22, 0x3d, 0xc8, 0x43, 0xb7, 0x84, 0x8b, 0x7b, 0x48,
- 0x23, 0xb0, 0x1e, 0x13, 0x35, 0x1d, 0x1a, 0x90, 0x44, 0x62, 0x6c, 0xab, 0x9b
-};
-
-uint8_t attestPrivKey[] = { 0x7e, 0xbd, 0x91, 0x05, 0x5a, 0x80, 0x9f, 0x36, 0xe5, 0x2f, 0xe0,
- 0xd0, 0xa9, 0x63, 0x0c, 0x86, 0x04, 0xb1, 0x04, 0xe3, 0xd1, 0xfb,
- 0xd0, 0x83, 0xc7, 0x2e, 0x2f, 0x34, 0xb6, 0xd6, 0xa4, 0xb2 };
-
-uint8_t attestPubKey[] = { 0x04, 0x32, 0x41, 0xc3, 0xb8, 0x96, 0x97, 0xd8, 0x90, 0x66, 0x41,
- 0x88, 0x96, 0xd4, 0x73, 0xb6, 0x37, 0xf7, 0x85, 0x29, 0xaf, 0x3b,
- 0x15, 0x0f, 0x83, 0x61, 0x67, 0xea, 0xc9, 0xb2, 0xdb, 0x82, 0xb3,
- 0x2c, 0x99, 0x60, 0x8a, 0x98, 0x7c, 0xd4, 0x04, 0xa0, 0x92, 0x22,
- 0x05, 0xaa, 0xf7, 0x7a, 0x91, 0x02, 0x03, 0xdd, 0x15, 0x88, 0x87,
- 0x6a, 0x26, 0xe9, 0xee, 0xcf, 0x99, 0xb1, 0x66, 0xc0, 0x01 };
diff --git a/Certificates.cpp.template b/Certificates.cpp.template
new file mode 100644
index 0000000..31e661b
--- /dev/null
+++ b/Certificates.cpp.template
@@ -0,0 +1,37 @@
+/*
+U2FDevice - A program to allow Raspberry Pi Zeros to act as U2F tokens
+Copyright (C) 2018 Michael Kuc
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include "Certificates.hpp"
+
+// You may not actually want to use these values -
+// having been shared publicly, these may be vulnerable to exploits.
+// However, generating your own attestation certificate makes your device
+// uniquely identifiable across platforms / services, etc.
+// You can generate your own using the method detailed in the README.
+
+uint8_t attestCert[] = {
+ // Generate attestation certificate here
+};
+
+uint8_t attestPrivKey[] = {
+ // Generate private key here
+};
+
+uint8_t attestPubKey[] = {
+ // Generate public key here
+};
diff --git a/Certificates.hpp b/Certificates.hpp.template
similarity index 79%
rename from Certificates.hpp
rename to Certificates.hpp.template
index 8da2396..d7f034d 100644
--- a/Certificates.hpp
+++ b/Certificates.hpp.template
@@ -19,6 +19,6 @@ along with this program. If not, see .
#pragma once
#include
-extern uint8_t attestCert[557];
-extern uint8_t attestPrivKey[32];
-extern uint8_t attestPubKey[65];
+extern uint8_t attestCert[/* attestation certificate size */];
+extern uint8_t attestPrivKey[/* attestation private key size */];
+extern uint8_t attestPubKey[/* attestion public key size */];
diff --git a/GenCertificates.sh b/GenCertificates.sh
new file mode 100755
index 0000000..5e51e97
--- /dev/null
+++ b/GenCertificates.sh
@@ -0,0 +1,31 @@
+#!/usr/bin/env sh
+
+sed --version | grep "GNU" 2>&1 1>/dev/null
+if [ $? -ne 0 ]; then
+ printf "Requires the GNU version of SED.\n"
+ return -1
+fi
+
+[ -d Keys ] || mkdir Keys
+
+openssl ecparam -name prime256v1 -genkey -noout -out Keys/ecprivkey.pem
+openssl ec -in Keys/ecprivkey.pem -pubout -out Keys/ecpubkey.pem 2>/dev/null
+openssl req -new -x509 -key Keys/ecprivkey.pem -out Keys/certificate.pem -days 3650
+openssl x509 -outform der -in Keys/certificate.pem -out Keys/certificate.der 2>/dev/null
+
+certificate="$(xxd --include Keys/certificate.der | sed -e '0,/{/d;/};/,$d' -e 's/^\s\+/\t/g')"
+certificateSize="$(printf "%s" "${certificate}" | wc -w)"
+printf "%s" "${certificate}" | sed -e '/\/\/ Generate attestation certificate here/{r/dev/stdin
+d }' Certificates.cpp.template > Keys/Certificates.cpp.template.1
+
+privkey="$(openssl ec -in Keys/ecprivkey.pem -pubout -text -noout 2>/dev/null | sed -e '0,/priv:/d;/pub:/,$d' -e 's/\s//g;s/:/, /g;' -e 's/^/\t/g;s/\s\+$//g' -e 's/\(\s\)/\10x/g')"
+privSize="$(printf "%s" "${privkey}" | wc -w)"
+printf "%s\n" "${privkey}" | sed -e '/\/\/ Generate private key here/{r/dev/stdin
+d }' Keys/Certificates.cpp.template.1 > Keys/Certificates.cpp.template.2
+
+pubkey="$(openssl ec -in Keys/ecprivkey.pem -pubout -text -noout 2>/dev/null | sed -e '0,/pub:/d;/ASN1/,$d' -e 's/\s//g;s/:/, /g;' -e 's/^/\t/g;s/\s\+$//g' -e 's/\(\s\)/\10x/g')"
+pubSize="$(printf "%s" "${pubkey}" | wc -w)"
+printf "%s\n" "${pubkey}" | sed -e '/\/\/ Generate public key here/{r/dev/stdin
+d }' Keys/Certificates.cpp.template.2 > Certificates.cpp
+
+sed -e "s/\\/\\* attestation certificate size \\*\\//${certificateSize}/; s/\\/\\* attestation private key size \\*\\//${privSize}/; s/\\/\\* attestion public key size \\*\\//${pubSize}/" Certificates.hpp.template > Certificates.hpp
diff --git a/Keys/certificate.der b/Keys/certificate.der
deleted file mode 100644
index 3b061d1..0000000
Binary files a/Keys/certificate.der and /dev/null differ
diff --git a/Keys/ecprivkey.pem b/Keys/ecprivkey.pem
deleted file mode 100644
index 0f84abe..0000000
--- a/Keys/ecprivkey.pem
+++ /dev/null
@@ -1,5 +0,0 @@
------BEGIN EC PRIVATE KEY-----
-MHcCAQEEIH69kQVagJ825S/g0KljDIYEsQTj0fvQg8cuLzS21qSyoAoGCCqGSM49
-AwEHoUQDQgAEMkHDuJaX2JBmQYiW1HO2N/eFKa87FQ+DYWfqybLbgrMsmWCKmHzU
-BKCSIgWq93qRAgPdFYiHaibp7s+ZsWbAAQ==
------END EC PRIVATE KEY-----
diff --git a/Keys/ecpubkey.pem b/Keys/ecpubkey.pem
deleted file mode 100644
index b45f686..0000000
--- a/Keys/ecpubkey.pem
+++ /dev/null
@@ -1,4 +0,0 @@
------BEGIN PUBLIC KEY-----
-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMkHDuJaX2JBmQYiW1HO2N/eFKa87
-FQ+DYWfqybLbgrMsmWCKmHzUBKCSIgWq93qRAgPdFYiHaibp7s+ZsWbAAQ==
------END PUBLIC KEY-----
diff --git a/Keys/privkey.der b/Keys/privkey.der
deleted file mode 100644
index f3dd341..0000000
--- a/Keys/privkey.der
+++ /dev/null
@@ -1 +0,0 @@
-~Z6/ЩcЃ./4֤
\ No newline at end of file
diff --git a/Keys/pubkey.der b/Keys/pubkey.der
deleted file mode 100644
index 06b9bf1..0000000
--- a/Keys/pubkey.der
+++ /dev/null
@@ -1 +0,0 @@
-2AøؐfAs7);agɲۂ,`|"zj&ϙf
\ No newline at end of file
diff --git a/Keys/server.pem b/Keys/server.pem
deleted file mode 100644
index 132699c..0000000
--- a/Keys/server.pem
+++ /dev/null
@@ -1,14 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICKTCCAdCgAwIBAgIJAIriIT8vi3JSMAoGCCqGSM49BAMCMHAxCzAJBgNVBAYT
-AlVLMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn
-aXRzIFB0eSBMdGQxKTAnBgNVBAMMIFUyRiBLZXkgdFBGU3FUcW9abWI3OGFqby91
-WFBzUT09MB4XDTE4MDYzMDE5MDc1MVoXDTI4MDYyNzE5MDc1MVowcDELMAkGA1UE
-BhMCVUsxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp
-ZGdpdHMgUHR5IEx0ZDEpMCcGA1UEAwwgVTJGIEtleSB0UEZTcVRxb1ptYjc4YWpv
-L3VYUHNRPT0wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQyQcO4lpfYkGZBiJbU
-c7Y394UprzsVD4NhZ+rJstuCsyyZYIqYfNQEoJIiBar3epECA90ViIdqJunuz5mx
-ZsABo1MwUTAdBgNVHQ4EFgQUz3/6fcSNumBSTLYWLohix4z84GMwHwYDVR0jBBgw
-FoAUz3/6fcSNumBSTLYWLohix4z84GMwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjO
-PQQDAgNHADBEAiByJYnBMlRm+A5Yd+O1YkczGFrcKGpKVstYY+OhAmrw2AIgZSaE
-fMM7fWoiDCI9yEO3hIt7SCOwHhM1HRqQRGJsq5s=
------END CERTIFICATE-----
diff --git a/Makefile b/Makefile
index 0a16c6e..034d530 100755
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,7 @@
#!/usr/bin/env make
SRC_DIR := .
+KEY_DIR := Keys
OBJ_DIR := obj
CXXFLAGS := -std=c++11 -MMD -MP -Wall -Wfatal-errors -Wextra -fPIE
LDFLAGS := -fPIE
@@ -31,7 +32,7 @@ install: U2FDevice
install -m775 -t /etc/systemd/system Services/U2FDevice.service
install -d /usr/share/U2FDevice/
-$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR)
+$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp | $(OBJ_DIR) $(SRC_DIR)/Certificates.hpp
$(CXX) $(STATIC) $(CXXFLAGS) -c -o $@ $<
$(OBJ_DIR):
@@ -45,7 +46,14 @@ clean:
$(MAKE) -C micro-ecc clean
$(MAKE) -C cpp-base64 clean
-.PHONY: clean install
+clean-certificates:
+ rm -f $(KEY_DIR)/*
+ rm -f Certificates.cpp Certificates.hpp
+
+$(SRC_DIR)/Certificates.hpp: $(SRC_DIR)/Certificates.hpp.template
+ $(error "Please run the GenCertificates.sh script to generate certificate before building\n")
+
+.PHONY: clean clean-certificates install
libuECC.a:
$(MAKE) -C micro-ecc
diff --git a/Readme.AttestationCertificateGeneration.md b/Readme.AttestationCertificateGeneration.md
index fabb13d..ae2f204 100644
--- a/Readme.AttestationCertificateGeneration.md
+++ b/Readme.AttestationCertificateGeneration.md
@@ -1,19 +1,20 @@
-From https://github.com/pratikd650/Teensy_U2F/blob/master/Teensy_U2F.cpp line 292
+From [Teensy U2F](https://github.com/pratikd650/Teensy_U2F/blob/master/Teensy_U2F.cpp) line 292
Instructions to generate attestation certificate using open ssl
-https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations
-https://www.guyrutenberg.com/2013/12/28/creating-self-signed-ecdsa-ssl-certificate-using-openssl/
+[OpenSSL wiki](https://wiki.openssl.org/index.php/Command_Line_Elliptic_Curve_Operations)
+[Guy Rutenberg](https://www.guyrutenberg.com/2013/12/28/creating-self-signed-ecdsa-ssl-certificate-using-openssl/)
P-256 (also secp256r1) EC key pair is W = dG (Note secp256k1 is Koblitz curve - not P256)
d = private key is it 256 bits (32 bytes)
G = generator point - it is part of the curve definition
W = public key point - it is a (256, 256) bits - 64 bytes
+
1) Generate a key pair - the private key will be saved in PKCS8 format in ecprivkey.pem
`openssl ecparam -name prime256v1 -genkey -noout -out ecprivkey.pem`
2) Dump out the private key in hex format - it will be a 32 byte key
-`openssl asn1parse -in ecprivkey.pem`
+`openssl asn1parse -in ecprivkey.pem`
3) Compute the public key from the private key and the curve
@@ -41,20 +42,20 @@ For the Certificate name give a unique certificate name.
8) Generate a usable c-array for source code
-`xxd --include certificate.der`
+`xxd --include certificate.der | sed -e '0,/{/d;/};/,$d'`
Copy output into appropriate array in 'Certificates.cpp', overwriting existing values
-9) Repeat steps 7 & 8 for public key and private key
+9) Find the public key
-So:
+`openssl ec -in ecprivkey.pem -pubout -text -noout 2>/dev/null | sed -e '0,/priv:/d;/pub:/,$d' -e 's/\s//g;s/:/, /g' -e 's/^/\t/g;s/\s\+$//g' -e 's/\(\s\)/\10x/g'`
-```
-openssl asn1parse -in ecprivkey.pem 2>/dev/null | grep 'HEX DUMP' | perl -pe 's/^.*\[HEX DUMP\]:(.+)$/$1/' 2>/dev/null | xxd -r -p > privkey.der && xxd --include privkey.der
+10) Find the private key
-openssl ec -in ecprivkey.pem -pubout -text 2>/dev/null | perl -0777 -ne 'print /pub:.+ASN1/sg' 2>/dev/null | sed -e '/pub:/d;/ASN1/d' | perl -pe 's/^\s+(.+):?$/$1/gm' 2>/dev/null | perl -pe 's/\n//' 2>/dev/null | perl -pe 's/(.{2}):?/$1/g' 2>/dev/null | xxd -r -p > pubkey.der && xxd --include pubkey.der
-```
+`openssl ec -in ecprivkey.pem -pubout -text -noout 2>/dev/null | sed -e '0,/pub:/d;/ASN1/,$d' | sed -e 's/\s//g;s/:/, /g' -e 's/^/\t/g;s/\s\+$//g' -e 's/\(\s\)/\10x/g'`
-and copy the arrays into the correct arrays in Certificates.cpp.
+11)
+
+Copy the arrays into the correct arrays in Certificates.cpp.
If any arrays have different lengths than shown in Certificates.hpp, update these too.