Subject: [bug#52555] [PATCH v4 1/7] narinfo: Add ERIS field.

From: pukkamustard <[email-masked]>
Date: Thu, 28 Dec 2023 09:40:04 +0000

* guix/narinfo.scm (<narinfo>)[eris-urn]: New field.
  (narinfo-maker): Handle new field.
  (read-narifno): Handle new field.
  (equivalent-narinfo?): Require ERIS field to be equal.
---
 guix/narinfo.scm | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/guix/narinfo.scm b/guix/narinfo.scm
index a149d9a901..5f5ed8be6f 100644
--- a/guix/narinfo.scm
+++ b/guix/narinfo.scm
@@ -45,6 +45,7 @@ (define-module (guix narinfo)
             narinfo-file-sizes
             narinfo-hash
             narinfo-size
+            narinfo-eris-urn
             narinfo-references
             narinfo-deriver
             narinfo-system
@@ -69,7 +70,7 @@ (define-module (guix narinfo)
 
 (define-record-type <narinfo>
   (%make-narinfo path uri-base uris compressions file-sizes file-hashes
-                 nar-hash nar-size references deriver system
+                 nar-hash nar-size eris-urn references deriver system
                  signature contents)
   narinfo?
   (path         narinfo-path)
@@ -80,6 +81,7 @@ (define-record-type <narinfo>
   (file-hashes  narinfo-file-hashes)
   (nar-hash     narinfo-hash)
   (nar-size     narinfo-size)
+  (eris-urn     narinfo-eris-urn)
   (references   narinfo-references)
   (deriver      narinfo-deriver)
   (system       narinfo-system)
@@ -136,7 +138,7 @@ (define (narinfo-maker str cache-url)
   "Return a narinfo constructor for narinfos originating from CACHE-URL.  STR
 must contain the original contents of a narinfo file."
   (lambda (path urls compressions file-hashes file-sizes
-                nar-hash nar-size references deriver system
+                nar-hash nar-size eris-urn references deriver system
                 signature)
     "Return a new <narinfo> object."
     (define len (length urls))
@@ -158,6 +160,7 @@ (define (narinfo-maker str cache-url)
                      ((lst ...) (map string->number lst)))
                    nar-hash
                    (and=> nar-size string->number)
+                   (if eris-urn (string->uri eris-urn) #f)
                    (string-tokenize references)
                    (match deriver
                      ((or #f "") #f)
@@ -185,7 +188,7 @@ (define* (read-narinfo port #:optional url
                    (narinfo-maker str url)
                    '("StorePath" "URL" "Compression"
                      "FileHash" "FileSize" "NarHash" "NarSize"
-                     "References" "Deriver" "System"
+                     "ERIS" "References" "Deriver" "System"
                      "Signature")
                    '("URL" "Compression" "FileSize" "FileHash"))))
 
@@ -271,7 +274,13 @@ (define (equivalent-narinfo? narinfo1 narinfo2)
                (narinfo-references narinfo2))
 
        (= (narinfo-size narinfo1)
-          (narinfo-size narinfo2))))
+          (narinfo-size narinfo2))
+
+       ;; When downloading substitutes with ERIS the hash is not checked. To
+       ;; avoid malicious substitutes we must ensure that the ERIS URN is equal.
+       ;; See also <https://issues.guix.gnu.org/52555#43>.
+       (equal? (narinfo-eris-urn narinfo1)
+               (narinfo-eris-urn narinfo2))))
 
 (define %compression-methods
   ;; Known compression methods and a thunk to determine whether they're
-- 
2.41.0