substitute: Ignore irrelevant narinfo signatures.
Fixes <https://bugs.gnu.org/33733>. Fixes a bug whereby 'guix substitute' would accept narinfos whose signature does not cover the StorePath/NarHash/References tuple. * guix/scripts/substitute.scm (narinfo-sha256)[%mandatory-fields]: New variable. Compute SIGNED-FIELDS; return #f unless each of the %MANDATORY-FIELDS is among SIGNED-FIELDS. * tests/substitute.scm ("query narinfo with signature over nothing") ("query narinfo with signature over irrelevant bits"): New tests.
This commit is contained in:
parent
6b34499dc6
commit
60b04024f8
|
@ -392,12 +392,21 @@ No authentication and authorization checks are performed here!"
|
||||||
(define (narinfo-sha256 narinfo)
|
(define (narinfo-sha256 narinfo)
|
||||||
"Return the sha256 hash of NARINFO as a bytevector, or #f if NARINFO lacks a
|
"Return the sha256 hash of NARINFO as a bytevector, or #f if NARINFO lacks a
|
||||||
'Signature' field."
|
'Signature' field."
|
||||||
|
(define %mandatory-fields
|
||||||
|
;; List of fields that must be signed. If they are not signed, the
|
||||||
|
;; narinfo is considered unsigned.
|
||||||
|
'("StorePath" "NarHash" "References"))
|
||||||
|
|
||||||
(let ((contents (narinfo-contents narinfo)))
|
(let ((contents (narinfo-contents narinfo)))
|
||||||
(match (string-contains contents "Signature:")
|
(match (string-contains contents "Signature:")
|
||||||
(#f #f)
|
(#f #f)
|
||||||
(index
|
(index
|
||||||
(let ((above-signature (string-take contents index)))
|
(let* ((above-signature (string-take contents index))
|
||||||
(sha256 (string->utf8 above-signature)))))))
|
(signed-fields (match (call-with-input-string above-signature
|
||||||
|
fields->alist)
|
||||||
|
(((fields . values) ...) fields))))
|
||||||
|
(and (every (cut member <> signed-fields) %mandatory-fields)
|
||||||
|
(sha256 (string->utf8 above-signature))))))))
|
||||||
|
|
||||||
(define* (valid-narinfo? narinfo #:optional (acl (current-acl))
|
(define* (valid-narinfo? narinfo #:optional (acl (current-acl))
|
||||||
#:key verbose?)
|
#:key verbose?)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2014 Nikita Karetnikov <nikita@karetnikov.org>
|
;;; Copyright © 2014 Nikita Karetnikov <nikita@karetnikov.org>
|
||||||
;;; Copyright © 2014, 2015, 2017 Ludovic Courtès <ludo@gnu.org>
|
;;; Copyright © 2014, 2015, 2017, 2018 Ludovic Courtès <ludo@gnu.org>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -211,6 +211,46 @@ a file for NARINFO."
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(guix-substitute "--query"))))))))
|
(guix-substitute "--query"))))))))
|
||||||
|
|
||||||
|
(test-equal "query narinfo with signature over nothing"
|
||||||
|
;; The signature is computed over the empty string, not over the important
|
||||||
|
;; parts, so the narinfo must be ignored.
|
||||||
|
""
|
||||||
|
|
||||||
|
(with-narinfo (string-append "Signature: " (signature-field "") "\n"
|
||||||
|
%narinfo "\n")
|
||||||
|
(string-trim-both
|
||||||
|
(with-output-to-string
|
||||||
|
(lambda ()
|
||||||
|
(with-input-from-string (string-append "have " (%store-prefix)
|
||||||
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
||||||
|
(lambda ()
|
||||||
|
(guix-substitute "--query"))))))))
|
||||||
|
|
||||||
|
(test-equal "query narinfo with signature over irrelevant bits"
|
||||||
|
;; The signature is valid but it does not cover the
|
||||||
|
;; StorePath/NarHash/References tuple and is thus irrelevant; the narinfo
|
||||||
|
;; must be ignored.
|
||||||
|
""
|
||||||
|
|
||||||
|
(let ((prefix (string-append "StorePath: " (%store-prefix)
|
||||||
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo
|
||||||
|
URL: example.nar
|
||||||
|
Compression: none\n")))
|
||||||
|
(with-narinfo (string-append prefix
|
||||||
|
"Signature: " (signature-field prefix) "
|
||||||
|
NarHash: sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||||
|
NarSize: 42
|
||||||
|
References: bar baz
|
||||||
|
Deriver: " (%store-prefix) "/foo.drv
|
||||||
|
System: mips64el-linux\n")
|
||||||
|
(string-trim-both
|
||||||
|
(with-output-to-string
|
||||||
|
(lambda ()
|
||||||
|
(with-input-from-string (string-append "have " (%store-prefix)
|
||||||
|
"/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
||||||
|
(lambda ()
|
||||||
|
(guix-substitute "--query")))))))))
|
||||||
|
|
||||||
(test-equal "query narinfo signed with authorized key"
|
(test-equal "query narinfo signed with authorized key"
|
||||||
(string-append (%store-prefix) "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
(string-append (%store-prefix) "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue