authenticate: Allow signatures with binary data to be written to stdout.

Fixes <http://bugs.gnu.org/17312>.

* guix/scripts/authenticate.scm (guix-authenticate): Add calls to
  'set-port-encoding!' and 'set-port-conversion-strategy!'.  Wrap body
  in 'with-fluids' form that sets '%default-port-encoding' and
  '%default-port-conversion-strategy'.
* tests/guix-authenticate.sh: Add test.
* tests/pk-crypto.scm ("hash corrupt due to restrictive locale
  encoding"): Add reference to bug.
This commit is contained in:
Ludovic Courtès 2014-04-22 11:30:51 +02:00
parent 6030d8493e
commit 6f69588529
3 changed files with 54 additions and 24 deletions

View File

@ -89,30 +89,39 @@ to stdout upon success."
;;; ;;;
(define (guix-authenticate . args) (define (guix-authenticate . args)
(match args ;; Signature sexps written to stdout may contain binary data, so force
;; As invoked by guix-daemon. ;; ISO-8859-1 encoding so that things are not mangled. See
(("rsautl" "-sign" "-inkey" key "-in" hash-file) ;; <http://bugs.gnu.org/17312> for details.
(call-with-input-file hash-file (set-port-encoding! (current-output-port) "ISO-8859-1")
(lambda (port) (set-port-conversion-strategy! (current-output-port) 'error)
(sign-with-key key port))))
;; As invoked by Nix/Crypto.pm (used by Hydra.) ;; Same goes for input ports.
(("rsautl" "-sign" "-inkey" key) (with-fluids ((%default-port-encoding "ISO-8859-1")
(sign-with-key key (current-input-port))) (%default-port-conversion-strategy 'error))
;; As invoked by guix-daemon. (match args
(("rsautl" "-verify" "-inkey" _ "-pubin" "-in" signature-file) ;; As invoked by guix-daemon.
(call-with-input-file signature-file (("rsautl" "-sign" "-inkey" key "-in" hash-file)
(lambda (port) (call-with-input-file hash-file
(validate-signature port)))) (lambda (port)
;; As invoked by Nix/Crypto.pm (used by Hydra.) (sign-with-key key port))))
(("rsautl" "-verify" "-inkey" _ "-pubin") ;; As invoked by Nix/Crypto.pm (used by Hydra.)
(validate-signature (current-input-port))) (("rsautl" "-sign" "-inkey" key)
(("--help") (sign-with-key key (current-input-port)))
(display (_ "Usage: guix authenticate OPTION... ;; As invoked by guix-daemon.
(("rsautl" "-verify" "-inkey" _ "-pubin" "-in" signature-file)
(call-with-input-file signature-file
(lambda (port)
(validate-signature port))))
;; As invoked by Nix/Crypto.pm (used by Hydra.)
(("rsautl" "-verify" "-inkey" _ "-pubin")
(validate-signature (current-input-port)))
(("--help")
(display (_ "Usage: guix authenticate OPTION...
Sign or verify the signature on the given file. This tool is meant to Sign or verify the signature on the given file. This tool is meant to
be used internally by 'guix-daemon'.\n"))) be used internally by 'guix-daemon'.\n")))
(("--version") (("--version")
(show-version-and-exit "guix authenticate")) (show-version-and-exit "guix authenticate"))
(else (else
(leave (_ "wrong arguments"))))) (leave (_ "wrong arguments"))))))
;;; authenticate.scm ends here ;;; authenticate.scm ends here

View File

@ -72,3 +72,24 @@ if guix authenticate rsautl -verify \
then false then false
else true else true
fi fi
# Test for <http://bugs.gnu.org/17312>: make sure 'guix authenticate' produces
# valid signatures when run in the C locale.
echo "5eff0b55c9c5f5e87b4e34cd60a2d5654ca1eb78c7b3c67c3179fed1cff07b4c" \
> "$hash"
LC_ALL=C
export LC_ALL
guix authenticate rsautl -sign \
-inkey "$abs_top_srcdir/tests/signing-key.sec" \
-in "$hash" > "$sig"
guix authenticate rsautl -verify \
-inkey "$abs_top_srcdir/tests/signing-key.pub" \
-pubin -in "$sig"
hash2="`guix authenticate rsautl -verify \
-inkey $abs_top_srcdir/tests/signing-key.pub \
-pubin -in $sig`"
test "$hash2" = `cat "$hash"`

View File

@ -153,7 +153,7 @@
;; In Guix up to 0.6 included this test would fail because at some point ;; In Guix up to 0.6 included this test would fail because at some point
;; the hash value would be cropped to ASCII. In practice 'guix ;; the hash value would be cropped to ASCII. In practice 'guix
;; authenticate' would produce invalid signatures that would fail ;; authenticate' would produce invalid signatures that would fail
;; signature verification. ;; signature verification. See <http://bugs.gnu.org/17312>.
(let ((locale (setlocale LC_ALL))) (let ((locale (setlocale LC_ALL)))
(dynamic-wind (dynamic-wind
(lambda () (lambda ()