Skip to content

Commit bbf60e4

Browse files
authored
Merge pull request #111 from canokeys/dev
Dev
2 parents 90281f1 + 98b4f70 commit bbf60e4

File tree

3 files changed

+44
-23
lines changed

3 files changed

+44
-23
lines changed

applets/piv/piv.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ static int piv_general_authenticate(const CAPDU *capdu, RAPDU *rapdu) {
655655
len[IDX_CHALLENGE]);
656656
memzero(DATA + pos[IDX_CHALLENGE], PRIVATE_KEY_LENGTH[key.meta.type] - len[IDX_CHALLENGE]);
657657
}
658-
int sig_len = ck_sign(&key, DATA + pos[IDX_CHALLENGE], PRIVATE_KEY_LENGTH[key.meta.type], RDATA + 4);
658+
int sig_len = ck_sign(&key, DATA + pos[IDX_CHALLENGE], len[IDX_CHALLENGE], RDATA + 4);
659659
if (sig_len < 0) {
660660
ERR_MSG("Sign failed\n");
661661
return -1;

src/key.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,19 @@ int ck_parse_piv(ck_key_t *key, const uint8_t *buf, size_t buf_len) {
126126
DBG_MSG("too short\n");
127127
return KEY_ERR_LENGTH;
128128
}
129-
if (*p++ != 0x06) {
129+
if (*p != 0x06 && !(key->meta.type == ED25519 && *p == 0x07) && !(key->meta.type == X25519 && *p == 0x08)) {
130130
DBG_MSG("invalid tag\n");
131131
return KEY_ERR_DATA;
132132
}
133+
p++;
133134
if (*p++ != PRIVATE_KEY_LENGTH[key->meta.type]) {
134135
DBG_MSG("invalid private key length\n");
135136
return KEY_ERR_LENGTH;
136137
}
137138
memcpy(key->ecc.pri, p, PRIVATE_KEY_LENGTH[key->meta.type]);
139+
if (key->meta.type == X25519) {
140+
swap_big_number_endian(key->ecc.pri); // Private key of x25519 is encoded in little endian
141+
}
138142
if (!ecc_verify_private_key(key->meta.type, &key->ecc)) {
139143
memzero(key, sizeof(ck_key_t));
140144
return KEY_ERR_DATA;

test-real/test-piv.sh

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ PIVImportKeyCert() {
2828
cert_pem="$3"
2929
YPT -a import-key -s $key -i "$priv_pem"
3030
assertEquals 'import-key' 0 $?
31-
YPT -a import-certificate -s $key -i "$cert_pem"
32-
assertEquals 'import-certificate' 0 $?
33-
cp "$cert_pem" "$TEST_TMP_DIR/cert-$key.pem"
31+
if [[ -f "$cert_pem" ]]; then
32+
YPT -a import-certificate -s $key -i "$cert_pem"
33+
assertEquals 'import-certificate' 0 $?
34+
cp "$cert_pem" "$TEST_TMP_DIR/cert-$key.pem"
35+
fi
3436
}
3537

3638
PIVSignDec() {
@@ -166,24 +168,39 @@ test_PinBlock() {
166168
assertContains 'verify-pin' "$out" 'Successfully unblocked the pin code'
167169
}
168170

169-
test_P256KeyImport() {
170-
openssl ecparam -name prime256v1 -out $TEST_TMP_DIR/p256.pem
171-
openssl req -x509 -newkey ec:$TEST_TMP_DIR/p256.pem -keyout $TEST_TMP_DIR/key.pem -out $TEST_TMP_DIR/cert.pem -days 365 -nodes -subj "/CN=www.example.com"
172-
173-
for s in 9a 9c 9d 9e; do PIVImportKeyCert $s $TEST_TMP_DIR/key.pem $TEST_TMP_DIR/cert.pem; done
174-
YPT -a status
175-
for s in 9a 9c 9e; do PIVSignDec $s 1 s; done # 9a/9c/9e only do the ECDSA
176-
PIVSignDec 9d 1 d # 9d only do the ECDH
177-
}
178-
179-
test_P384KeyImport() {
180-
openssl ecparam -name secp384r1 -out $TEST_TMP_DIR/p384.pem
181-
openssl req -x509 -newkey ec:$TEST_TMP_DIR/p384.pem -keyout $TEST_TMP_DIR/key.pem -out $TEST_TMP_DIR/cert.pem -days 365 -nodes -subj "/CN=www.example.com"
182-
183-
for s in 9a 9c 9d 9e; do PIVImportKeyCert $s $TEST_TMP_DIR/key.pem $TEST_TMP_DIR/cert.pem; done
184-
YPT -a status
185-
for s in 9a 9c 9e; do PIVSignDec $s 1 s; done # 9a/9c/9e only do the ECDSA
186-
PIVSignDec 9d 1 d # 9d only do the ECDH
171+
test_ECKeyImport() {
172+
declare -A OPTS
173+
OPTS=(\
174+
[ECCP256]="-algorithm EC -pkeyopt ec_paramgen_curve:prime256v1" \
175+
[ECCP384]="-algorithm EC -pkeyopt ec_paramgen_curve:secp384r1" \
176+
[ED25519]="-algorithm ED25519" \
177+
[X25519]="-algorithm X25519" \
178+
)
179+
for algo in ${!OPTS[@]}
180+
do
181+
# openssl ecparam -name $curve -out $TEST_TMP_DIR/$curve.pem
182+
# openssl req -x509 -newkey ec:$TEST_TMP_DIR/$curve.pem -keyout $TEST_TMP_DIR/key.pem -out $TEST_TMP_DIR/cert.pem -days 365 -nodes -subj "/CN=www.example.com"
183+
opt=${OPTS[${algo}]}
184+
for s in 9a 9c 9d 9e; do
185+
openssl genpkey $opt -out $TEST_TMP_DIR/key-$s.pem
186+
# this command is expected to fail on X25519
187+
openssl req -x509 -key $TEST_TMP_DIR/key-$s.pem -out $TEST_TMP_DIR/cert.pem -days 365 -nodes -subj "/CN=www.example.com"
188+
189+
PIVImportKeyCert $s $TEST_TMP_DIR/key-$s.pem $TEST_TMP_DIR/cert.pem
190+
# pubkey-$s.pem is used by X25519
191+
openssl pkey -in $TEST_TMP_DIR/key-$s.pem -pubout -out $TEST_TMP_DIR/pubkey-$s.pem
192+
done
193+
YPT -a status
194+
for s in 9a 9c 9d 9e; do
195+
if [[ $algo != X25519 ]]; then
196+
PIVSignDec $s 1 s $algo;
197+
fi
198+
if [[ $algo != ED25519 ]]; then
199+
PIVSignDec $s 1 d $algo;
200+
fi
201+
done
202+
rm -f $TEST_TMP_DIR/cert.pem
203+
done
187204
}
188205

189206
test_RSAKeyImport() {

0 commit comments

Comments
 (0)