aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/base32.scm31
-rw-r--r--tests/guix-authenticate.sh77
-rw-r--r--tests/store.scm117
3 files changed, 126 insertions, 99 deletions
diff --git a/tests/base32.scm b/tests/base32.scm
index 134e578633..a999edcacc 100644
--- a/tests/base32.scm
+++ b/tests/base32.scm
@@ -1,5 +1,5 @@
;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2015 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2015, 2020 Ludovic Courtès <ludo@gnu.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -23,26 +23,12 @@
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-34)
#:use-module (srfi srfi-64)
- #:use-module (ice-9 rdelim)
- #:use-module (ice-9 popen)
#:use-module (ice-9 match)
#:use-module (rnrs bytevectors)
#:use-module (rnrs io ports))
;; Test the (guix base32) module.
-(define %nix-hash
- (or (and=> (getenv "NIX_HASH")
- (match-lambda
- ("" #f)
- (val val)))
- "nix-hash"))
-
-(define %have-nix-hash?
- ;; Note: Use `system', not `system*', because of <http://bugs.gnu.org/13166>.
- (false-if-exception
- (zero? (system (string-append %nix-hash " --version")))))
-
(test-begin "base32")
(test-assert "bytevector->base32-string"
@@ -85,19 +71,4 @@
(nix-base32-string->bytevector
(string-append (make-string 51 #\a) "e"))))
-;; The following test requires `nix-hash' in $PATH.
-(unless %have-nix-hash?
- (test-skip 1))
-
-(test-assert "sha256 & bytevector->nix-base32-string"
- (let ((file (search-path %load-path "tests/test.drv")))
- (equal? (bytevector->nix-base32-string
- (sha256 (call-with-input-file file get-bytevector-all)))
- (let* ((c (format #f "~a --type sha256 --base32 --flat \"~a\""
- %nix-hash file))
- (p (open-input-pipe c))
- (l (read-line p)))
- (close-pipe p)
- l))))
-
(test-end)
diff --git a/tests/guix-authenticate.sh b/tests/guix-authenticate.sh
index 72c3d161d7..f3b36ee41d 100644
--- a/tests/guix-authenticate.sh
+++ b/tests/guix-authenticate.sh
@@ -1,5 +1,5 @@
# GNU Guix --- Functional package management for GNU
-# Copyright © 2013, 2014 Ludovic Courtès <ludo@gnu.org>
+# Copyright © 2013, 2014, 2020 Ludovic Courtès <ludo@gnu.org>
#
# This file is part of GNU Guix.
#
@@ -28,68 +28,51 @@ 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.
-echo "2749f0ea9f26c6c7be746a9cff8fa4c2f2a02b000070dba78429e9a11f87c6eb" \
- > "$hash"
+hash="2749f0ea9f26c6c7be746a9cff8fa4c2f2a02b000070dba78429e9a11f87c6eb"
+hash_len="`echo -n $hash | wc -c`"
-guix authenticate rsautl -sign \
- -inkey "$abs_top_srcdir/tests/signing-key.sec" \
- -in "$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 rsautl -verify \
- -inkey $abs_top_srcdir/tests/signing-key.pub \
- -pubin -in $sig`"
-test "$hash2" = `cat "$hash"`
-
-# Same thing in a pipeline, using the command line syntax that Nix/Crypto.pm
-# uses.
-hash2="` \
- cat "$hash" \
- | guix authenticate rsautl -sign \
- -inkey "$abs_top_srcdir/tests/signing-key.sec" \
- | guix authenticate rsautl -verify \
- -inkey $abs_top_srcdir/tests/signing-key.pub \
- -pubin`"
-test "$hash2" = `cat "$hash"`
+hash2="$(echo verify $(cat "$sig") | guix authenticate)"
+test "$(echo $hash2 | cut -d : -f 2)" = "$hash"
# Detect corrupt signatures.
-if guix authenticate rsautl -verify \
- -inkey "$abs_top_srcdir/tests/signing-key.pub" \
- -pubin -in /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 rsautl -verify \
- -inkey "$abs_top_srcdir/tests/signing-key.pub" \
- -pubin -in "$sig"
-then false
-else true
-fi
-
+code="$(echo "verify $(cat $sig)" | guix authenticate | cut -f1 -d ' ')"
+test "$code" -ne 0
# Test for <http://bugs.gnu.org/17312>: make sure 'guix authenticate' produces
# valid signatures when run in the C locale.
-echo "5eff0b55c9c5f5e87b4e34cd60a2d5654ca1eb78c7b3c67c3179fed1cff07b4c" \
- > "$hash"
+hash="5eff0b55c9c5f5e87b4e34cd60a2d5654ca1eb78c7b3c67c3179fed1cff07b4c"
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"`
+echo "sign $key_len:$key $hash_len:$hash" | guix authenticate > "$sig"
+
+# Remove the leading "0".
+sed -i "$sig" -e's/^0 //g'
+
+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 ee3e01f33b..38051bf5e5 100644
--- a/tests/store.scm
+++ b/tests/store.scm
@@ -23,6 +23,8 @@
#:use-module (guix utils)
#:use-module (guix monads)
#:use-module ((gcrypt hash) #:prefix gcrypt:)
+ #:use-module ((gcrypt pk-crypto) #:prefix gcrypt:)
+ #:use-module (guix pki)
#:use-module (guix base32)
#:use-module (guix packages)
#:use-module (guix derivations)
@@ -141,6 +143,15 @@
(string-append (%store-prefix) "/"
(make-string 32 #\e) "-foobar"))))
+(test-equal "with-store, multiple values" ;<https://bugs.gnu.org/42912>
+ '(1 2 3)
+ (call-with-values
+ (lambda ()
+ (with-store s
+ (add-text-to-store s "foo" "bar")
+ (values 1 2 3)))
+ list))
+
(test-assert "valid-path? error"
(with-store s
(guard (c ((store-protocol-error? c) #t))
@@ -212,30 +223,22 @@
;;(> freed 0)
(not (file-exists? p))))))
-(test-assert "add-text-to-store vs. delete-paths"
- ;; Before, 'add-text-to-store' would return PATH2 without noticing that it
- ;; is no longer valid.
+(test-assert "add-text-to-store/add-to-store vs. delete-paths"
+ ;; Before, 'add-text-to-store' and 'add-to-store' would return the same
+ ;; store item without noticing that it is no longer valid.
(with-store store
(let* ((text (random-text))
- (path (add-text-to-store store "delete-me" text))
- (deleted (delete-paths store (list path)))
- (path2 (add-text-to-store store "delete-me" text)))
- (and (string=? path path2)
- (equal? deleted (list path))
- (valid-path? store path)
- (file-exists? path)))))
-
-(test-assert "add-to-store vs. delete-paths"
- ;; Same as above.
- (with-store store
- (let* ((file (search-path %load-path "guix.scm"))
- (path (add-to-store store "delete-me" #t "sha256" file))
- (deleted (delete-paths store (list path)))
- (path2 (add-to-store store "delete-me" #t "sha256" file)))
- (and (string=? path path2)
- (equal? deleted (list path))
- (valid-path? store path)
- (file-exists? path)))))
+ (file (search-path %load-path "guix.scm"))
+ (path1 (add-text-to-store store "delete-me" text))
+ (path2 (add-to-store store "delete-me" #t "sha256" file))
+ (deleted (delete-paths store (list path1 path2))))
+ (and (string=? path1 (add-text-to-store store "delete-me" text))
+ (string=? path2 (add-to-store store "delete-me" #t "sha256" file))
+ (lset= string=? deleted (list path1 path2))
+ (valid-path? store path1)
+ (valid-path? store path2)
+ (file-exists? path1)
+ (file-exists? path2)))))
(test-equal "add-file-tree-to-store"
`(42
@@ -957,6 +960,76 @@
(list out1 out2))))
#:guile-for-build (%guile-for-build)))
+
+(test-assert "import not signed"
+ (let* ((text (random-text))
+ (file (add-file-tree-to-store %store
+ `("tree" directory
+ ("text" regular (data ,text))
+ ("link" symlink "text"))))
+ (dump (call-with-bytevector-output-port
+ (lambda (port)
+ (write-int 1 port) ;start
+
+ (write-file file port) ;contents
+ (write-int #x4558494e port) ;%export-magic
+ (write-string file port) ;store item
+ (write-string-list '() port) ;references
+ (write-string "" port) ;deriver
+ (write-int 0 port) ;not signed
+
+ (write-int 0 port))))) ;done
+
+ ;; Ensure 'import-paths' raises an exception.
+ (guard (c ((store-protocol-error? 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))
+ (imported (import-paths %store source)))
+ (pk 'unsigned-imported imported)
+ #f))))
+
+(test-assert "import signed by unauthorized key"
+ (let* ((text (random-text))
+ (file (add-file-tree-to-store %store
+ `("tree" directory
+ ("text" regular (data ,text))
+ ("link" symlink "text"))))
+ (key (gcrypt:generate-key
+ (gcrypt:string->canonical-sexp
+ "(genkey (ecdsa (curve Ed25519) (flags rfc6979)))")))
+ (dump (call-with-bytevector-output-port
+ (lambda (port)
+ (write-int 1 port) ;start
+
+ (write-file file port) ;contents
+ (write-int #x4558494e port) ;%export-magic
+ (write-string file port) ;store item
+ (write-string-list '() port) ;references
+ (write-string "" port) ;deriver
+ (write-int 1 port) ;signed
+ (write-string (gcrypt:canonical-sexp->string
+ (signature-sexp
+ (gcrypt:bytevector->hash-data
+ (gcrypt:sha256 #vu8(0 1 2))
+ #:key-type 'ecc)
+ (gcrypt:find-sexp-token key 'private-key)
+ (gcrypt:find-sexp-token key 'public-key)))
+ port)
+
+ (write-int 0 port))))) ;done
+
+ ;; Ensure 'import-paths' raises an exception.
+ (guard (c ((store-protocol-error? 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)
+ #f))))
+
(test-assert "import corrupt path"
(let* ((text (random-text))
(file (add-text-to-store %store "text" text))