-
-
Save darconeous/adb1b2c4b15d3d8fbc72a5097270cdaf to your computer and use it in GitHub Desktop.
#!/bin/sh | |
GP=${GP-java -jar gp.jar} | |
set -v | |
set -e | |
# This is for the ACR122U to put it into | |
# a nice state where it won't time out on us. | |
$GP -d -v -a ff0041ff00 -a ff00520000 || true | |
$GP -d -v \ | |
--uninstall U2FApplet.cap | |
$GP -d -v \ | |
--install U2FApplet.cap \ | |
--create A0000006472F0001 \ | |
--params "000140f3fccc0d00d8031954f90864d43c247f4bf5f0665c6b50cc17749a27d1cf7664" | |
$GP -d -v \ | |
-a "00 A4 04 00 08 A0 00 00 06 47 2F 00 01" \ | |
-a "80 01 00 00 80 30 82 01 3c 30 81 e4 a0 03 02 01 02 02 0a 47 90 12 80 00 11 55 95 73 52 30 0a 06 08 2a 86 48 ce 3d 04 03 02 30 17 31 15 30 13 06 03 55 04 03 13 0c 47 6e 75 62 62 79 20 50 69 6c 6f 74 30 1e 17 0d 31 32 30 38 31 34 31 38 32 39 33 32 5a 17 0d 31 33 30 38 31 34 31 38 32 39 33 32 5a 30 31 31 2f 30 2d 06 03 55 04 03 13 26 50 69 6c 6f 74 47 6e 75 62 62 79 2d 30 2e 34 2e 31 2d 34 37 39 30" \ | |
-a "80 01 00 80 80 31 32 38 30 30 30 31 31 35 35 39 35 37 33 35 32 30 59 30 13 06 07 2a 86 48 ce 3d 02 01 06 08 2a 86 48 ce 3d 03 01 07 03 42 00 04 8d 61 7e 65 c9 50 8e 64 bc c5 67 3a c8 2a 67 99 da 3c 14 46 68 2c 25 8c 46 3f ff df 58 df d2 fa 3e 6c 37 8b 53 d7 95 c4 a4 df fb 41 99 ed d7 86 2f 23 ab af 02 03 b4 b8 91 1b a0 56 99 94 e1 01 30 0a 06 08 2a 86 48 ce 3d 04 03 02 03 47 00 30 44 02 20 60 cd" \ | |
-a "80 01 01 00 40 b6 06 1e 9c 22 26 2d 1a ac 1d 96 d8 c7 08 29 b2 36 65 31 dd a2 68 83 2c b8 36 bc d3 0d fa 02 20 63 1b 14 59 f0 9e 63 30 05 57 22 c8 d8 9b 7f 48 88 3b 90 89 b8 8d 60 d1 d9 79 59 02 b3 04 10 df" |
Thanks to your clarifications, I was able to track down the example attestation certificate in the Fido Alliance's spec page FIDO U2F Raw Message Formats:
Assume we have a U2F token with the following private attestation key:
f3fccc0d00d8031954f90864d43c247f4bf5f0665c6b50cc17749a27d1cf7664
the corresponding public key:
048d617e65c9508e64bcc5673ac82a6799da3c1446682c258c463fffdf58dfd2fa3e6c378b53d795c4a4dffb4199edd7862f23abaf0203b4b8911ba0569994e101
and the following attestation cert:
[ [ Version: V3 Subject: CN=PilotGnubby-0.4.1-47901280001155957352 Signature Algorithm: SHA256withECDSA, OID = 1.2.840.10045.4.3.2 Key: EC Public Key X: 8d617e65c9508e64bcc5673ac82a6799da3c1446682c258c463fffdf58dfd2fa Y: 3e6c378b53d795c4a4dffb4199edd7862f23abaf0203b4b8911ba0569994e101 Validity: [From: Tue Aug 14 11:29:32 PDT 2012, To: Wed Aug 14 11:29:32 PDT 2013] Issuer: CN=Gnubby Pilot SerialNumber: [ 47901280 00115595 7352] ] Algorithm: [SHA256withECDSA] Signature: 0000: 30 44 02 20 60 CD B6 06 1E 9C 22 26 2D 1A AC 1D 0D. `....."&-... 0010: 96 D8 C7 08 29 B2 36 65 31 DD A2 68 83 2C B8 36 ....).6e1..h.,.6 0020: BC D3 0D FA 02 20 63 1B 14 59 F0 9E 63 30 05 57 ..... c..Y..c0.W 0030: 22 C8 D8 9B 7F 48 88 3B 90 89 B8 8D 60 D1 D9 79 "....H.;....`..y 0040: 59 02 B3 04 10 DF Y..... ]
...
...
Posting here in case anyone else has the same confusion. Thanks again!
I made an extended version of script that will generate really private private keys and corresponding attestation cert:
#!/bin/bash
function usage {
echo "usage: $0 <cap file> <gp jar> <certificate subject> [extra gp args...]" >&2
echo "" >&2
echo "Generates fresh key and certificate, installs applet on a card and" >&2
echo "uploads a certificate, giving you ready-to-use card" >&2
echo "" >&2
echo "If you have a locked card, specify extra arguments like '--key XXX'" >&2
exit 2
}
if [ -z "$1" -o -z "$2" -o -z "$3" ]; then
usage
fi
CAP_FILE="$1"
GP_JAR="$2"
CERT_SUBJECT="$3"
shift 3
echo "++ Generating keys and certificates..."
set -e # make shell exit on errors
[ -d "certs" ] || mkdir certs
[ -f "certs/private.pem" ] || openssl ecparam -genkey -name P-256 -out "certs/private.pem"
## Extract OpenSSL config: config is needed to avoid space-consuming extensions like "Subject key info"
if [ ! -f "certs/config.conf" ]; then
base64 -d <<EOF | gzip -d > "certs/config.conf"
H4sIAJrPK2ECA22MQQqAMAwE73lF/+DZl5QSxC4axFSbKvb3VjzqdWZnvcvYXaAoVkSnQ2xGZB1W
uP5R/BX0YFwFapLU2u7suDGCjjVvhRfUBjUR+f+HQP5NAt0Vsx1wgAAAAA==
EOF
fi
# Generate self-signed cert
[ -f "certs/cert.crt" ] || openssl req -x509 -config "certs/config.conf" -key "certs/private.pem" \
-sha256 -days 36500 -nodes -out "certs/cert.crt" -subj "/CN=$CERT_SUBJECT"
# Convert from PEM to DER
openssl x509 -in "certs/cert.crt" -outform DER -out "certs/cert.cer"
# Convert private key to just 32 raw bytes
PRIVATE_KEY=$(openssl ec -in "certs/private.pem" -text 2>/dev/null | grep -A 3 priv: | tail -n +2 | tr -d ':[:space:]')
CERT_LENGTH=$(stat --printf "%s" "certs/cert.cer")
echo "++ Installing everything on card..."
function gp {
echo "+ java -jar \"$GP_JAR\" $@"
java -jar "$GP_JAR" $@
}
gp "$@" \
--install "$CAP_FILE" \
--create A0000006472F0001 \
--params "00$(printf "%04x" "$CERT_LENGTH")$PRIVATE_KEY"
OFFSET=0
FRAGMENT=64
APDUS=(--apdu "00A4040008A0000006472F0001")
while [ "$OFFSET" -lt "$CERT_LENGTH" ]; do
CERT_CHUNK=$(dd if="certs/cert.cer" bs=1 skip="$OFFSET" count="$FRAGMENT" status=none | xxd -p -c 9999)
CHUNK_LENGTH=$(($(echo "$CERT_CHUNK" | wc -c) / 2))
APDUS=(${APDUS[@]} --apdu "8001$(printf "%04x%02x" "$OFFSET" "$CHUNK_LENGTH")$CERT_CHUNK")
OFFSET=$(($OFFSET+$FRAGMENT))
done
# Install the certificate
gp ${APDUS[@]}
I made an extended version of script that will generate really private private keys and corresponding attestation cert:
That's really cool! Thanks for writing that up!
One of the reasons why I avoid doing this for my own tokens is that it makes the token uniquely identifiable across services, which is something I was trying to avoid.
Well, homebrew U2F token is sufficiently unique on it's own :)
For what it's worth, I've gone ahead and updated the README.