[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
05/06: git-authenticate: Disallow SHA1 (and MD5) signatures.
From: |
guix-commits |
Subject: |
05/06: git-authenticate: Disallow SHA1 (and MD5) signatures. |
Date: |
Fri, 12 Jun 2020 12:57:16 -0400 (EDT) |
civodul pushed a commit to branch master
in repository guix.
commit 52c529ff20b389eb64ac033586e6b1a5c5d82cb5
Author: Ludovic Courtès <ludo@gnu.org>
AuthorDate: Wed Jun 10 14:54:13 2020 +0200
git-authenticate: Disallow SHA1 (and MD5) signatures.
* guix/git-authenticate.scm (commit-signing-key): Add
#:disallowed-hash-algorithms and honor it.
(authenticate-commit)[recent-commit?]: New variable.
Pass #:disallowed-hash-algorithms to 'commit-signing-key'.
* tests/git-authenticate.scm ("signed commits, SHA1 signature"): New test.
---
guix/git-authenticate.scm | 29 ++++++++++++++++++++++++++---
tests/git-authenticate.scm | 29 +++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/guix/git-authenticate.scm b/guix/git-authenticate.scm
index c333717..0d6f696 100644
--- a/guix/git-authenticate.scm
+++ b/guix/git-authenticate.scm
@@ -85,9 +85,11 @@
(signature missing-key-error-signature))
-(define (commit-signing-key repo commit-id keyring)
+(define* (commit-signing-key repo commit-id keyring
+ #:key (disallowed-hash-algorithms '(sha1)))
"Return the OpenPGP key that signed COMMIT-ID (an OID). Raise an exception
-if the commit is unsigned, has an invalid signature, or if its signing key is
+if the commit is unsigned, has an invalid signature, has a signature using one
+of the hash algorithms in DISALLOWED-HASH-ALGORITHMS, or if its signing key is
not in KEYRING."
(let-values (((signature signed-data)
(catch 'git-error
@@ -103,6 +105,17 @@ not in KEYRING."
(oid->string commit-id)))))))
(let ((signature (string->openpgp-packet signature)))
+ (when (memq (openpgp-signature-hash-algorithm signature)
+ `(,@disallowed-hash-algorithms md5))
+ (raise (condition
+ (&unsigned-commit-error (commit commit-id))
+ (&message
+ (message (format #f (G_ "commit ~a has a ~a signature, \
+which is not permitted")
+ (oid->string commit-id)
+ (openpgp-signature-hash-algorithm
+ signature)))))))
+
(with-fluids ((%default-port-encoding "UTF-8"))
(let-values (((status data)
(verify-openpgp-signature signature keyring
@@ -198,8 +211,18 @@ not specify anything, fall back to DEFAULT-AUTHORIZATIONS."
(define id
(commit-id commit))
+ (define recent-commit?
+ (false-if-git-not-found
+ (tree-entry-bypath (commit-tree commit) ".guix-authorizations")))
+
(define signing-key
- (commit-signing-key repository id keyring))
+ (commit-signing-key repository id keyring
+ ;; Reject SHA1 signatures unconditionally as suggested
+ ;; by the authors of "SHA-1 is a Shambles" (2019).
+ ;; Accept it for "historical" commits (there are such
+ ;; signatures from April 2020 in the repository).
+ #:disallowed-hash-algorithms
+ (if recent-commit? '(sha1) '())))
(unless (member (openpgp-public-key-fingerprint signing-key)
(commit-authorized-keys repository commit
diff --git a/tests/git-authenticate.scm b/tests/git-authenticate.scm
index 84689d6..97990ac 100644
--- a/tests/git-authenticate.scm
+++ b/tests/git-authenticate.scm
@@ -81,6 +81,35 @@
#:keyring-reference "master")
'failed)))))
+(unless (which (git-command)) (test-skip 1))
+(test-assert "signed commits, SHA1 signature"
+ (with-fresh-gnupg-setup (list %ed25519-public-key-file
+ %ed25519-secret-key-file)
+ ;; Force use of SHA1 for signatures.
+ (call-with-output-file (string-append (getenv "GNUPGHOME") "/gpg.conf")
+ (lambda (port)
+ (display "digest-algo sha1" port)))
+
+ (with-temporary-git-repository directory
+ `((add "a.txt" "A")
+ (add "signer.key" ,(call-with-input-file %ed25519-public-key-file
+ get-string-all))
+ (add ".guix-authorizations"
+ ,(object->string
+ `(authorizations (version 0)
+ ((,(key-fingerprint %ed25519-public-key-file)
+ (name "Charlie"))))))
+ (commit "first commit"
+ (signer ,(key-fingerprint %ed25519-public-key-file))))
+ (with-repository directory repository
+ (let ((commit (find-commit repository "first")))
+ (guard (c ((unsigned-commit-error? c)
+ (oid=? (git-authentication-error-commit c)
+ (commit-id commit))))
+ (authenticate-commits repository (list commit)
+ #:keyring-reference "master")
+ 'failed))))))
+
(unless (gpg+git-available?) (test-skip 1))
(test-assert "signed commits, default authorizations"
(with-fresh-gnupg-setup (list %ed25519-public-key-file
- branch master updated (205a0ec -> 29e4d3e), guix-commits, 2020/06/12
- 01/06: gnu: Add emacs-shell-pop., guix-commits, 2020/06/12
- 02/06: gnu: Add libestr., guix-commits, 2020/06/12
- 03/06: gnu: Add libfastjson., guix-commits, 2020/06/12
- 04/06: gnu: Add liblogging., guix-commits, 2020/06/12
- 05/06: git-authenticate: Disallow SHA1 (and MD5) signatures.,
guix-commits <=
- 06/06: gnu: guile-sqlite3: Update to 0.1.1., guix-commits, 2020/06/12