* [bug#50750] [PATCH 2/4] tests: Move keys into ./tests/keys/ and add a third ed25519 key.
2021-09-28 0:40 ` [bug#50750] [PATCH 1/4] tests: Smarten up git repository testing framework Attila Lendvai
@ 2021-09-28 0:40 ` Attila Lendvai
2021-09-28 0:40 ` [bug#50750] [PATCH 3/4] tests: Add failing test for .guix-authorizations and channel intro Attila Lendvai
2021-09-28 0:40 ` [bug#50750] [PATCH 4/4] guix: git-authenticate: Fix authenticate-repository Attila Lendvai
2 siblings, 0 replies; 11+ messages in thread
From: Attila Lendvai @ 2021-09-28 0:40 UTC (permalink / raw)
To: 50750; +Cc: Attila Lendvai
The third key will be used in in upcoming commit.
Rename public keys to .pub.
* guix/tests/gnupg.scm (%ed25519-3-public-key-file): New variable.
(%ed25519-3-secret-key-file): New variable.
(%ed25519-2-public-key-file): Renamed from %ed25519bis-public-key-file.
(%ed25519-2-secret-key-file): Renamed from %ed25519bis-secret-key-file.
* tests/keys/ed25519-3.key: New file.
* tests/keys/ed25519-3.sec: New file.
---
Makefile.am | 20 +++++-----
build-aux/test-env.in | 6 +--
guix/tests/gnupg.scm | 22 ++++++----
tests/channels.scm | 18 ++++-----
tests/git-authenticate.scm | 23 +++++------
tests/guix-authenticate.sh | 4 +-
tests/{civodul.key => keys/civodul.pub} | 0
tests/{dsa.key => keys/dsa.pub} | 0
tests/{ed25519bis.key => keys/ed25519-2.pub} | 0
tests/{ed25519bis.sec => keys/ed25519-2.sec} | 0
tests/keys/ed25519-3.pub | 9 +++++
tests/keys/ed25519-3.sec | 10 +++++
tests/{ed25519.key => keys/ed25519.pub} | 0
tests/{ => keys}/ed25519.sec | 0
tests/{rsa.key => keys/rsa.pub} | 0
tests/{ => keys}/signing-key.pub | 0
tests/{ => keys}/signing-key.sec | 0
tests/openpgp.scm | 42 +++++++++++---------
18 files changed, 93 insertions(+), 61 deletions(-)
rename tests/{civodul.key => keys/civodul.pub} (100%)
rename tests/{dsa.key => keys/dsa.pub} (100%)
rename tests/{ed25519bis.key => keys/ed25519-2.pub} (100%)
rename tests/{ed25519bis.sec => keys/ed25519-2.sec} (100%)
create mode 100644 tests/keys/ed25519-3.pub
create mode 100644 tests/keys/ed25519-3.sec
rename tests/{ed25519.key => keys/ed25519.pub} (100%)
rename tests/{ => keys}/ed25519.sec (100%)
rename tests/{rsa.key => keys/rsa.pub} (100%)
rename tests/{ => keys}/signing-key.pub (100%)
rename tests/{ => keys}/signing-key.sec (100%)
diff --git a/Makefile.am b/Makefile.am
index 042cf28464..c0a5b14f02 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -640,16 +640,18 @@ EXTRA_DIST += \
build-aux/update-guix-package.scm \
build-aux/update-NEWS.scm \
tests/test.drv \
- tests/signing-key.pub \
- tests/signing-key.sec \
tests/cve-sample.json \
- tests/civodul.key \
- tests/rsa.key \
- tests/dsa.key \
- tests/ed25519.key \
- tests/ed25519.sec \
- tests/ed25519bis.key \
- tests/ed25519bis.sec \
+ tests/keys/signing-key.pub \
+ tests/keys/signing-key.sec \
+ tests/keys/civodul.pub \
+ tests/keys/rsa.pub \
+ tests/keys/dsa.pub \
+ tests/keys/ed25519.pub \
+ tests/keys/ed25519.sec \
+ tests/keys/ed25519-2.pub \
+ tests/keys/ed25519-2.sec \
+ tests/keys/ed25519-3.pub \
+ tests/keys/ed25519-3.sec \
build-aux/config.rpath \
bootstrap \
doc/build.scm \
diff --git a/build-aux/test-env.in b/build-aux/test-env.in
index 7efc43206c..ca786437e9 100644
--- a/build-aux/test-env.in
+++ b/build-aux/test-env.in
@@ -73,9 +73,9 @@ then
# Copy the keys so that the secret key has the right permissions (the
# daemon errors out when this is not the case.)
mkdir -p "$GUIX_CONFIGURATION_DIRECTORY"
- cp "@abs_top_srcdir@/tests/signing-key.sec" \
- "@abs_top_srcdir@/tests/signing-key.pub" \
- "$GUIX_CONFIGURATION_DIRECTORY"
+ cp "@abs_top_srcdir@/tests/keys/signing-key.sec" \
+ "@abs_top_srcdir@/tests/keys/signing-key.pub" \
+ "$GUIX_CONFIGURATION_DIRECTORY"
chmod 400 "$GUIX_CONFIGURATION_DIRECTORY/signing-key.sec"
fi
diff --git a/guix/tests/gnupg.scm b/guix/tests/gnupg.scm
index c7630db912..09f02a2b67 100644
--- a/guix/tests/gnupg.scm
+++ b/guix/tests/gnupg.scm
@@ -28,8 +28,10 @@
%ed25519-public-key-file
%ed25519-secret-key-file
- %ed25519bis-public-key-file
- %ed25519bis-secret-key-file
+ %ed25519-2-public-key-file
+ %ed25519-2-secret-key-file
+ %ed25519-3-public-key-file
+ %ed25519-3-secret-key-file
read-openpgp-packet
key-fingerprint
@@ -64,13 +66,17 @@ process is terminated afterwards."
(call-with-fresh-gnupg-setup imported (lambda () exp ...)))
(define %ed25519-public-key-file
- (search-path %load-path "tests/ed25519.key"))
+ (search-path %load-path "tests/keys/ed25519.pub"))
(define %ed25519-secret-key-file
- (search-path %load-path "tests/ed25519.sec"))
-(define %ed25519bis-public-key-file
- (search-path %load-path "tests/ed25519bis.key"))
-(define %ed25519bis-secret-key-file
- (search-path %load-path "tests/ed25519bis.sec"))
+ (search-path %load-path "tests/keys/ed25519.sec"))
+(define %ed25519-2-public-key-file
+ (search-path %load-path "tests/keys/ed25519-2.pub"))
+(define %ed25519-2-secret-key-file
+ (search-path %load-path "tests/keys/ed25519-2.sec"))
+(define %ed25519-3-public-key-file
+ (search-path %load-path "tests/keys/ed25519-3.pub"))
+(define %ed25519-3-secret-key-file
+ (search-path %load-path "tests/keys/ed25519-3.sec"))
(define (read-openpgp-packet file)
(get-openpgp-packet
diff --git a/tests/channels.scm b/tests/channels.scm
index 3e82315b0c..d45c450241 100644
--- a/tests/channels.scm
+++ b/tests/channels.scm
@@ -480,8 +480,8 @@
#t
(with-fresh-gnupg-setup (list %ed25519-public-key-file
%ed25519-secret-key-file
- %ed25519bis-public-key-file
- %ed25519bis-secret-key-file)
+ %ed25519-2-public-key-file
+ %ed25519-2-secret-key-file)
(with-temporary-git-repository directory
`((add ".guix-channel"
,(object->string
@@ -507,7 +507,7 @@
(commit-id-string commit1)
(openpgp-public-key-fingerprint
(read-openpgp-packet
- %ed25519bis-public-key-file)))) ;different key
+ %ed25519-2-public-key-file)))) ;different key
(channel (channel (name 'example)
(url (string-append "file://" directory))
(introduction intro))))
@@ -519,7 +519,7 @@
(oid->string (commit-id commit1))
(key-fingerprint %ed25519-public-key-file)
(key-fingerprint
- %ed25519bis-public-key-file))))))
+ %ed25519-2-public-key-file))))))
(authenticate-channel channel directory
(commit-id-string commit2)
#:keyring-reference-prefix "")
@@ -530,8 +530,8 @@
#t
(with-fresh-gnupg-setup (list %ed25519-public-key-file
%ed25519-secret-key-file
- %ed25519bis-public-key-file
- %ed25519bis-secret-key-file)
+ %ed25519-2-public-key-file
+ %ed25519-2-secret-key-file)
(with-temporary-git-repository directory
`((add ".guix-channel"
,(object->string
@@ -552,12 +552,12 @@
(signer ,(key-fingerprint %ed25519-public-key-file)))
(add "c.txt" "C")
(commit "third commit"
- (signer ,(key-fingerprint %ed25519bis-public-key-file)))
+ (signer ,(key-fingerprint %ed25519-2-public-key-file)))
(branch "channel-keyring")
(checkout "channel-keyring")
(add "signer.key" ,(call-with-input-file %ed25519-public-key-file
get-string-all))
- (add "other.key" ,(call-with-input-file %ed25519bis-public-key-file
+ (add "other.key" ,(call-with-input-file %ed25519-2-public-key-file
get-string-all))
(commit "keyring commit")
(checkout "master"))
@@ -588,7 +588,7 @@
(unauthorized-commit-error-signing-key c))
(openpgp-public-key-fingerprint
(read-openpgp-packet
- %ed25519bis-public-key-file))))))
+ %ed25519-2-public-key-file))))))
(authenticate-channel channel directory
(commit-id-string commit3)
#:keyring-reference-prefix "")
diff --git a/tests/git-authenticate.scm b/tests/git-authenticate.scm
index d87eacc659..f66ef191b0 100644
--- a/tests/git-authenticate.scm
+++ b/tests/git-authenticate.scm
@@ -161,14 +161,14 @@
(test-assert "signed commits, .guix-authorizations, unauthorized merge"
(with-fresh-gnupg-setup (list %ed25519-public-key-file
%ed25519-secret-key-file
- %ed25519bis-public-key-file
- %ed25519bis-secret-key-file)
+ %ed25519-2-public-key-file
+ %ed25519-2-secret-key-file)
(with-temporary-git-repository directory
`((add "signer1.key"
,(call-with-input-file %ed25519-public-key-file
get-string-all))
(add "signer2.key"
- ,(call-with-input-file %ed25519bis-public-key-file
+ ,(call-with-input-file %ed25519-2-public-key-file
get-string-all))
(add ".guix-authorizations"
,(object->string
@@ -184,7 +184,7 @@
(checkout "devel")
(add "devel/1.txt" "1")
(commit "first devel commit"
- (signer ,(key-fingerprint %ed25519bis-public-key-file)))
+ (signer ,(key-fingerprint %ed25519-2-public-key-file)))
(checkout "master")
(add "b.txt" "B")
(commit "second commit"
@@ -203,7 +203,7 @@
(openpgp-public-key-fingerprint
(unauthorized-commit-error-signing-key c))
(openpgp-public-key-fingerprint
- (read-openpgp-packet %ed25519bis-public-key-file)))))
+ (read-openpgp-packet %ed25519-2-public-key-file)))))
(and (authenticate-commits repository (list master1 master2)
#:keyring-reference "master")
@@ -230,14 +230,14 @@
(test-assert "signed commits, .guix-authorizations, authorized merge"
(with-fresh-gnupg-setup (list %ed25519-public-key-file
%ed25519-secret-key-file
- %ed25519bis-public-key-file
- %ed25519bis-secret-key-file)
+ %ed25519-2-public-key-file
+ %ed25519-2-secret-key-file)
(with-temporary-git-repository directory
`((add "signer1.key"
,(call-with-input-file %ed25519-public-key-file
get-string-all))
(add "signer2.key"
- ,(call-with-input-file %ed25519bis-public-key-file
+ ,(call-with-input-file %ed25519-2-public-key-file
get-string-all))
(add ".guix-authorizations"
,(object->string
@@ -258,12 +258,12 @@
%ed25519-public-key-file)
(name "Alice"))
(,(key-fingerprint
- %ed25519bis-public-key-file))))))
+ %ed25519-2-public-key-file))))))
(commit "first devel commit"
(signer ,(key-fingerprint %ed25519-public-key-file)))
(add "devel/2.txt" "2")
(commit "second devel commit"
- (signer ,(key-fingerprint %ed25519bis-public-key-file)))
+ (signer ,(key-fingerprint %ed25519-2-public-key-file)))
(checkout "master")
(add "b.txt" "B")
(commit "second commit"
@@ -273,7 +273,7 @@
;; After the merge, the second signer is authorized.
(add "c.txt" "C")
(commit "third commit"
- (signer ,(key-fingerprint %ed25519bis-public-key-file))))
+ (signer ,(key-fingerprint %ed25519-2-public-key-file))))
(with-repository directory repository
(let ((master1 (find-commit repository "first commit"))
(master2 (find-commit repository "second commit"))
@@ -328,4 +328,3 @@
'failed)))))))
(test-end "git-authenticate")
-
diff --git a/tests/guix-authenticate.sh b/tests/guix-authenticate.sh
index 3a05b232c1..0de6da1878 100644
--- a/tests/guix-authenticate.sh
+++ b/tests/guix-authenticate.sh
@@ -28,7 +28,7 @@ rm -f "$sig" "$hash"
trap 'rm -f "$sig" "$hash"' EXIT
-key="$abs_top_srcdir/tests/signing-key.sec"
+key="$abs_top_srcdir/tests/keys/signing-key.sec"
key_len="`echo -n $key | wc -c`"
# A hexadecimal string as long as a sha256 hash.
@@ -67,7 +67,7 @@ test "$code" -ne 0
# encoded independently of the current locale: <https://bugs.gnu.org/43421>.
hash="636166e9636166e9636166e9636166e9636166e9636166e9636166e9636166e9"
latin1_cafe="caf$(printf '\351')"
-echo "sign 21:tests/signing-key.sec 64:$hash" | guix authenticate \
+echo "sign 26:tests/keys/signing-key.sec 64:$hash" | guix authenticate \
| LC_ALL=C grep "hash sha256 \"$latin1_cafe"
# Test for <http://bugs.gnu.org/17312>: make sure 'guix authenticate' produces
diff --git a/tests/civodul.key b/tests/keys/civodul.pub
similarity index 100%
rename from tests/civodul.key
rename to tests/keys/civodul.pub
diff --git a/tests/dsa.key b/tests/keys/dsa.pub
similarity index 100%
rename from tests/dsa.key
rename to tests/keys/dsa.pub
diff --git a/tests/ed25519bis.key b/tests/keys/ed25519-2.pub
similarity index 100%
rename from tests/ed25519bis.key
rename to tests/keys/ed25519-2.pub
diff --git a/tests/ed25519bis.sec b/tests/keys/ed25519-2.sec
similarity index 100%
rename from tests/ed25519bis.sec
rename to tests/keys/ed25519-2.sec
diff --git a/tests/keys/ed25519-3.pub b/tests/keys/ed25519-3.pub
new file mode 100644
index 0000000000..72f311984c
--- /dev/null
+++ b/tests/keys/ed25519-3.pub
@@ -0,0 +1,9 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mDMEYVH/7xYJKwYBBAHaRw8BAQdALMLeUhjEG2/UPCJj2j/debFwwAK5gT3G0l5d
+ILfFldm0FTxleGFtcGxlQGV4YW1wbGUuY29tPoiWBBMWCAA+FiEEjO6M85jMSK68
+7tINGBzA7NyoagkFAmFR/+8CGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgEC
+F4AACgkQGBzA7Nyoagl3lgEAw6yqIlX11lTqwxBGhZk/Oy34O13cbJSZCGv+m0ja
++hcA/3DCNOmT+oXjgO/w6enQZUQ1m/d6dUjCc2wOLlLz+ZoG
+=+r3i
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/keys/ed25519-3.sec b/tests/keys/ed25519-3.sec
new file mode 100644
index 0000000000..04128a4131
--- /dev/null
+++ b/tests/keys/ed25519-3.sec
@@ -0,0 +1,10 @@
+-----BEGIN PGP PRIVATE KEY BLOCK-----
+
+lFgEYVH/7xYJKwYBBAHaRw8BAQdALMLeUhjEG2/UPCJj2j/debFwwAK5gT3G0l5d
+ILfFldkAAP92goSbbzQ0ttElr9lr5Cm6rmQtqUZ2Cu/Jk9fvfZROwxI0tBU8ZXhh
+bXBsZUBleGFtcGxlLmNvbT6IlgQTFggAPhYhBIzujPOYzEiuvO7SDRgcwOzcqGoJ
+BQJhUf/vAhsDBQkDwmcABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEBgcwOzc
+qGoJd5YBAMOsqiJV9dZU6sMQRoWZPzst+Dtd3GyUmQhr/ptI2voXAP9wwjTpk/qF
+44Dv8Onp0GVENZv3enVIwnNsDi5S8/maBg==
+=EmOt
+-----END PGP PRIVATE KEY BLOCK-----
diff --git a/tests/ed25519.key b/tests/keys/ed25519.pub
similarity index 100%
rename from tests/ed25519.key
rename to tests/keys/ed25519.pub
diff --git a/tests/ed25519.sec b/tests/keys/ed25519.sec
similarity index 100%
rename from tests/ed25519.sec
rename to tests/keys/ed25519.sec
diff --git a/tests/rsa.key b/tests/keys/rsa.pub
similarity index 100%
rename from tests/rsa.key
rename to tests/keys/rsa.pub
diff --git a/tests/signing-key.pub b/tests/keys/signing-key.pub
similarity index 100%
rename from tests/signing-key.pub
rename to tests/keys/signing-key.pub
diff --git a/tests/signing-key.sec b/tests/keys/signing-key.sec
similarity index 100%
rename from tests/signing-key.sec
rename to tests/keys/signing-key.sec
diff --git a/tests/openpgp.scm b/tests/openpgp.scm
index c2be26fa49..1f20466772 100644
--- a/tests/openpgp.scm
+++ b/tests/openpgp.scm
@@ -59,18 +59,22 @@ vBSFjNSiVHsuAA==
(define %civodul-fingerprint
"3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5")
-(define %civodul-key-id #x090B11993D9AEBB5) ;civodul.key
-
-;; Test keys. They were generated in a container along these lines:
-;; guix environment -CP --ad-hoc gnupg pinentry
-;; then, within the container:
-;; mkdir ~/.gnupg
-;; echo pinentry-program ~/.guix-profile/bin/pinentry-tty > ~/.gnupg/gpg-agent.conf
-;; gpg --quick-gen-key '<ludo+test-rsa@chbouib.org>' rsa
-;; or similar.
-(define %rsa-key-id #xAE25DA2A70DEED59) ;rsa.key
-(define %dsa-key-id #x587918047BE8BD2C) ;dsa.key
-(define %ed25519-key-id #x771F49CBFAAE072D) ;ed25519.key
+(define %civodul-key-id #x090B11993D9AEBB5) ;civodul.pub
+
+#|
+Test keys in ./tests/keys. They were generated in a container along these lines:
+ guix environment -CP --ad-hoc gnupg pinentry coreutils
+then, within the container:
+ mkdir ~/.gnupg && chmod -R og-rwx ~/.gnupg
+ gpg --batch --passphrase '' --quick-gen-key '<example@example.com>' ed25519
+ gpg --armor --export example@example.com
+ gpg --armor --export-secret-key example@example.com
+ # echo pinentry-program ~/.guix-profile/bin/pinentry-curses > ~/.gnupg/gpg-agent.conf
+or similar.
+|#
+(define %rsa-key-id #xAE25DA2A70DEED59) ;rsa.pub
+(define %dsa-key-id #x587918047BE8BD2C) ;dsa.pub
+(define %ed25519-key-id #x771F49CBFAAE072D) ;ed25519.pub
(define %rsa-key-fingerprint
(base16-string->bytevector
@@ -168,7 +172,7 @@ Pz7oopeN72xgggYUNT37ezqN3MeCqw0=
(not (port-ascii-armored? (open-bytevector-input-port %binary-sample))))
(test-assert "get-openpgp-keyring"
- (let* ((key (search-path %load-path "tests/civodul.key"))
+ (let* ((key (search-path %load-path "tests/keys/civodul.pub"))
(keyring (get-openpgp-keyring
(open-bytevector-input-port
(call-with-input-file key read-radix-64)))))
@@ -228,8 +232,10 @@ Pz7oopeN72xgggYUNT37ezqN3MeCqw0=
(verify-openpgp-signature signature keyring
(open-input-string "Hello!\n"))))
(list status (openpgp-public-key-id key)))))
- (list "tests/rsa.key" "tests/dsa.key"
- "tests/ed25519.key" "tests/ed25519.key" "tests/ed25519.key")
+ (list "tests/keys/rsa.pub" "tests/keys/dsa.pub"
+ "tests/keys/ed25519.pub"
+ "tests/keys/ed25519.pub"
+ "tests/keys/ed25519.pub")
(list %hello-signature/rsa %hello-signature/dsa
%hello-signature/ed25519/sha256
%hello-signature/ed25519/sha512
@@ -248,9 +254,9 @@ Pz7oopeN72xgggYUNT37ezqN3MeCqw0=
(call-with-input-file key read-radix-64))
keyring)))
%empty-keyring
- '("tests/rsa.key" "tests/dsa.key"
- "tests/ed25519.key" "tests/ed25519.key"
- "tests/ed25519.key"))))
+ '("tests/keys/rsa.pub" "tests/keys/dsa.pub"
+ "tests/keys/ed25519.pub" "tests/keys/ed25519.pub"
+ "tests/keys/ed25519.pub"))))
(map (lambda (signature)
(let ((signature (string->openpgp-packet signature)))
(let-values (((status key)
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [bug#50750] [PATCH 3/4] tests: Add failing test for .guix-authorizations and channel intro.
2021-09-28 0:40 ` [bug#50750] [PATCH 1/4] tests: Smarten up git repository testing framework Attila Lendvai
2021-09-28 0:40 ` [bug#50750] [PATCH 2/4] tests: Move keys into ./tests/keys/ and add a third ed25519 key Attila Lendvai
@ 2021-09-28 0:40 ` Attila Lendvai
2021-09-28 0:40 ` [bug#50750] [PATCH 4/4] guix: git-authenticate: Fix authenticate-repository Attila Lendvai
2 siblings, 0 replies; 11+ messages in thread
From: Attila Lendvai @ 2021-09-28 0:40 UTC (permalink / raw)
To: 50750; +Cc: Attila Lendvai
Will be fixed in a subsequent commit.
* tests/git-authenticate.scm: New test "signed commits, .guix-authorizations,
channel-introduction".
---
tests/git-authenticate.scm | 112 +++++++++++++++++++++++++++++++++++++
1 file changed, 112 insertions(+)
diff --git a/tests/git-authenticate.scm b/tests/git-authenticate.scm
index f66ef191b0..91eaac73c1 100644
--- a/tests/git-authenticate.scm
+++ b/tests/git-authenticate.scm
@@ -24,6 +24,7 @@
#:use-module (guix tests git)
#:use-module (guix tests gnupg)
#:use-module (guix build utils)
+ #:use-module ((ice-9 control) #:select (let/ec))
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-34)
#:use-module (srfi srfi-64)
@@ -226,6 +227,117 @@
#:keyring-reference "master")
#f)))))))
+(unless (gpg+git-available?) (test-skip 1))
+(test-assert "signed commits, .guix-authorizations, channel-introduction"
+ (let* ((result #true)
+ (key1 %ed25519-public-key-file)
+ (key2 %ed25519-2-public-key-file)
+ (key3 %ed25519-3-public-key-file))
+ (with-fresh-gnupg-setup (list key1 %ed25519-secret-key-file
+ key2 %ed25519-2-secret-key-file
+ key3 %ed25519-3-secret-key-file)
+ (with-temporary-git-repository dir
+ `((checkout "keyring" orphan)
+ (add "signer1.key" ,(call-with-input-file key1 get-string-all))
+ (add "signer2.key" ,(call-with-input-file key2 get-string-all))
+ (add "signer3.key" ,(call-with-input-file key3 get-string-all))
+ (commit "keyring commit")
+
+ (checkout "main" orphan)
+ (add "noise0")
+ (add ".guix-authorizations"
+ ,(object->string
+ `(authorizations
+ (version 0)
+ ((,(key-fingerprint key1) (name "Alice"))))))
+ (commit "commit 0" (signer ,(key-fingerprint key3)))
+ (add "noise1")
+ (commit "commit 1" (signer ,(key-fingerprint key1)))
+ (add "noise2")
+ (commit "commit 2" (signer ,(key-fingerprint key1))))
+ (with-repository dir repo
+ (let* ((commit-0 (find-commit repo "commit 0"))
+ (check-from
+ (lambda* (commit #:key (should-fail? #false) (key key1)
+ (historical-authorizations
+ ;; key3 is trusted to authorize commit 0
+ (list (key-fingerprint-vector key3))))
+ (guard (c ((unauthorized-commit-error? c)
+ (if should-fail?
+ c
+ (let ((port (current-output-port)))
+ (format port "FAILURE: Unexpected exception at commit '~s':~%"
+ commit)
+ (print-exception port (stack-ref (make-stack #t) 1)
+ c (exception-args c))
+ (set! result #false)
+ '()))))
+ (format #true "~%~%Checking ~s, should-fail? ~s, repo commits:~%"
+ commit should-fail?)
+ ;; to be able to inspect in the logs
+ (invoke "git" "-C" dir "log" "--reverse" "--pretty=oneline" "main")
+ (set! commit (find-commit repo commit))
+ (authenticate-repository
+ repo
+ (commit-id commit)
+ (key-fingerprint-vector key)
+ #:historical-authorizations historical-authorizations)
+ (when should-fail?
+ (format #t "FAILURE: Authenticating commit '~s' should have failed.~%" commit)
+ (set! result #false))
+ '()))))
+ (check-from "commit 0" #:key key3)
+ (check-from "commit 1")
+ (check-from "commit 2")
+ (with-git-repository dir
+ `((add "noise 3")
+ ;; a commit with key2
+ (commit "commit 3" (signer ,(key-fingerprint key2))))
+ ;; Should fail because it is signed with key2, not key1
+ (check-from "commit 3" #:should-fail? #true)
+ ;; Specify commit 3 as a channel-introduction signed with
+ ;; key2. This is valid, but it should warn the user, because
+ ;; .guix-authorizations is not updated to include key2, which
+ ;; means that any subsequent commits with the same key will be
+ ;; rejected.
+ ;;
+ ;; TODO we should check somehow that a warning is issued
+ (check-from "commit 3" #:key key2))
+ (with-git-repository dir
+ `((reset ,(oid->string (commit-id (find-commit repo "commit 2"))))
+ (add "noise 4")
+ ;; set it up properly
+ (add ".guix-authorizations"
+ ,(object->string
+ `(authorizations
+ (version 0)
+ ((,(key-fingerprint key1) (name "Alice"))
+ (,(key-fingerprint key2) (name "Bob"))))))
+ (commit "commit 4" (signer ,(key-fingerprint key2))))
+ ;; This should fail because even though commit 4 adds key2 to
+ ;; .guix-authorizations, the commit itself is not authorized.
+ (check-from "commit 1" #:should-fail? #true)
+ ;; This should pass, because it's a valid channel intro at commit 4
+ (check-from "commit 4" #:key key2))
+ (with-git-repository dir
+ `((add "noise 5")
+ (commit "commit 5" (signer ,(key-fingerprint key2))))
+ ;; This is not very intuitive: because commit 4 has once been
+ ;; used as a channel intro, it got marked as trusted in the
+ ;; ~/.cache/, and because commit 1 is one of its parent, it is
+ ;; also trusted.
+ (check-from "commit 1")
+ (check-from "commit 2")
+ ;; Should still be fine, but only when starting from commit 4
+ (check-from "commit 4" #:key key2))
+ (with-git-repository dir
+ `((add "noise 6")
+ (commit "commit 6" (signer ,(key-fingerprint key1))))
+ (check-from "commit 1")
+ (check-from "commit 2")
+ (check-from "commit 4" #:key key2))))))
+ result))
+
(unless (gpg+git-available?) (test-skip 1))
(test-assert "signed commits, .guix-authorizations, authorized merge"
(with-fresh-gnupg-setup (list %ed25519-public-key-file
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [bug#50750] [PATCH 4/4] guix: git-authenticate: Fix authenticate-repository.
2021-09-28 0:40 ` [bug#50750] [PATCH 1/4] tests: Smarten up git repository testing framework Attila Lendvai
2021-09-28 0:40 ` [bug#50750] [PATCH 2/4] tests: Move keys into ./tests/keys/ and add a third ed25519 key Attila Lendvai
2021-09-28 0:40 ` [bug#50750] [PATCH 3/4] tests: Add failing test for .guix-authorizations and channel intro Attila Lendvai
@ 2021-09-28 0:40 ` Attila Lendvai
2 siblings, 0 replies; 11+ messages in thread
From: Attila Lendvai @ 2021-09-28 0:40 UTC (permalink / raw)
To: 50750; +Cc: Attila Lendvai
Also authenticate the channel intro commit.
* guix/git-authenticate.scm (authenticate-commit): Reword and extend the error
message to point to the relevant part of the manual.
(authenticate-repository): Eliminate optimizations to make the code path less
dependent on the input. Always trust the intro-commit itself. Always call
verify-introductory-commit.
(verify-introductory-commit): Check if the commit contains the key that was
used to sign it, and issue a warning otherwise. This is to avoid the confusion
caused by only the *second* commit yielding an error, because intro-commits
are always trusted.
(authenticate-commit): Clarify error message.
(authorized-keys-at-commit): Factored out to the toplevel from
commit-authorized-keys.
---
guix/channels.scm | 4 +-
guix/git-authenticate.scm | 153 ++++++++++++++++++++++----------------
2 files changed, 91 insertions(+), 66 deletions(-)
diff --git a/guix/channels.scm b/guix/channels.scm
index e4e0428eb5..b84064537f 100644
--- a/guix/channels.scm
+++ b/guix/channels.scm
@@ -347,8 +347,8 @@ commits)...~%")
(progress-reporter/bar (length commits)))
(define authentic-commits
- ;; Consider the currently-used commit of CHANNEL as authentic so
- ;; authentication can skip it and all its closure.
+ ;; Optimization: consider the currently-used commit of CHANNEL as
+ ;; authentic, so that authentication can skip it and all its closure.
(match (find (lambda (candidate)
(eq? (channel-name candidate) (channel-name channel)))
(current-channels))
diff --git a/guix/git-authenticate.scm b/guix/git-authenticate.scm
index ab3fcd8b2f..713642d2ea 100644
--- a/guix/git-authenticate.scm
+++ b/guix/git-authenticate.scm
@@ -30,6 +30,7 @@
#:select (cache-directory with-atomic-file-output))
#:use-module ((guix build utils)
#:select (mkdir-p))
+ #:use-module (guix diagnostics)
#:use-module (guix progress)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-11)
@@ -38,6 +39,7 @@
#:use-module (srfi srfi-35)
#:use-module (rnrs bytevectors)
#:use-module (rnrs io ports)
+ #:use-module (ice-9 exceptions)
#:use-module (ice-9 match)
#:autoload (ice-9 pretty-print) (pretty-print)
#:export (read-authorizations
@@ -159,11 +161,10 @@ return a list of authorized fingerprints."
(string-downcase (string-filter char-set:graphic fingerprint))))
fingerprints))))
-(define* (commit-authorized-keys repository commit
- #:optional (default-authorizations '()))
- "Return the list of OpenPGP fingerprints authorized to sign COMMIT, based on
-authorizations listed in its parent commits. If one of the parent commits
-does not specify anything, fall back to DEFAULT-AUTHORIZATIONS."
+(define (authorized-keys-at-commit repository commit default-authorizations)
+ "Return the list of authorized key fingerprints from the '.guix-authorizations'
+file at the given commit."
+
(define (parents-have-authorizations-file? commit)
;; Return true if at least one of the parents of COMMIT has the
;; '.guix-authorizations' file.
@@ -185,28 +186,35 @@ does not specify anything, fall back to DEFAULT-AUTHORIZATIONS."
to remove '.guix-authorizations' file")
(oid->string (commit-id commit)))))))
- (define (commit-authorizations commit)
- (catch 'git-error
- (lambda ()
- (let* ((tree (commit-tree commit))
- (entry (tree-entry-bypath tree ".guix-authorizations"))
- (blob (blob-lookup repository (tree-entry-id entry))))
- (read-authorizations
- (open-bytevector-input-port (blob-content blob)))))
- (lambda (key error)
- (if (= (git-error-code error) GIT_ENOTFOUND)
- (begin
- ;; Prevent removal of '.guix-authorizations' since it would make
- ;; it trivial to force a fallback to DEFAULT-AUTHORIZATIONS.
- (assert-parents-lack-authorizations commit)
- default-authorizations)
- (throw key error)))))
+ (catch 'git-error
+ (lambda ()
+ (let* ((tree (commit-tree commit))
+ (entry (tree-entry-bypath tree ".guix-authorizations"))
+ (blob (blob-lookup repository (tree-entry-id entry))))
+ (read-authorizations
+ (open-bytevector-input-port (blob-content blob)))))
+ (lambda (key error)
+ (if (= (git-error-code error) GIT_ENOTFOUND)
+ (begin
+ ;; Prevent removal of '.guix-authorizations' since it would make
+ ;; it trivial to force a fallback to DEFAULT-AUTHORIZATIONS.
+ (assert-parents-lack-authorizations commit)
+ default-authorizations)
+ (throw key error)))))
+(define* (commit-authorized-keys repository commit
+ #:optional (default-authorizations '()))
+ "Return the list of OpenPGP fingerprints authorized to sign COMMIT, based on
+authorizations listed in its parent commits. If one of the parent commits
+does not specify anything, fall back to DEFAULT-AUTHORIZATIONS."
(match (commit-parents commit)
(() default-authorizations)
(parents
(apply lset-intersection bytevector=?
- (map commit-authorizations parents)))))
+ (map (lambda (commit)
+ (authorized-keys-at-commit repository commit
+ default-authorizations))
+ parents)))))
(define* (authenticate-commit repository commit keyring
#:key (default-authorizations '()))
@@ -236,8 +244,8 @@ not specify anything, fall back to DEFAULT-AUTHORIZATIONS."
(condition
(&unauthorized-commit-error (commit id)
(signing-key signing-key)))
- (formatted-message (G_ "commit ~a not signed by an authorized \
-key: ~a")
+ (formatted-message (G_ "commit ~a is signed by an unauthorized \
+key: ~a\nSee info guix \"Specifying Channel Authorizations\".")
(oid->string id)
(openpgp-format-fingerprint
(openpgp-public-key-fingerprint
@@ -356,7 +364,8 @@ authenticated (only COMMIT-ID is written to cache, though)."
(base64-encode
(sha256 (string->utf8 (repository-directory repository))))))
-(define (verify-introductory-commit repository keyring commit expected-signer)
+(define (verify-introductory-commit repository commit expected-signer keyring
+ authorizations)
"Look up COMMIT in REPOSITORY, and raise an exception if it is not signed by
EXPECTED-SIGNER."
(define actual-signer
@@ -364,13 +373,25 @@ EXPECTED-SIGNER."
(commit-signing-key repository (commit-id commit) keyring)))
(unless (bytevector=? expected-signer actual-signer)
- (raise (formatted-message (G_ "initial commit ~a is signed by '~a' \
+ (raise (make-compound-condition
+ (condition (&unauthorized-commit-error (commit (commit-id commit))
+ (signing-key actual-signer)))
+ (formatted-message (G_ "initial commit ~a is signed by '~a' \
instead of '~a'")
- (oid->string (commit-id commit))
- (openpgp-format-fingerprint actual-signer)
- (openpgp-format-fingerprint expected-signer)))))
-
-(define* (authenticate-repository repository start signer
+ (oid->string (commit-id commit))
+ (openpgp-format-fingerprint actual-signer)
+ (openpgp-format-fingerprint expected-signer)))))
+ (unless (member actual-signer
+ (authorized-keys-at-commit repository commit authorizations)
+ bytevector=?)
+ ;; FIXME Is this the right way to tell the user about this situation? It
+ ;; would also be nice if the tests could assert for this warning.
+ (warning (G_ "initial commit ~a does not add \
+the key it is signed with (~a) to the '.guix-authorizations' file.")
+ (oid->string (commit-id commit))
+ (openpgp-format-fingerprint actual-signer))))
+
+(define* (authenticate-repository repository intro-commit-hash intro-signer
#:key
(keyring-reference "keyring")
(cache-key (repository-cache-key repository))
@@ -380,11 +401,12 @@ instead of '~a'")
(historical-authorizations '())
(make-reporter
(const progress-reporter/silent)))
- "Authenticate REPOSITORY up to commit END, an OID. Authentication starts
-with commit START, an OID, which must be signed by SIGNER; an exception is
-raised if that is not the case. Commits listed in AUTHENTIC-COMMITS and their
-closure are considered authentic. Return an alist mapping OpenPGP public keys
-to the number of commits signed by that key that have been traversed.
+ "Authenticate REPOSITORY up to commit END, an OID. Authentication starts with
+commit INTRO-COMMIT-HASH, an OID, which must be signed by INTRO-SIGNER; an
+exception is raised if that is not the case. Commits listed in
+AUTHENTIC-COMMITS and their closure are considered authentic. Return an
+alist mapping OpenPGP public keys to the number of commits signed by that
+key that have been traversed.
The OpenPGP keyring is loaded from KEYRING-REFERENCE in REPOSITORY, where
KEYRING-REFERENCE is the name of a branch. The list of authenticated commits
@@ -393,8 +415,10 @@ is cached in the authentication cache under CACHE-KEY.
HISTORICAL-AUTHORIZATIONS must be a list of OpenPGP fingerprints (bytevectors)
denoting the authorized keys for commits whose parent lack the
'.guix-authorizations' file."
- (define start-commit
- (commit-lookup repository start))
+
+ (define intro-commit
+ (commit-lookup repository intro-commit-hash))
+
(define end-commit
(commit-lookup repository end))
@@ -404,36 +428,37 @@ denoting the authorized keys for commits whose parent lack the
(define authenticated-commits
;; Previously-authenticated commits that don't need to be checked again.
(filter-map (lambda (id)
+ ;; We need to tolerate when cached commits disappear due to
+ ;; --allow-downgrades.
(false-if-git-not-found
(commit-lookup repository (string->oid id))))
(append (previously-authenticated-commits cache-key)
- authentic-commits)))
+ authentic-commits
+ ;; The intro commit is unconditionally trusted.
+ (list (oid->string intro-commit-hash)))))
(define commits
;; Commits to authenticate, excluding the closure of
;; AUTHENTICATED-COMMITS.
- (commit-difference end-commit start-commit
- authenticated-commits))
-
- ;; When COMMITS is empty, it's because END-COMMIT is in the closure of
- ;; START-COMMIT and/or AUTHENTICATED-COMMITS, in which case it's known to
- ;; be authentic already.
- (if (null? commits)
- '()
- (let ((reporter (make-reporter start-commit end-commit commits)))
- ;; If it's our first time, verify START-COMMIT's signature.
- (when (null? authenticated-commits)
- (verify-introductory-commit repository keyring
- start-commit signer))
-
- (let ((stats (call-with-progress-reporter reporter
- (lambda (report)
- (authenticate-commits repository commits
- #:keyring keyring
- #:default-authorizations
- historical-authorizations
- #:report-progress report)))))
- (cache-authenticated-commit cache-key
- (oid->string (commit-id end-commit)))
-
- stats))))
+ (commit-difference end-commit intro-commit
+ authenticated-commits))
+
+ (verify-introductory-commit repository intro-commit
+ intro-signer keyring
+ historical-authorizations)
+
+ (let* ((reporter (make-reporter intro-commit end-commit commits))
+ (stats (call-with-progress-reporter reporter
+ (lambda (report)
+ (authenticate-commits repository commits
+ #:keyring keyring
+ #:default-authorizations
+ historical-authorizations
+ #:report-progress report)))))
+ ;; Note that this will make the then current end commit of any channel,
+ ;; that has been used/trusted in the past with a channel introduction,
+ ;; remain trusted until the cache is cleared.
+ (cache-authenticated-commit cache-key
+ (oid->string (commit-id end-commit)))
+
+ stats))
--
2.33.0
^ permalink raw reply related [flat|nested] 11+ messages in thread