From patchwork Tue Sep 8 22:16:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 23970 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id A122527BBE7; Tue, 8 Sep 2020 23:18:40 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 4AF5927BBE9 for ; Tue, 8 Sep 2020 23:18:40 +0100 (BST) Received: from localhost ([::1]:35526 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kFlwl-000748-HG for patchwork@mira.cbaines.net; Tue, 08 Sep 2020 18:18:39 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43428) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kFlvD-0005Pk-23 for guix-patches@gnu.org; Tue, 08 Sep 2020 18:17:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:45132) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kFlvC-0004ZH-OQ for guix-patches@gnu.org; Tue, 08 Sep 2020 18:17:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kFlvC-0002tp-KB for guix-patches@gnu.org; Tue, 08 Sep 2020 18:17:02 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#43285] [PATCH 1/3] store: Test 'import-paths' with unauthorized and unsigned nar bundles. References: <20200908215837.32037-1-ludo@gnu.org> In-Reply-To: <20200908215837.32037-1-ludo@gnu.org> Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Tue, 08 Sep 2020 22:17:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 43285 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 43285@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= Received: via spool by 43285-submit@debbugs.gnu.org id=B43285.159960341810966 (code B ref 43285); Tue, 08 Sep 2020 22:17:02 +0000 Received: (at 43285) by debbugs.gnu.org; 8 Sep 2020 22:16:58 +0000 Received: from localhost ([127.0.0.1]:56674 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kFlv8-0002qP-6n for submit@debbugs.gnu.org; Tue, 08 Sep 2020 18:16:58 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33262) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kFlv5-0002k1-3j for 43285@debbugs.gnu.org; Tue, 08 Sep 2020 18:16:57 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:50275) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kFluz-0004WR-4T; Tue, 08 Sep 2020 18:16:49 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=54296 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1kFlux-0008Ez-Vn; Tue, 08 Sep 2020 18:16:48 -0400 From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Wed, 9 Sep 2020 00:16:33 +0200 Message-Id: <20200908221635.32684-1-ludo@gnu.org> X-Mailer: git-send-email 2.28.0 MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches * tests/store.scm ("import not signed") ("import signed by unauthorized key"): New tests. --- tests/store.scm | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/tests/store.scm b/tests/store.scm index e168d3dcf6..8ff76e8f98 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) @@ -966,6 +968,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 (pk 'C 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) + ;; XXX: The daemon-provided error message currently doesn't + ;; mention the reason of the failure. + (not (zero? (store-protocol-error-status c))))) + (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)) From patchwork Tue Sep 8 22:16:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 23969 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id 675FC27BBE7; Tue, 8 Sep 2020 23:17:11 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 1A45127BBE8 for ; Tue, 8 Sep 2020 23:17:10 +0100 (BST) Received: from localhost ([::1]:60014 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kFlvJ-0005Rj-9N for patchwork@mira.cbaines.net; Tue, 08 Sep 2020 18:17:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43430) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kFlvD-0005QO-HR for guix-patches@gnu.org; Tue, 08 Sep 2020 18:17:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:45133) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kFlvD-0004ZM-8Y for guix-patches@gnu.org; Tue, 08 Sep 2020 18:17:03 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kFlvD-0002uG-41 for guix-patches@gnu.org; Tue, 08 Sep 2020 18:17:03 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#43285] [PATCH 2/3] doc: Distinguish the "nar bundle" format from "nar". Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Tue, 08 Sep 2020 22:17:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 43285 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 43285@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= Received: via spool by 43285-submit@debbugs.gnu.org id=B43285.159960341910990 (code B ref 43285); Tue, 08 Sep 2020 22:17:03 +0000 Received: (at 43285) by debbugs.gnu.org; 8 Sep 2020 22:16:59 +0000 Received: from localhost ([127.0.0.1]:56676 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kFlv8-0002qo-O9 for submit@debbugs.gnu.org; Tue, 08 Sep 2020 18:16:59 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33266) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kFlv5-0002k8-9A for 43285@debbugs.gnu.org; Tue, 08 Sep 2020 18:16:57 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:50276) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kFlv0-0004WV-3B; Tue, 08 Sep 2020 18:16:50 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=54296 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1kFluz-0008Ez-Aw; Tue, 08 Sep 2020 18:16:49 -0400 From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Wed, 9 Sep 2020 00:16:34 +0200 Message-Id: <20200908221635.32684-2-ludo@gnu.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200908221635.32684-1-ludo@gnu.org> References: <20200908221635.32684-1-ludo@gnu.org> MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches * doc/guix.texi (Invoking guix archive): Introduce the term "nar bundle" and clarify what the output of "guix archive --export" really is. * guix/nar.scm (restore-one-item, restore-file-set): Use the term "nar bundle" in docstrings. --- doc/guix.texi | 12 +++++++++++- guix/nar.scm | 15 ++++++++------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 1d6782e6fa..5cb4fe2dfd 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -4990,7 +4990,13 @@ what you should use in this case (@pxref{Invoking guix copy}). @cindex nar, archive format @cindex normalized archive (nar) -Archives are stored in the ``normalized archive'' or ``nar'' format, which is +@cindex nar bundle, archive format +Each store item is written in the @dfn{normalized archive} or @dfn{nar} +format (described below), and the output of @command{guix archive +--export} (and input of @command{guix archive --import}) is a @dfn{nar +bundle}. + +The nar format is comparable in spirit to `tar', but with differences that make it more appropriate for our purposes. First, rather than recording all Unix metadata for each file, the nar format only mentions @@ -5000,6 +5006,10 @@ entries are stored always follows the order of file names according to the C locale collation order. This makes archive production fully deterministic. +That nar bundle format is essentially the concatenation of zero or more +nars along with metadata for each store item it contains: its file name, +references, corresponding derivation, and a digital signature. + When exporting, the daemon digitally signs the contents of the archive, and that digital signature is appended. When importing, the daemon verifies the signature and rejects the import in case of an invalid diff --git a/guix/nar.scm b/guix/nar.scm index 6bb2ea5b96..a23af2e5de 100644 --- a/guix/nar.scm +++ b/guix/nar.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2018, 2019 Ludovic Courtès +;;; Copyright © 2012, 2013, 2014, 2015, 2016, 2018, 2019, 2020 Ludovic Courtès ;;; Copyright © 2014 Mark H Weaver ;;; ;;; This file is part of GNU Guix. @@ -156,7 +156,8 @@ protected from GC." (define* (restore-one-item port #:key acl (verify-signature? #t) (lock? #t) (log-port (current-error-port))) - "Restore one store item from PORT; return its file name on success." + "Restore one store item of a nar bundle read from PORT; return its file name +on success." (define (assert-valid-signature signature hash file) ;; Bail out if SIGNATURE, which must be a string as produced by @@ -251,11 +252,11 @@ a signature")) (define* (restore-file-set port #:key (verify-signature? #t) (lock? #t) (log-port (current-error-port))) - "Restore the file set read from PORT to the store. The format of the data -on PORT must be as created by 'export-paths'---i.e., a series of Nar-formatted -archives with interspersed meta-data joining them together, possibly with a -digital signature at the end. Log progress to LOG-PORT. Return the list of -files restored. + "Restore the file set (\"nar bundle\") read from PORT to the store. The +format of the data on PORT must be as created by 'export-paths'---i.e., a +series of Nar-formatted archives with interspersed meta-data joining them +together, possibly with a digital signature at the end. Log progress to +LOG-PORT. Return the list of files restored. When LOCK? is #f, assume locks for the files to be restored are already held. This is the case when the daemon calls a build hook. From patchwork Tue Sep 8 22:16:35 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ludovic_Court=C3=A8s?= X-Patchwork-Id: 23968 Return-Path: X-Original-To: patchwork@mira.cbaines.net Delivered-To: patchwork@mira.cbaines.net Received: by mira.cbaines.net (Postfix, from userid 113) id EDA7727BBE9; Tue, 8 Sep 2020 23:17:10 +0100 (BST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mira.cbaines.net X-Spam-Level: X-Spam-Status: No, score=-2.9 required=5.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_MSPIKE_H4,RCVD_IN_MSPIKE_WL,URIBL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.2 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mira.cbaines.net (Postfix) with ESMTPS id 72C4D27BBE7 for ; Tue, 8 Sep 2020 23:17:10 +0100 (BST) Received: from localhost ([::1]:60036 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kFlvJ-0005SS-K3 for patchwork@mira.cbaines.net; Tue, 08 Sep 2020 18:17:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:43440) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kFlvD-0005Qs-TO for guix-patches@gnu.org; Tue, 08 Sep 2020 18:17:03 -0400 Received: from debbugs.gnu.org ([209.51.188.43]:45134) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kFlvD-0004ZR-K0 for guix-patches@gnu.org; Tue, 08 Sep 2020 18:17:03 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kFlvD-0002ul-Gg for guix-patches@gnu.org; Tue, 08 Sep 2020 18:17:03 -0400 X-Loop: help-debbugs@gnu.org Subject: [bug#43285] [PATCH 3/3] daemon: Simplify interface with 'guix authenticate'. Resent-From: Ludovic =?utf-8?q?Court=C3=A8s?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Tue, 08 Sep 2020 22:17:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 43285 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 43285@debbugs.gnu.org Cc: Ludovic =?utf-8?q?Court=C3=A8s?= Received: via spool by 43285-submit@debbugs.gnu.org id=B43285.159960342211136 (code B ref 43285); Tue, 08 Sep 2020 22:17:03 +0000 Received: (at 43285) by debbugs.gnu.org; 8 Sep 2020 22:17:02 +0000 Received: from localhost ([127.0.0.1]:56678 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kFlvB-0002sx-DD for submit@debbugs.gnu.org; Tue, 08 Sep 2020 18:17:02 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33276) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kFlv6-0002lN-Rp for 43285@debbugs.gnu.org; Tue, 08 Sep 2020 18:16:58 -0400 Received: from fencepost.gnu.org ([2001:470:142:3::e]:50277) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kFlv1-0004Wo-Ls; Tue, 08 Sep 2020 18:16:51 -0400 Received: from [2a01:e0a:1d:7270:af76:b9b:ca24:c465] (port=54296 helo=gnu.org) by fencepost.gnu.org with esmtpsa (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1kFlv0-0008Ez-DX; Tue, 08 Sep 2020 18:16:50 -0400 From: Ludovic =?utf-8?q?Court=C3=A8s?= Date: Wed, 9 Sep 2020 00:16:35 +0200 Message-Id: <20200908221635.32684-3-ludo@gnu.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200908221635.32684-1-ludo@gnu.org> References: <20200908221635.32684-1-ludo@gnu.org> MIME-Version: 1.0 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+patchwork=mira.cbaines.net@gnu.org Sender: "Guix-patches" X-getmail-retrieved-from-mailbox: Patches There's no reason at this point to mimic the calling convention of the 'openssl' command. * nix/libstore/local-store.cc (LocalStore::exportPath): Add only "sign" and HASH to ARGS. Remove 'tmpDir' and 'hashFile'. (LocalStore::importPath): Add only "verify" and SIGNATURE to ARGS. Remove 'sigFile'. * guix/scripts/authenticate.scm (guix-authenticate): Adjust accordingly; remove the OpenSSL-style clauses. (read-hash-data): Remove. (sign-with-key): Replace 'port' with 'sha256' and adjust accordingly. (validate-signature): Export SIGNATURE to be a canonical sexp. --- guix/scripts/authenticate.scm | 57 +++++++++++------------------------ nix/libstore/local-store.cc | 24 +++------------ 2 files changed, 22 insertions(+), 59 deletions(-) diff --git a/guix/scripts/authenticate.scm b/guix/scripts/authenticate.scm index f1fd8ee895..b5f043e6ac 100644 --- a/guix/scripts/authenticate.scm +++ b/guix/scripts/authenticate.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès +;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2020 Ludovic Courtès ;;; ;;; This file is part of GNU Guix. ;;; @@ -17,7 +17,6 @@ ;;; along with GNU Guix. If not, see . (define-module (guix scripts authenticate) - #:use-module (guix config) #:use-module (guix base16) #:use-module (gcrypt pk-crypto) #:use-module (guix pki) @@ -39,16 +38,9 @@ ;; Read a gcrypt sexp from a port and return it. (compose string->canonical-sexp read-string)) -(define (read-hash-data port key-type) - "Read sha256 hash data from PORT and return it as a gcrypt sexp. KEY-TYPE -is a symbol representing the type of public key algo being used." - (let* ((hex (read-string port)) - (bv (base16-string->bytevector (string-trim-both hex)))) - (bytevector->hash-data bv #:key-type key-type))) - -(define (sign-with-key key-file port) - "Sign the hash read from PORT with KEY-FILE, and write an sexp that includes -both the hash and the actual signature." +(define (sign-with-key key-file sha256) + "Sign the hash SHA256 (a bytevector) with KEY-FILE, and write an sexp that +includes both the hash and the actual signature." (let* ((secret-key (call-with-input-file key-file read-canonical-sexp)) (public-key (if (string-suffix? ".sec" key-file) (call-with-input-file @@ -58,18 +50,18 @@ both the hash and the actual signature." (leave (G_ "cannot find public key for secret key '~a'~%") key-file))) - (data (read-hash-data port (key-type public-key))) + (data (bytevector->hash-data sha256 + #:key-type (key-type public-key))) (signature (signature-sexp data secret-key public-key))) (display (canonical-sexp->string signature)) #t)) -(define (validate-signature port) - "Read the signature from PORT (which is as produced above), check whether -its public key is authorized, verify the signature, and print the signed data -to stdout upon success." - (let* ((signature (read-canonical-sexp port)) - (subject (signature-subject signature)) - (data (signature-signed-data signature))) +(define (validate-signature signature) + "Validate SIGNATURE, a canonical sexp. Check whether its public key is +authorized, verify the signature, and print the signed data to stdout upon +success." + (let* ((subject (signature-subject signature)) + (data (signature-signed-data signature))) (if (and data subject) (if (authorized-key? subject) (if (valid-signature? signature) @@ -85,9 +77,7 @@ to stdout upon success." ;;; -;;; Entry point with 'openssl'-compatible interface. We support this -;;; interface because that's what the daemon expects, and we want to leave it -;;; unmodified currently. +;;; Entry point. ;;; (define (guix-authenticate . args) @@ -101,22 +91,11 @@ to stdout upon success." (with-fluids ((%default-port-encoding "ISO-8859-1") (%default-port-conversion-strategy 'error)) (match args - ;; As invoked by guix-daemon. - (("rsautl" "-sign" "-inkey" key "-in" hash-file) - (call-with-input-file hash-file - (lambda (port) - (sign-with-key key port)))) - ;; As invoked by Nix/Crypto.pm (used by Hydra.) - (("rsautl" "-sign" "-inkey" key) - (sign-with-key key (current-input-port))) - ;; 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))) + (("sign" key-file hash) + (sign-with-key key-file (base16-string->bytevector hash))) + (("verify" signature) + (validate-signature (string->canonical-sexp signature))) + (("--help") (display (G_ "Usage: guix authenticate OPTION... Sign or verify the signature on the given file. This tool is meant to diff --git a/nix/libstore/local-store.cc b/nix/libstore/local-store.cc index 7a520925e5..0534f2a3fc 100644 --- a/nix/libstore/local-store.cc +++ b/nix/libstore/local-store.cc @@ -1277,21 +1277,13 @@ void LocalStore::exportPath(const Path & path, bool sign, writeInt(1, hashAndWriteSink); - Path tmpDir = createTempDir(); - AutoDelete delTmp(tmpDir); - Path hashFile = tmpDir + "/hash"; - writeFile(hashFile, printHash(hash)); - Path secretKey = settings.nixConfDir + "/signing-key.sec"; checkSecrecy(secretKey); Strings args; - args.push_back("rsautl"); - args.push_back("-sign"); - args.push_back("-inkey"); + args.push_back("sign"); args.push_back(secretKey); - args.push_back("-in"); - args.push_back(hashFile); + args.push_back(printHash(hash)); string signature = runAuthenticationProgram(args); @@ -1372,17 +1364,9 @@ Path LocalStore::importPath(bool requireSignature, Source & source) string signature = readString(hashAndReadSource); if (requireSignature) { - Path sigFile = tmpDir + "/sig"; - writeFile(sigFile, signature); - Strings args; - args.push_back("rsautl"); - args.push_back("-verify"); - args.push_back("-inkey"); - args.push_back(settings.nixConfDir + "/signing-key.pub"); - args.push_back("-pubin"); - args.push_back("-in"); - args.push_back(sigFile); + args.push_back("verify"); + args.push_back(signature); string hash2 = runAuthenticationProgram(args); /* Note: runProgram() throws an exception if the signature