unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
From: "Ludovic Courtès" <ludo@gnu.org>
To: Maxim Cournoyer <maxim.cournoyer@gmail.com>
Cc: 41767@debbugs.gnu.org
Subject: [bug#41767] [PATCH 4/9] channels: 'latest-channel-instance' authenticates Git checkouts.
Date: Thu, 11 Jun 2020 11:24:23 +0200	[thread overview]
Message-ID: <87sgf2araw.fsf@gnu.org> (raw)
In-Reply-To: <87v9k0i0yj.fsf@gmail.com> (Maxim Cournoyer's message of "Tue, 09 Jun 2020 13:49:24 -0400")

[-- Attachment #1: Type: text/plain, Size: 5269 bytes --]

Hi Maxim,

Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:

>> +(define %guix-channel-introduction
>> +  ;; Introduction of the official 'guix channel.  The chosen commit is the
>> +  ;; first one that introduces '.guix-authorizations' on the 'core-updates'
>> +  ;; branch that was eventually merged in 'master'.  Any branch starting
>> +  ;; before that commit cannot be merged or it will be rejected by 'guix pull'
>> +  ;; & co.
>> +  (make-channel-introduction
>> +   "87a40d7203a813921b3ef0805c2b46c0026d6c31"
>> +   (base16-string->bytevector
>> +    (string-downcase
>> +     (string-filter char-set:hex-digit            ;mbakke
>> +                    "BBB0 2DDF 2CEA F6A8 0D1D  E643 A2A0 6DF2 A33A 54FA")))
>> +   #f))                   ;TODO: Add an intro signature so it can be exported.
>
> The GnuPG key fingerprint is SHA1 derived, which isn't cryptographically
> secure.  This doesn't mean fingerprints are unsafe *now* (given that
> forging a key to match it isn't currently practical),

Fingerprints are used as an index in the keyring here.  If somebody
introduced a second OpenPGP key with the same fingerprint in the keyring
and we picked the wrong one when verifying a signature, signature
verification would just fail.  So I think it’s perfectly OK here.

> but I don't think we should create something *today* that relies on
> SHA1 for trust.  My point is made moot by the fact that Git uses SHA1
> too... but that's another issue.  Just saying, but not blocking or
> requesting change, as I don't have a good solution for that, short of
> patching GnuPG and Git.

Right, we’re following the OpenPGP standard (which I think is fine in
this respect, at least for this use case) and Git (which is less fine).

Git commit signatures are over computed over the raw commit, something
like:

--8<---------------cut here---------------start------------->8---
tree 6e3ed6ad90013f8cb685556b0669c8a12f24bd09
parent 394566f7f4a99748f59b86da5bc551903ece5052
author Ludovic Courtès <ludo@gnu.org> 1591626893 +0200
committer Ludovic Courtès <ludo@gnu.org> 1591648112 +0200

tests: Move OpenPGP helpers to (guix tests gnupg).

* tests/git-authenticate.scm (key-id): Remove.
(%ed25519-public-key-file, %ed25519-secret-key-file)
(%ed25519bis-public-key-file, %ed25519bis-secret-key-file)
(read-openpgp-packet, key-fingerprint): Move to...
* guix/tests/gnupg.scm: ... here.
--8<---------------cut here---------------end--------------->8---

One could forge a tree object with the same SHA1: signature verification
would still pass, but the checkout could be very different.

The “SHA-1 is a Shambles” paper reads:

  The GIT developers have been working on replacing SHA-1 for a
  while[16], and they use a collision detection library [SS17] to
  mitigate the risks of collision attacks.

  [16] https://git-scm.com/docs/hash-function-transition/

On the Fediverse, someone pointed out that Bitcoin Core developers
compute a SHA512 hash of Git trees to mitigate it:

  https://github.com/bitcoin/bitcoin/tree/master/contrib/verify-commits

What they do is add a “Tree-SHA512:” line to commit logs and check
those in ‘verify-commits.py’:

--8<---------------cut here---------------start------------->8---
# Check the Tree-SHA512
if (verify_tree or prev_commit == "") and current_commit not in incorrect_sha512_allowed:
    tree_hash = tree_sha512sum(current_commit)
    if ("Tree-SHA512: {}".format(tree_hash)) not in subprocess.check_output([GIT, 'show', '-s', '--format=format:%B', current_commit]).decode('utf8').splitlines():
        print("Tree-SHA512 did not match for commit " + current_commit, file=sys.stderr)
        sys.exit(1)
--8<---------------cut here---------------end--------------->8---

We could do something similar, maybe optionally, but verification would
be expensive (you need to traverse all the blobs of the whole tree for
each commit being authenticated).

At this point, I’d wait for Git’s SHA256 migration to happen, though
<https://git-scm.com/docs/hash-function-transition/> doesn’t specify an
ETA.

>> +          ;; If it's our first time, verify CHANNEL's introductory commit.
>> +          (when (null? authenticated-commits)
>> +            (verify-introductory-commit repository
>> +                                        (channel-introduction channel)
>> +                                        keyring))
>> +
>> +          (call-with-progress-reporter reporter
>> +            (lambda (report)
>> +              (authenticate-commits repository commits
>> +                                    #:keyring keyring
>> +                                    #:report-progress report)))
>> +
>> +          (unless (null? commits)
>
> That condition is already checked above, but OK to be defensive.

Oh that’s a leftover, I’ve removed it for clarity.

>> +        (when (guix-channel? channel)
>> +          (warning (G_ "the code of channel '~a' cannot be authenticated~%")
>> +                   (channel-name channel))))
>> +
>
> Perhaps the warning message could say why.

Good point.

Below are changes I made locally to account for your feedback.

Thank you!

Ludo’.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 1272 bytes --]

diff --git a/guix/channels.scm b/guix/channels.scm
index c2ea0e26ff..036c8d9b5d 100644
--- a/guix/channels.scm
+++ b/guix/channels.scm
@@ -369,10 +369,9 @@ commits ~a to ~a (~h new commits)...~%")
                                     #:keyring keyring
                                     #:report-progress report)))
 
-          (unless (null? commits)
-            (cache-authenticated-commit cache-key
-                                        (oid->string
-                                         (commit-id end-commit))))))))
+          (cache-authenticated-commit cache-key
+                                      (oid->string
+                                       (commit-id end-commit)))))))
 
 (define* (latest-channel-instance store channel
                                   #:key (patches %patches)
@@ -392,7 +391,8 @@ relation to STARTING-COMMIT when provided."
         ;; TODO: Warn for all the channels once the authentication interface
         ;; is public.
         (when (guix-channel? channel)
-          (warning (G_ "the code of channel '~a' cannot be authenticated~%")
+          (warning (G_ "channel '~a' lacks an introduction and \
+cannot be authenticated~%")
                    (channel-name channel))))
 
     (when (guix-channel? channel)

  reply	other threads:[~2020-06-11  9:25 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-08 21:52 [bug#41767] [PATCH 0/9] Authenticate channels Ludovic Courtès
2020-06-08 22:02 ` [bug#41767] [PATCH 1/9] git-authenticate: Cache takes a key parameter Ludovic Courtès
2020-06-08 22:02   ` [bug#41767] [PATCH 2/9] git-authenticate: 'authenticate-commits' takes a #:keyring parameter Ludovic Courtès
2020-06-08 22:02   ` [bug#41767] [PATCH 3/9] tests: Move OpenPGP helpers to (guix tests gnupg) Ludovic Courtès
2020-06-08 22:02   ` [bug#41767] [PATCH 4/9] channels: 'latest-channel-instance' authenticates Git checkouts Ludovic Courtès
2020-06-09 17:49     ` Maxim Cournoyer
2020-06-11  9:24       ` Ludovic Courtès [this message]
2020-06-11 13:15         ` Maxim Cournoyer
2020-06-08 22:02   ` [bug#41767] [PATCH 5/9] channels: Make 'validate-pull' call right after clone/pull Ludovic Courtès
2020-06-08 22:02   ` [bug#41767] [PATCH 6/9] .guix-channel: Add 'keyring-reference' Ludovic Courtès
2020-06-08 22:02   ` [bug#41767] [PATCH 7/9] channels: Automatically add introduction for the official 'guix' channel Ludovic Courtès
2020-06-08 22:02   ` [bug#41767] [PATCH 8/9] pull: Add '--disable-authentication' Ludovic Courtès
2020-06-08 22:02   ` [bug#41767] [PATCH 9/9] DROP? channels: Add prehistorical authorizations to <channel-introduction> Ludovic Courtès
2020-06-09 18:35     ` Maxim Cournoyer
2020-06-10 13:21       ` Ludovic Courtès
2020-06-09  7:15 ` [bug#41767] [PATCH 0/9] Authenticate channels Ludovic Courtès
2020-06-09 10:52 ` zimoun
2020-06-09 14:16   ` Ludovic Courtès
2020-06-13 11:42     ` zimoun
2020-06-14 13:51       ` Ludovic Courtès
2020-06-16 14:22 ` bug#41767: " Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87sgf2araw.fsf@gnu.org \
    --to=ludo@gnu.org \
    --cc=41767@debbugs.gnu.org \
    --cc=maxim.cournoyer@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).