summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--guix/openpgp.scm43
-rw-r--r--tests/openpgp.scm16
2 files changed, 40 insertions, 19 deletions
diff --git a/guix/openpgp.scm b/guix/openpgp.scm
index 3b11998c112..8479f8a1682 100644
--- a/guix/openpgp.scm
+++ b/guix/openpgp.scm
@@ -52,6 +52,7 @@
52 openpgp-keyring? 52 openpgp-keyring?
53 %empty-keyring 53 %empty-keyring
54 lookup-key-by-id 54 lookup-key-by-id
55 lookup-key-by-fingerprint
55 get-openpgp-keyring 56 get-openpgp-keyring
56 57
57 read-radix-64) 58 read-radix-64)
@@ -912,14 +913,32 @@ FINGERPRINT, a bytevector."
912;;; Keyring management 913;;; Keyring management
913 914
914(define-record-type <openpgp-keyring> 915(define-record-type <openpgp-keyring>
915 (openpgp-keyring table) 916 (openpgp-keyring ids fingerprints)
916 openpgp-keyring? 917 openpgp-keyring?
917 (table openpgp-keyring-table)) ;vhash mapping key id to packets 918 (ids openpgp-keyring-ids) ;vhash mapping key id to packets
919 (fingerprints openpgp-keyring-fingerprints)) ;mapping fingerprint to packets
920
921(define* (keyring-insert key keyring #:optional (packets (list key)))
922 "Insert the KEY/PACKETS association into KEYRING and return the resulting
923keyring. PACKETS typically contains KEY, an <openpgp-public-key>, alongside
924with additional <openpgp-public-key> records for sub-keys, <openpgp-user-id>
925records, and so on."
926 (openpgp-keyring (vhash-consv (openpgp-public-key-id key) packets
927 (openpgp-keyring-ids keyring))
928 (vhash-cons (openpgp-public-key-fingerprint key) packets
929 (openpgp-keyring-fingerprints keyring))))
918 930
919(define (lookup-key-by-id keyring id) 931(define (lookup-key-by-id keyring id)
920 "Return a list of packets for the key with ID in KEYRING, or #f if ID could 932 "Return a list of packets for the key with ID in KEYRING, or #f if ID could
921not be found. ID must be the 64-bit key ID of the key, an integer." 933not be found. ID must be the 64-bit key ID of the key, an integer."
922 (match (vhash-assv id (openpgp-keyring-table keyring)) 934 (match (vhash-assv id (openpgp-keyring-ids keyring))
935 ((_ . lst) lst)
936 (#f '())))
937
938(define (lookup-key-by-fingerprint keyring fingerprint)
939 "Return a list of packets for the key with FINGERPRINT in KEYRING, or #f if
940FINGERPRINT could not be found. FINGERPRINT must be a bytevector."
941 (match (vhash-assoc fingerprint (openpgp-keyring-fingerprints keyring))
923 ((_ . lst) lst) 942 ((_ . lst) lst)
924 (#f '()))) 943 (#f '())))
925 944
@@ -928,7 +947,7 @@ not be found. ID must be the 64-bit key ID of the key, an integer."
928 947
929(define %empty-keyring 948(define %empty-keyring
930 ;; The empty keyring. 949 ;; The empty keyring.
931 (openpgp-keyring vlist-null)) 950 (openpgp-keyring vlist-null vlist-null))
932 951
933(define* (get-openpgp-keyring port 952(define* (get-openpgp-keyring port
934 #:optional (keyring %empty-keyring) 953 #:optional (keyring %empty-keyring)
@@ -939,15 +958,15 @@ complements KEYRING. LIMIT is the maximum number of keys to read, or -1 if
939there is no limit." 958there is no limit."
940 (let lp ((pkt (get-packet port)) 959 (let lp ((pkt (get-packet port))
941 (limit limit) 960 (limit limit)
942 (keyring (openpgp-keyring-table keyring))) 961 (keyring keyring))
943 (print "#;key " pkt) 962 (print "#;key " pkt)
944 (cond ((or (zero? limit) (eof-object? pkt)) 963 (cond ((or (zero? limit) (eof-object? pkt))
945 (openpgp-keyring keyring)) 964 keyring)
946 ((openpgp-public-key-primary? pkt) 965 ((openpgp-public-key-primary? pkt)
947 ;; Read signatures, user id's, subkeys 966 ;; Read signatures, user id's, subkeys
948 (let lp* ((pkt (get-packet port)) 967 (let lp* ((pkt (get-packet port))
949 (pkts (list pkt)) 968 (pkts (list pkt))
950 (key-ids (list (openpgp-public-key-id pkt)))) 969 (keys (list pkt)))
951 (print "#;keydata " pkt) 970 (print "#;keydata " pkt)
952 (cond ((or (eof-object? pkt) 971 (cond ((or (eof-object? pkt)
953 (eq? pkt 'unsupported-public-key-version) 972 (eq? pkt 'unsupported-public-key-version)
@@ -957,13 +976,13 @@ there is no limit."
957 ;; packets. 976 ;; packets.
958 (lp pkt 977 (lp pkt
959 (- limit 1) 978 (- limit 1)
960 (fold (cute vhash-consv <> (reverse pkts) <>) 979 (fold (cute keyring-insert <> <> (reverse pkts))
961 keyring key-ids))) 980 keyring keys)))
962 ((openpgp-public-key? pkt) ;subkey 981 ((openpgp-public-key? pkt) ;subkey
963 (lp* (get-packet port) (cons pkt pkts) 982 (lp* (get-packet port) (cons pkt pkts)
964 (cons (openpgp-public-key-id pkt) key-ids))) 983 (cons pkt keys)))
965 (else 984 (else
966 (lp* (get-packet port) (cons pkt pkts) key-ids))))) 985 (lp* (get-packet port) (cons pkt pkts) keys)))))
967 (else 986 (else
968 ;; Skip until there's a primary key. Ignore errors... 987 ;; Skip until there's a primary key. Ignore errors...
969 (lp (get-packet port) limit keyring))))) 988 (lp (get-packet port) limit keyring)))))
diff --git a/tests/openpgp.scm b/tests/openpgp.scm
index 1709167859d..eac2e88f747 100644
--- a/tests/openpgp.scm
+++ b/tests/openpgp.scm
@@ -162,13 +162,15 @@ Pz7oopeN72xgggYUNT37ezqN3MeCqw0=
162 (call-with-input-file key read-radix-64))))) 162 (call-with-input-file key read-radix-64)))))
163 (match (lookup-key-by-id keyring %civodul-key-id) 163 (match (lookup-key-by-id keyring %civodul-key-id)
164 (((? openpgp-public-key? primary) packets ...) 164 (((? openpgp-public-key? primary) packets ...)
165 (and (= (openpgp-public-key-id primary) %civodul-key-id) 165 (let ((fingerprint (openpgp-public-key-fingerprint primary)))
166 (not (openpgp-public-key-subkey? primary)) 166 (and (= (openpgp-public-key-id primary) %civodul-key-id)
167 (string=? (openpgp-format-fingerprint 167 (not (openpgp-public-key-subkey? primary))
168 (openpgp-public-key-fingerprint primary)) 168 (string=? (openpgp-format-fingerprint fingerprint)
169 %civodul-fingerprint) 169 %civodul-fingerprint)
170 (string=? (openpgp-user-id-value (find openpgp-user-id? packets)) 170 (string=? (openpgp-user-id-value (find openpgp-user-id? packets))
171 "Ludovic Courtès <ludo@gnu.org>")))))) 171 "Ludovic Courtès <ludo@gnu.org>")
172 (equal? (lookup-key-by-id keyring %civodul-key-id)
173 (lookup-key-by-fingerprint keyring fingerprint))))))))
172 174
173(test-equal "get-openpgp-detached-signature/ascii" 175(test-equal "get-openpgp-detached-signature/ascii"
174 (list `(,%dsa-key-id ,%dsa-key-fingerprint dsa sha256) 176 (list `(,%dsa-key-id ,%dsa-key-fingerprint dsa sha256)