diff --git a/CHANGES b/CHANGES index 3389713033..b3ed5d4853 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ 'rndc addzone' contained a double quote (") in its name. [GL #1695] +5397. [func] Update PKCS#11 EdDSA implementation to PKCS#11 v3.0. + Thanks to Aaron Thompson. [GL !3326] + 5394. [cleanup] Don't change effective uid/gid in named_os_openfile() if named is already running under specified uid/gid. [GL #1042] [GL #1090] diff --git a/bin/dnssec/dnssec-keyfromlabel.c b/bin/dnssec/dnssec-keyfromlabel.c index 3d2d24eae8..05cc77cca5 100644 --- a/bin/dnssec/dnssec-keyfromlabel.c +++ b/bin/dnssec/dnssec-keyfromlabel.c @@ -63,7 +63,8 @@ usage(void) { " DH | RSASHA1 |\n" " NSEC3RSASHA1 |\n" " RSASHA256 | RSASHA512 |\n" - " ECDSAP256SHA256 | ECDSAP384SHA384\n"); + " ECDSAP256SHA256 | ECDSAP384SHA384 |\n" + " ED25519 | ED448\n"); fprintf(stderr, " -3: use NSEC3-capable algorithm\n"); fprintf(stderr, " -c class (default: IN)\n"); fprintf(stderr, " -E :\n"); diff --git a/bin/tests/system/cleanpkcs11.sh b/bin/tests/system/cleanpkcs11.sh index b974708b1c..fafb08a54e 100644 --- a/bin/tests/system/cleanpkcs11.sh +++ b/bin/tests/system/cleanpkcs11.sh @@ -9,9 +9,8 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -SYSTEMTESTTOP=. -. $SYSTEMTESTTOP/conf.sh +. "$SYSTEMTESTTOP/conf.sh" -if [ ! -x ../../pkcs11/pkcs11-destroy ]; then exit 1; fi +PK11DELBIN=$(echo "$PK11DEL" | awk '{ print $1 }') -$PK11DEL -w0 > /dev/null 2>&1 +[ -x "$PK11DELBIN" ] && $PK11DEL -w0 > /dev/null 2>&1 diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh index 568741063e..7b524309e3 100644 --- a/bin/tests/system/dnssec/clean.sh +++ b/bin/tests/system/dnssec/clean.sh @@ -19,7 +19,7 @@ rm -f ./*/named.run ./*/named.run.prev rm -f ./*/named.secroots rm -f ./*/tmp* ./*/*.jnl ./*/*.bk ./*/*.jbk rm -f ./*/trusted.conf ./*/managed.conf ./*/revoked.conf -rm -f ./Kexample.* +rm -f ./Kexample.* ./Kkeygen* ./keygen*.err rm -f ./canonical?.* rm -f ./delv.out* rm -f ./delve.out* diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index cce7b3fcb0..50f1dc7452 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -3220,6 +3220,7 @@ ret=0 alg=1 until test $alg -eq 256 do + zone="keygen-$alg." case $alg in 2) # Diffie Helman alg=$((alg+1)) @@ -3228,21 +3229,21 @@ do alg=$((alg+1)) continue;; 1|5|7|8|10) # RSA algorithms - key1=$($KEYGEN -a "$alg" -b "1024" -n zone example 2> keygen.err || true) + key1=$($KEYGEN -a "$alg" -b "1024" -n zone "$zone" 2> "keygen-$alg.err" || true) ;; 15|16) - key1=$($KEYGEN -a "$alg" -b "1024" -n zone example 2> keygen.err || true) + key1=$($KEYGEN -a "$alg" -n zone "$zone" 2> "keygen-$alg.err" || true) # Soft-fail in case HSM doesn't support Edwards curves - if grep "not found" keygen.err > /dev/null && [ "$CRYPTO" = "pkcs11" ]; then + if grep "not found" "keygen-$alg.err" > /dev/null && [ "$CRYPTO" = "pkcs11" ]; then echo_i "Algorithm $alg not supported by HSM: skipping" alg=$((alg+1)) continue fi ;; *) - key1=$($KEYGEN -a "$alg" -n zone example 2> keygen.err || true) + key1=$($KEYGEN -a "$alg" -n zone "$zone" 2> "keygen-$alg.err" || true) esac - if grep "unsupported algorithm" keygen.err > /dev/null + if grep "unsupported algorithm" "keygen-$alg.err" > /dev/null then alg=$((alg+1)) continue @@ -3250,7 +3251,7 @@ do if test -z "$key1" then echo_i "'$KEYGEN -a $alg': failed" - cat keygen.err + cat "keygen-$alg.err" ret=1 alg=$((alg+1)) continue diff --git a/bin/tests/system/pkcs11/clean.sh b/bin/tests/system/pkcs11/clean.sh index a3c1ab3a12..ffdbec76f6 100644 --- a/bin/tests/system/pkcs11/clean.sh +++ b/bin/tests/system/pkcs11/clean.sh @@ -12,9 +12,8 @@ set -e rm -f K* ns1/K* keyset-* dsset-* ns1/*.db ns1/*.signed ns1/*.jnl -rm -f dig.out* pin upd.log* -rm -f ns1/*.key ns1/named.memstats +rm -f dig.out* pin upd.log* upd.cmd* pkcs11-list.out* +rm -f ns1/*.ksk ns1/*.zsk ns1/named.memstats rm -f supported -rm -f ns*/named.run -rm -f ns*/named.lock +rm -f ns*/named.run ns*/named.lock ns*/named.conf rm -f ns*/managed-keys.bind* diff --git a/bin/tests/system/pkcs11/ns1/named.conf b/bin/tests/system/pkcs11/ns1/named.conf.in similarity index 66% rename from bin/tests/system/pkcs11/ns1/named.conf rename to bin/tests/system/pkcs11/ns1/named.conf.in index 0e96eda38a..a4a51b357c 100644 --- a/bin/tests/system/pkcs11/ns1/named.conf +++ b/bin/tests/system/pkcs11/ns1/named.conf.in @@ -15,7 +15,7 @@ options { query-source address 10.53.0.1; notify-source 10.53.0.1; transfer-source 10.53.0.1; - port 5300; + port @PORT@; pid-file "named.pid"; listen-on { 10.53.0.1; }; listen-on-v6 { none; }; @@ -30,23 +30,5 @@ key rndc_key { }; controls { - inet 10.53.0.1 port 9953 allow { any; } keys { rndc_key; }; -}; - -zone "rsa.example." { - type master; - file "rsa.example.db.signed"; - allow-update { any; }; -}; - -zone "ecc.example." { - type master; - file "ecc.example.db.signed"; - allow-update { any; }; -}; - -zone "ecx.example." { - type master; - file "ecx.example.db.signed"; - allow-update { any; }; + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; }; diff --git a/bin/tests/system/pkcs11/setup.sh b/bin/tests/system/pkcs11/setup.sh index fd642d9e5d..a45db18d10 100644 --- a/bin/tests/system/pkcs11/setup.sh +++ b/bin/tests/system/pkcs11/setup.sh @@ -9,106 +9,84 @@ # See the COPYRIGHT file distributed with this work for additional # information regarding copyright ownership. -set -e +set -eu SYSTEMTESTTOP=.. # shellcheck source=conf.sh -. $SYSTEMTESTTOP/conf.sh +. "$SYSTEMTESTTOP/conf.sh" -echo "I:(Native PKCS#11)" >&2 -ecxfail=0 - -$SHELL ../testcrypto.sh -q eddsa || ecxfail=1 - -rm -f supported -touch supported -echo rsa >> supported -echo ecc >> supported -if [ $ecxfail = 0 ]; then - echo ecx >> supported -fi +echo_i "Generating keys for Native PKCS#11" >&2 infile=ns1/example.db.in printf '%s' "${HSMPIN:-1234}" > pin PWD=$(pwd) -zone=rsa.example -zonefile=ns1/rsa.example.db -have_rsa=$(grep rsa supported || true) -if [ "x$have_rsa" != "x" ]; then - $PK11GEN -a RSA -b 1024 -l robie-rsa-zsk1 -i 01 - $PK11GEN -a RSA -b 1024 -l robie-rsa-zsk2 -i 02 - $PK11GEN -a RSA -b 2048 -l robie-rsa-ksk +copy_setports ns1/named.conf.in ns1/named.conf - rsazsk1=$($KEYFRLAB -a RSASHA1 \ - -l "object=robie-rsa-zsk1;pin-source=$PWD/pin" rsa.example) - rsazsk2=$($KEYFRLAB -a RSASHA1 \ - -l "object=robie-rsa-zsk2;pin-source=$PWD/pin" rsa.example) - rsaksk=$($KEYFRLAB -a RSASHA1 -f ksk \ - -l "object=robie-rsa-ksk;pin-source=$PWD/pin" rsa.example) +get_random() { + dd if=/dev/urandom bs=1 count=2 2>/dev/null | od -tu2 -An +} - cat $infile "$rsazsk1".key "$rsaksk".key > $zonefile - $SIGNER -a -P -g -o $zone $zonefile \ - > /dev/null 2> signer.err || cat signer.err - cp "$rsazsk2".key ns1/rsa.key - mv Krsa* ns1 -else - # RSA not available and will not be tested; make a placeholder - cp $infile ${zonefile}.signed -fi +genpkcs() ( + alg="$1" + bits="$2" + label="$3" + id="$(get_random)" -zone=ecc.example -zonefile=ns1/ecc.example.db -have_ecc=$(grep ecc supported || true) -if [ "x$have_ecc" != "x" ]; then - $PK11GEN -a ECC -b 256 -l robie-ecc-zsk1 -i 03 - $PK11GEN -a ECC -b 256 -l robie-ecc-zsk2 -i 04 - $PK11GEN -a ECC -b 384 -l robie-ecc-ksk + $PK11DEL -l "$label" -w0 >/dev/null || true + $PK11GEN -a "$alg" -b "$bits" -l "$label" -i "$id" >/dev/null +) - ecczsk1=$($KEYFRLAB -a ECDSAP256SHA256 \ - -l "object=robie-ecc-zsk1;pin-source=$PWD/pin" ecc.example) - ecczsk2=$($KEYFRLAB -a ECDSAP256SHA256 \ - -l "object=robie-ecc-zsk2;pin-source=$PWD/pin" ecc.example) - eccksk=$($KEYFRLAB -a ECDSAP384SHA384 -f ksk \ - -l "object=robie-ecc-ksk;pin-source=$PWD/pin" ecc.example) +keyfrlab() ( + alg="$1" + bits="$2" + label="$3" + zone="$4" + shift 4 - cat $infile "$ecczsk1".key "$eccksk".key > $zonefile - $SIGNER -a -P -g -o $zone $zonefile \ - > /dev/null 2> signer.err || cat signer.err - cp "$ecczsk2".key ns1/ecc.key - mv Kecc* ns1 -else - # ECC not available and will not be tested; make a placeholder - cp $infile ${zonefile}.signed -fi + $KEYFRLAB -a "$alg" -l "pkcs11:object=$label;pin-source=$PWD/pin" "$@" "$zone" +) -zone=ecx.example -zonefile=ns1/ecx.example.db -have_ecx=$(grep ecx supported || true) -if [ "x$have_ecx" != "x" ]; then - $PK11GEN -a ECX -b 256 -l robie-ecx-zsk1 -i 05 - $PK11GEN -a ECX -b 256 -l robie-ecx-zsk2 -i 06 - $PK11GEN -a ECX -b 256 -l robie-ecx-ksk -# $PK11GEN -a ECX -b 456 -l robie-ecx-ksk +genzsk() ( + genpkcs "$@" + keyfrlab "$@" +) - ecxzsk1=$($KEYFRLAB -a ED25519 \ - -l "object=robie-ecx-zsk1;pin-source=$PWD/pin" ecx.example) - ecxzsk2=$($KEYFRLAB -a ED25519 \ - -l "object=robie-ecx-zsk2;pin-source=$PWD/pin" ecx.example) - ecxksk=$($KEYFRLAB -a ED25519 -f ksk \ - -l "object=robie-ecx-ksk;pin-source=$PWD/pin" ecx.example) -# ecxksk=`$KEYFRLAB -a ED448 -f ksk \ -# -l "object=robie-ecx-ksk;pin-source=$PWD/pin" ecx.example` +genksk() ( + genpkcs "$@" + keyfrlab "$@" -f ksk +) - cat $infile "$ecxzsk1".key "$ecxksk".key > $zonefile - $SIGNER -a -P -g -o $zone $zonefile \ - > /dev/null 2> signer.err || cat signer.err - cp "$ecxzsk2".key ns1/ecx.key - mv Kecx* ns1 -else - # ECX not available and will not be tested; make a placeholder - cp $infile ${zonefile}.signed -fi +algs= +for algbits in rsasha256:2048 rsasha512:2048 ecdsap256sha256:256 ecdsap384sha384:384 ed25519:256 ed448:456; do + alg=$(echo "$algbits" | cut -f 1 -d :) + bits=$(echo "$algbits" | cut -f 2 -d :) + zone="$alg.example" + zonefile="ns1/$alg.example.db" + if $SHELL "$SYSTEMTESTTOP/testcrypto.sh" "$alg"; then + echo "$alg" >> supported + algs="$algs$alg " -rm -f signer.err + zsk1=$(genzsk "$alg" "$bits" "pkcs11-$alg-zsk1" "$zone") + zsk2=$(genzsk "$alg" "$bits" "pkcs11-$alg-zsk2" "$zone") + ksk1=$(genksk "$alg" "$bits" "pkcs11-$alg-ksk1" "$zone") + ksk2=$(genksk "$alg" "$bits" "pkcs11-$alg-ksk2" "$zone") + + cat "$infile" "$zsk1.key" "$ksk1.key" > "$zonefile" + $SIGNER -a -P -g -o "$zone" "$zonefile" > /dev/null + cp "$zsk2.key" "ns1/$alg.zsk" + cp "$ksk2.key" "ns1/$alg.ksk" + mv "K$alg"* ns1/ + + cat >> ns1/named.conf < "dig.out.$rrtype.$alg" && + count=$(count_rrsigs "dig.out.$rrtype.$alg") && + test "$count" -gt "$count0" +) + +test_done() { + if [ $ret -ne 0 ]; then echo_i "failed"; fi + status=$((status+ret)) + ret=0 } status=0 ret=0 -algs="" -have_rsa=$(grep rsa supported || true) -if [ "x$have_rsa" != "x" ]; then - algs="rsa " -fi -have_ecc=$(grep ecc supported || true) -if [ "x$have_ecc" != "x" ]; then - algs=$algs"ecc " -fi -have_ecx=$(grep ecx supported || true) -if [ "x$have_ecx" != "x" ]; then - algs=$algs"ecx " -fi +n=0 +while read -r alg; do + zonefile=ns1/$alg.example.db + echo_i "testing PKCS#11 key generation ($alg)" + count=$($PK11LIST | grep -c "pkcs11-$alg-ksk" || true) + [ "$count" -eq 4 ] || ret=1 + test_done -for alg in $algs; do - zonefile=ns1/$alg.example.db - echo "I:testing PKCS#11 key generation ($alg)" - count=$($PK11LIST | grep -c "robie-$alg-ksk" || true) - if [ "$count" -ne 2 ]; then echo "I:failed"; status=1; fi + echo_i "testing offline signing with PKCS#11 keys ($alg)" - echo "I:testing offline signing with PKCS#11 keys ($alg)" + count=$(grep -c "[0-9][[:space:]]*RRSIG" "$zonefile.signed") + [ "$count" -eq 9 ] || ret=1 + test_done - count=$(grep -c RRSIG "$zonefile.signed" || true) - if [ "$count" -ne 12 ]; then echo "I:failed"; status=1; fi + echo_i "testing inline signing with new PKCS#11 ZSK ($alg)" - echo "I:testing inline signing with PKCS#11 keys ($alg)" + dig_with_opts "$alg.example." @10.53.0.1 "SOA" > "dig.out.SOA.$alg.0" || ret=1 + countSOA0=$(count_rrsigs "dig.out.SOA.$alg.0") + new_zsk=$(grep -v ';' "ns1/$alg.zsk") - dig_with_opts "ns.$alg.example." @10.53.0.1 a > "dig.out.$alg.0" || ret=1 - if [ $ret -ne 0 ]; then echo "I:failed"; fi - status=$((status + ret)) - count0=$(grep -c RRSIG "dig.out.$alg.0" || true) - - $NSUPDATE -v > "upd.log.$alg" < "upd.cmd.ZSK.$alg" < "upd.log.ZSK.$alg" < "upd.cmd.ZSK.$alg" || ret=1 - dig_with_opts "ns.$alg.example." @10.53.0.1 a > "dig.out.$alg" || ret=1 - if [ $ret -ne 0 ]; then echo "I:failed"; fi - status=$((status + ret)) - count=$(grep -c RRSIG "dig.out.$alg" || true) - if [ "$count" -le "$count0" ]; then echo "I:failed"; status=1; fi + retry_quiet 20 dig_for_rr "$alg" "SOA" "$countSOA0" || ret=1 + test_done - echo "I:testing PKCS#11 key destroy ($alg)" - ret=0 - $PK11DEL -l "robie-$alg-ksk" -w0 > /dev/null 2>&1 || ret=1 - $PK11DEL -l "robie-$alg-zsk1" -w0 > /dev/null 2>&1 || ret=1 - case $alg in - rsa) id=02 ;; - ecc) id=04 ;; - ecx) id=06 ;; - esac - $PK11DEL -i $id -w0 > /dev/null 2>&1 || ret=1 - if [ $ret -ne 0 ]; then echo "I:failed"; fi - status=$((status + ret)) - count=$($PK11LIST | grep -c "robie-$alg" || true) - if [ "$count" -ne 0 ]; then echo "I:failed"; fi - status=$((status + count)) -done + echo_i "testing inline signing with new PKCS#11 KSK ($alg)" -echo "I:exit status: $status" + dig_with_opts "$alg.example." @10.53.0.1 "DNSKEY" > "dig.out.DNSKEY.$alg.0" || ret=1 + countDNSKEY0=$(count_rrsigs "dig.out.DNSKEY.$alg.0") + new_ksk=$(grep -v ';' "ns1/$alg.ksk") + + cat > "upd.cmd.KSK.$alg" < "upd.log.KSK.$alg" < "upd.cmd.KSK.$alg" || ret=1 + + retry_quiet 20 dig_for_rr "$alg" "DNSKEY" "$countDNSKEY0" || ret=1 + test_done + + echo_i "testing PKCS#11 key destroy ($alg)" + + # Lookup all existing keys + echo_i "looking up all existing keys ($alg)" + $PK11LIST > "pkcs11-list.out.id.$alg" || ret=1 + test_done + + echo_i "destroying key with 'pkcs11-$alg-ksk1' label ($alg)" + $PK11DEL -l "pkcs11-$alg-ksk1" > /dev/null 2>&1 || ret=1 + test_done + + echo_i "destroying key with 'pkcs11-$alg-zsk1' label ($alg)" + $PK11DEL -l "pkcs11-$alg-zsk1" > /dev/null 2>&1 || ret=1 + test_done + + id=$(awk -v label="'pkcs11-$alg-ksk2'" '{ if ($7 == label) { print $9; exit; } }' < "pkcs11-list.out.id.$alg") + echo_i "destroying key with $id id ($alg)" + if [ -n "$id" ]; then + $PK11DEL -i "$id" > /dev/null 2>&1 || ret=1 + else + ret=1 + fi + test_done + + id=$(awk -v label="'pkcs11-$alg-zsk2'" '{ if ($7 == label) { print $9; exit; } }' < "pkcs11-list.out.id.$alg") + echo_i "destroying key with $id id ($alg)" + if [ -n "$id" ]; then + $PK11DEL -i "$id" > /dev/null 2>&1 || ret=1 + else + ret=1 + fi + test_done + + echo_i "checking if all keys have been destroyed ($alg)" + $PK11LIST > "pkcs11-list.out.$alg" || ret=1 + count=$(grep -c "pkcs11-$alg-[kz]sk[0-9]*" "pkcs11-list.out.$alg" || true) + [ "$count" -eq 0 ] || ret=1 + test_done + n=$((n+1)) +done < supported + +echo_i "Checking if all supported algorithms were tested" +[ "$n" -eq "$(wc -l < supported)" ] || ret=1 +test_done + +echo_i "exit status: $status" [ "$status" -eq 0 ] || exit 1 diff --git a/bin/tests/system/run.sh b/bin/tests/system/run.sh index a9e2f2652f..c885cbc772 100755 --- a/bin/tests/system/run.sh +++ b/bin/tests/system/run.sh @@ -121,10 +121,10 @@ start_servers_failed() { start_servers() { echoinfo "I:$systest:starting servers" if $restart; then - $PERL start.pl --restart --port "$PORT" "$systest" || start_fail + $PERL start.pl --restart --port "$PORT" "$systest" || start_servers_failed else restart=true - $PERL start.pl --port "$PORT" "$systest" || start_fail + $PERL start.pl --port "$PORT" "$systest" || start_servers_failed fi } @@ -190,13 +190,21 @@ fi # Clean up files left from any potential previous runs if test -f $systest/clean.sh then - ( cd $systest && $SHELL clean.sh "$@" ) + ( cd $systest && $SHELL clean.sh "$@" ) + ret=$? + if [ $ret -ne 0 ]; then + echowarn "I:$systest:clean.sh script failed with $ret" + fi fi # Set up any dynamically generated test data if test -f $systest/setup.sh then - ( cd $systest && $SHELL setup.sh "$@" ) + ( cd $systest && $SHELL setup.sh "$@" ) + ret=$? + if [ $ret -ne 0 ]; then + echowarn "I:$systest:clean.sh script failed with $ret" + fi fi status=0 diff --git a/bin/tests/system/testcrypto.sh b/bin/tests/system/testcrypto.sh index ae085c1a20..c4d34ad7c3 100644 --- a/bin/tests/system/testcrypto.sh +++ b/bin/tests/system/testcrypto.sh @@ -29,11 +29,27 @@ while test "$#" -gt 0; do alg="-a RSASHA1" msg="RSA cryptography" ;; - ecdsa|ECDSA) - alg="-a ecdsap256sha256" + rsasha256|RSASHA256) + alg="-a RSASHA256" + msg="RSA cryptography" + ;; + rsasha512|RSASHA512) + alg="-a RSASHA512" + msg="RSA cryptography" + ;; + ecdsa|ECDSA|ecdsap256sha256|ECDSAP256SHA256) + alg="-a ECDSAP256SHA256" msg="ECDSA cryptography" ;; - eddsa|EDDSA) + ecdsap384sha384|ECDSAP384SHA384) + alg="-a ECDSAP384SHA384" + msg="ECDSA cryptography" + ;; + eddsa|EDDSA|ed25519|ED25519) + alg="-a ED25519" + msg="EDDSA cryptography" + ;; + ed448|ED448) alg="-a ED25519" msg="EDDSA cryptography" ;; diff --git a/doc/arm/notes-9.16.3.xml b/doc/arm/notes-9.16.3.xml index e9b43ef1bd..93913bf097 100644 --- a/doc/arm/notes-9.16.3.xml +++ b/doc/arm/notes-9.16.3.xml @@ -38,6 +38,13 @@ None. + + + The native PKCS#11 EdDSA implementation has been updated to PKCS#11 + v3.0 and thus made operational again. Contributed by Aaron Thompson. + [GL !3326] + + diff --git a/lib/dns/openssleddsa_link.c b/lib/dns/openssleddsa_link.c index 524d6473bf..acc0b00e74 100644 --- a/lib/dns/openssleddsa_link.c +++ b/lib/dns/openssleddsa_link.c @@ -472,13 +472,13 @@ openssleddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { #if HAVE_OPENSSL_ED25519 if (key->key_alg == DST_ALG_ED25519) { nid = NID_ED25519; - key->key_size = DNS_KEY_ED25519SIZE; + key->key_size = DNS_KEY_ED25519SIZE * 8; } #endif /* if HAVE_OPENSSL_ED25519 */ #if HAVE_OPENSSL_ED448 if (key->key_alg == DST_ALG_ED448) { nid = NID_ED448; - key->key_size = DNS_KEY_ED448SIZE; + key->key_size = DNS_KEY_ED448SIZE * 8; } #endif /* if HAVE_OPENSSL_ED448 */ if (nid == 0) { @@ -607,7 +607,7 @@ openssleddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { } isc_buffer_forward(data, len); key->keydata.pkey = pkey; - key->key_size = len; + key->key_size = len * 8; return (ISC_R_SUCCESS); } @@ -734,7 +734,7 @@ openssleddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { DST_RET(DST_R_INVALIDPRIVATEKEY); } key->keydata.pkey = pkey; - key->key_size = len; + key->key_size = len * 8; ret = ISC_R_SUCCESS; err: diff --git a/lib/dns/pkcs11eddsa_link.c b/lib/dns/pkcs11eddsa_link.c index 1794128732..76b81c9d52 100644 --- a/lib/dns/pkcs11eddsa_link.c +++ b/lib/dns/pkcs11eddsa_link.c @@ -44,14 +44,17 @@ * object class CKO_PUBLIC_KEY * key type CKK_EC_EDWARDS * attribute CKA_EC_PARAMS (choice with OID namedCurve) - * attribute CKA_EC_POINT (big int A, CKA_VALUE on the token) + * attribute CKA_EC_POINT (big int A) * private keys: * object class CKO_PRIVATE_KEY * key type CKK_EC_EDWARDS * attribute CKA_EC_PARAMS (choice with OID namedCurve) * attribute CKA_VALUE (big int k) + * point format: 0x04 (octet-string) */ +#define TAG_OCTECT_STRING 0x04 + #define DST_RET(a) \ { \ ret = a; \ @@ -254,7 +257,7 @@ pkcs11eddsa_verify(dst_context_t *dctx, const isc_region_t *sig) { { CKA_PRIVATE, &falsevalue, (CK_ULONG)sizeof(falsevalue) }, { CKA_VERIFY, &truevalue, (CK_ULONG)sizeof(truevalue) }, { CKA_EC_PARAMS, NULL, 0 }, - { CKA_VALUE, NULL, 0 } + { CKA_EC_POINT, NULL, 0 } }; CK_ATTRIBUTE *attr; CK_SLOT_ID slotid; @@ -294,7 +297,7 @@ pkcs11eddsa_verify(dst_context_t *dctx, const isc_region_t *sig) { keyTemplate[5].ulValueLen = attr->ulValueLen; break; case CKA_EC_POINT: - /* keyTemplate[6].type is CKA_VALUE */ + INSIST(keyTemplate[6].type == attr->type); keyTemplate[6].pValue = isc_mem_get(dctx->mctx, attr->ulValueLen); memmove(keyTemplate[6].pValue, attr->pValue, @@ -479,7 +482,7 @@ pkcs11eddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { attr = ec->repr; attr[0].type = CKA_EC_PARAMS; - attr[1].type = CKA_VALUE; + attr[1].type = CKA_EC_POINT; attr[2].type = CKA_VALUE; attr = &pubTemplate[5]; @@ -503,7 +506,6 @@ pkcs11eddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { memset(attr->pValue, 0, attr->ulValueLen); PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, pub, attr, 1), DST_R_CRYPTOFAILURE); - attr->type = CKA_EC_POINT; attr++; PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, priv, attr, 1), @@ -521,10 +523,10 @@ pkcs11eddsa_generate(dst_key_t *key, int unused, void (*callback)(int)) { switch (key->key_alg) { case DST_ALG_ED25519: - key->key_size = DNS_KEY_ED25519SIZE; + key->key_size = DNS_KEY_ED25519SIZE * 8; break; case DST_ALG_ED448: - key->key_size = DNS_KEY_ED448SIZE; + key->key_size = DNS_KEY_ED448SIZE * 8; break; default: INSIST(0); @@ -614,7 +616,10 @@ pkcs11eddsa_todns(const dst_key_t *key, isc_buffer_t *data) { ec = key->keydata.pkey; attr = pk11_attribute_bytype(ec, CKA_EC_POINT); - if ((attr == NULL) || (attr->ulValueLen != len)) { + if ((attr == NULL) || (attr->ulValueLen != len + 2) || + (((CK_BYTE_PTR)attr->pValue)[0] != TAG_OCTECT_STRING) || + (((CK_BYTE_PTR)attr->pValue)[1] != len)) + { return (ISC_R_FAILURE); } @@ -622,7 +627,7 @@ pkcs11eddsa_todns(const dst_key_t *key, isc_buffer_t *data) { if (r.length < len) { return (ISC_R_NOSPACE); } - memmove(r.base, (CK_BYTE_PTR)attr->pValue, len); + memmove(r.base, (CK_BYTE_PTR)attr->pValue + 2, len); isc_buffer_add(data, len); return (ISC_R_SUCCESS); @@ -669,13 +674,15 @@ pkcs11eddsa_fromdns(dst_key_t *key, isc_buffer_t *data) { attr++; attr->type = CKA_EC_POINT; - attr->pValue = isc_mem_get(key->mctx, len); - memmove((CK_BYTE_PTR)attr->pValue, r.base, len); - attr->ulValueLen = len; + attr->pValue = isc_mem_get(key->mctx, len + 2); + ((CK_BYTE_PTR)attr->pValue)[0] = TAG_OCTECT_STRING; + ((CK_BYTE_PTR)attr->pValue)[1] = len; + memmove((CK_BYTE_PTR)attr->pValue + 2, r.base, len); + attr->ulValueLen = len + 2; isc_buffer_forward(data, len); key->keydata.pkey = ec; - key->key_size = len; + key->key_size = len * 8; return (ISC_R_SUCCESS); } @@ -770,6 +777,7 @@ pkcs11eddsa_fetch(dst_key_t *key, const char *engine, const char *label, attr->type = CKA_EC_PARAMS; pubattr = pk11_attribute_bytype(pubec, CKA_EC_PARAMS); + INSIST(pubattr != NULL); attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); attr->ulValueLen = pubattr->ulValueLen; @@ -777,6 +785,7 @@ pkcs11eddsa_fetch(dst_key_t *key, const char *engine, const char *label, attr->type = CKA_EC_POINT; pubattr = pk11_attribute_bytype(pubec, CKA_EC_POINT); + INSIST(pubattr != NULL); attr->pValue = isc_mem_get(key->mctx, pubattr->ulValueLen); memmove(attr->pValue, pubattr->pValue, pubattr->ulValueLen); attr->ulValueLen = pubattr->ulValueLen; @@ -931,10 +940,10 @@ pkcs11eddsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) { memset(&priv, 0, sizeof(priv)); switch (key->key_alg) { case DST_ALG_ED25519: - key->key_size = DNS_KEY_ED25519SIZE; + key->key_size = DNS_KEY_ED25519SIZE * 8; break; case DST_ALG_ED448: - key->key_size = DNS_KEY_ED448SIZE; + key->key_size = DNS_KEY_ED448SIZE * 8; break; default: INSIST(0); @@ -984,7 +993,7 @@ pkcs11eddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, ec->attrcnt = 2; attr = ec->repr; attr[0].type = CKA_EC_PARAMS; - attr[1].type = CKA_VALUE; + attr[1].type = CKA_EC_POINT; ret = pk11_parse_uri(ec, label, key->mctx, OP_EDDSA); if (ret != ISC_R_SUCCESS) { @@ -1030,7 +1039,6 @@ pkcs11eddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, } PK11_RET(pkcs_C_GetAttributeValue, (pk11_ctx->session, hKey, attr, 2), DST_R_CRYPTOFAILURE); - attr[1].type = CKA_EC_POINT; keyClass = CKO_PRIVATE_KEY; PK11_RET(pkcs_C_FindObjectsInit, @@ -1054,10 +1062,10 @@ pkcs11eddsa_fromlabel(dst_key_t *key, const char *engine, const char *label, key->label = isc_mem_strdup(key->mctx, label); switch (key->key_alg) { case DST_ALG_ED25519: - key->key_size = DNS_KEY_ED25519SIZE; + key->key_size = DNS_KEY_ED25519SIZE * 8; break; case DST_ALG_ED448: - key->key_size = DNS_KEY_ED448SIZE; + key->key_size = DNS_KEY_ED448SIZE * 8; break; default: INSIST(0);