From 64cf660f872fb7aaf0d2b463e45b4c756297f743 Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 11 Sep 2020 12:51:36 +0200 Subject: daemon: Spawn 'guix authenticate' once for all. Previously, we'd spawn 'guix authenticate' once for each item that has to be signed (when exporting) or authenticated (when importing). Now, we spawn it once for all and then follow a request/reply protocol. This reduces the wall-clock time of: guix archive --export -r $(guix build coreutils -d) from 30s to 2s. * guix/scripts/authenticate.scm (sign-with-key): Return the signature instead of displaying it. Raise a &formatted-message instead of calling 'leave'. (validate-signature): Likewise. (read-command): New procedure. (define-enumerate-type, reply-code): New macros. (guix-authenticate)[send-reply]: New procedure. Change to read commands from current-input-port. * nix/libstore/local-store.cc (runAuthenticationProgram): Remove. (authenticationAgent, readInteger, readAuthenticateReply): New functions. (signHash, verifySignature): Rewrite in terms of the agent. * tests/store.scm ("import not signed"): Remove 'pk' call. ("import signed by unauthorized key"): Check the error message of C. * tests/guix-authenticate.sh: Rewrite using the new protocol. fixlet --- tests/guix-authenticate.sh | 45 ++++++++++++++++++++++++++------------------- tests/store.scm | 8 ++++---- 2 files changed, 30 insertions(+), 23 deletions(-) (limited to 'tests') diff --git a/tests/guix-authenticate.sh b/tests/guix-authenticate.sh index 773443453d..f3b36ee41d 100644 --- a/tests/guix-authenticate.sh +++ b/tests/guix-authenticate.sh @@ -28,33 +28,38 @@ rm -f "$sig" "$hash" trap 'rm -f "$sig" "$hash"' EXIT +key="$abs_top_srcdir/tests/signing-key.sec" +key_len="`echo -n $key | wc -c`" + # A hexadecimal string as long as a sha256 hash. hash="2749f0ea9f26c6c7be746a9cff8fa4c2f2a02b000070dba78429e9a11f87c6eb" +hash_len="`echo -n $hash | wc -c`" -guix authenticate sign \ - "$abs_top_srcdir/tests/signing-key.sec" \ - "$hash" > "$sig" +echo "sign $key_len:$key $hash_len:$hash" | guix authenticate > "$sig" test -f "$sig" +case "$(cat $sig)" in + "0 "*) ;; + *) echo "broken signature: $(cat $sig)" + exit 42;; +esac + +# Remove the leading "0". +sed -i "$sig" -e's/^0 //g' -hash2="`guix authenticate verify "$sig"`" -test "$hash2" = "$hash" +hash2="$(echo verify $(cat "$sig") | guix authenticate)" +test "$(echo $hash2 | cut -d : -f 2)" = "$hash" # Detect corrupt signatures. -if guix authenticate verify /dev/null -then false -else true -fi +code="$(echo "verify 5:wrong" | guix authenticate | cut -f1 -d ' ')" +test "$code" -ne 0 # Detect invalid signatures. # The signature has (payload (data ... (hash sha256 #...#))). We proceed by # modifying this hash. sed -i "$sig" \ -e's|#[A-Z0-9]\{64\}#|#0000000000000000000000000000000000000000000000000000000000000000#|g' -if guix authenticate verify "$sig" -then false -else true -fi - +code="$(echo "verify $(cat $sig)" | guix authenticate | cut -f1 -d ' ')" +test "$code" -ne 0 # Test for : make sure 'guix authenticate' produces # valid signatures when run in the C locale. @@ -63,9 +68,11 @@ hash="5eff0b55c9c5f5e87b4e34cd60a2d5654ca1eb78c7b3c67c3179fed1cff07b4c" LC_ALL=C export LC_ALL -guix authenticate sign "$abs_top_srcdir/tests/signing-key.sec" "$hash" \ - > "$sig" +echo "sign $key_len:$key $hash_len:$hash" | guix authenticate > "$sig" + +# Remove the leading "0". +sed -i "$sig" -e's/^0 //g' -guix authenticate verify "$sig" -hash2="`guix authenticate verify "$sig"`" -test "$hash2" = "$hash" +echo "verify $(cat $sig)" | guix authenticate +hash2="$(echo "verify $(cat $sig)" | guix authenticate | cut -f2 -d ' ')" +test "$(echo $hash2 | cut -d : -f 2)" = "$hash" diff --git a/tests/store.scm b/tests/store.scm index 8ff76e8f98..3a2a21a250 100644 --- a/tests/store.scm +++ b/tests/store.scm @@ -990,7 +990,7 @@ ;; Ensure 'import-paths' raises an exception. (guard (c ((store-protocol-error? c) - (and (not (zero? (store-protocol-error-status (pk 'C c)))) + (and (not (zero? (store-protocol-error-status c))) (string-contains (store-protocol-error-message c) "lacks a signature")))) (let* ((source (open-bytevector-input-port dump)) @@ -1030,9 +1030,9 @@ ;; Ensure 'import-paths' raises an exception. (guard (c ((store-protocol-error? c) - ;; XXX: The daemon-provided error message currently doesn't - ;; mention the reason of the failure. - (not (zero? (store-protocol-error-status c))))) + (and (not (zero? (store-protocol-error-status c))) + (string-contains (store-protocol-error-message c) + "unauthorized public key")))) (let* ((source (open-bytevector-input-port dump)) (imported (import-paths %store source))) (pk 'unauthorized-imported imported) -- cgit 1.4.1