summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--guix/openpgp.scm44
-rw-r--r--tests/openpgp.scm22
2 files changed, 56 insertions, 10 deletions
diff --git a/guix/openpgp.scm b/guix/openpgp.scm
index bfdbe4b61b7..77a75373df2 100644
--- a/guix/openpgp.scm
+++ b/guix/openpgp.scm
@@ -33,6 +33,7 @@
33 33
34 openpgp-signature? 34 openpgp-signature?
35 openpgp-signature-issuer 35 openpgp-signature-issuer
36 openpgp-signature-issuer-fingerprint
36 openpgp-signature-public-key-algorithm 37 openpgp-signature-public-key-algorithm
37 openpgp-signature-hash-algorithm 38 openpgp-signature-hash-algorithm
38 openpgp-signature-creation-time 39 openpgp-signature-creation-time
@@ -345,7 +346,6 @@ hexadecimal format for fingerprints."
345 ;; 12 = Revocation Key 346 ;; 12 = Revocation Key
346 347
347(define SUBPACKET-ISSUER 16) 348(define SUBPACKET-ISSUER 16)
348;; TODO: hashed SUBPACKET-ISSUER-FINGERPRINT-V4
349(define SUBPACKET-NOTATION-DATA 20) 349(define SUBPACKET-NOTATION-DATA 20)
350(define SUBPACKET-PREFERRED-HASH-ALGORITHMS 21) 350(define SUBPACKET-PREFERRED-HASH-ALGORITHMS 21)
351(define SUBPACKET-PREFERRED-COMPRESSION-ALGORITHMS 22) 351(define SUBPACKET-PREFERRED-COMPRESSION-ALGORITHMS 22)
@@ -358,8 +358,8 @@ hexadecimal format for fingerprints."
358(define SUBPACKET-REASON-FOR-REVOCATION 29) 358(define SUBPACKET-REASON-FOR-REVOCATION 29)
359(define SUBPACKET-FEATURES 30) 359(define SUBPACKET-FEATURES 30)
360 ;; 31 = Signature Target 360 ;; 31 = Signature Target
361
362(define SUBPACKET-EMBEDDED-SIGNATURE 32) 361(define SUBPACKET-EMBEDDED-SIGNATURE 32)
362(define SUBPACKET-ISSUER-FINGERPRINT 33) ;defined in RFC4880bis
363 363
364(define SIGNATURE-BINARY #x00) 364(define SIGNATURE-BINARY #x00)
365(define SIGNATURE-TEXT #x01) 365(define SIGNATURE-TEXT #x01)
@@ -486,6 +486,13 @@ hexadecimal format for fingerprints."
486 ;; XXX: is the issuer always in the unhashed subpackets? 486 ;; XXX: is the issuer always in the unhashed subpackets?
487 (else #f))) 487 (else #f)))
488 488
489(define (openpgp-signature-issuer-fingerprint sig)
490 "When it's available, return the fingerprint, a bytevector, or the issuer of
491SIG. Otherwise, return #f."
492 (or (assoc-ref (openpgp-signature-hashed-subpackets sig) 'issuer-fingerprint)
493 (assoc-ref (openpgp-signature-unhashed-subpackets sig)
494 'issuer-fingerprint)))
495
489(define (openpgp-signature-creation-time sig) 496(define (openpgp-signature-creation-time sig)
490 (cond ((assq 'signature-ctime (openpgp-signature-hashed-subpackets sig)) 497 (cond ((assq 'signature-ctime (openpgp-signature-hashed-subpackets sig))
491 => (lambda (x) (unixtime (cdr x)))) 498 => (lambda (x) (unixtime (cdr x))))
@@ -578,6 +585,14 @@ the issuer's OpenPGP public key extracted from KEYRING."
578 (values 'missing-key issuer)))) 585 (values 'missing-key issuer))))
579 (values 'unsupported-signature sig))) 586 (values 'unsupported-signature sig)))
580 587
588(define (key-id-matches-fingerprint? key-id fingerprint)
589 "Return true if KEY-ID, a number, corresponds to the low 8 bytes of
590FINGERPRINT, a bytevector."
591 (let* ((len (bytevector-length fingerprint))
592 (low (make-bytevector 8)))
593 (bytevector-copy! fingerprint (- len 8) low 0 8)
594 (= (bytevector->uint low) key-id)))
595
581(define (get-signature p) 596(define (get-signature p)
582 (define (->hex n) 597 (define (->hex n)
583 (string-hex-pad (number->string n 16))) 598 (string-hex-pad (number->string n 16)))
@@ -662,14 +677,26 @@ the issuer's OpenPGP public key extracted from KEYRING."
662 ;; Errata ID: 2214. 677 ;; Errata ID: 2214.
663 (integers->bytevector u8 #x04 678 (integers->bytevector u8 #x04
664 u8 #xff 679 u8 #xff
665 u32 (+ 6 subpacket-len))))) 680 u32 (+ 6 subpacket-len))))
681 (unhashed-subpackets
682 (parse-subpackets unhashed-subpackets))
683 (hashed-subpackets (parse-subpackets hashed-subpackets))
684 (subpackets (append hashed-subpackets
685 unhashed-subpackets))
686 (issuer-key-id (assoc-ref subpackets 'issuer))
687 (issuer (assoc-ref subpackets
688 'issuer-fingerprint)))
689 (unless (or (not issuer) (not issuer-key-id)
690 (key-id-matches-fingerprint? issuer-key-id issuer))
691 (error "issuer key id does not match fingerprint" issuer))
692
666 (make-openpgp-signature version type 693 (make-openpgp-signature version type
667 (public-key-algorithm pkalg) 694 (public-key-algorithm pkalg)
668 (openpgp-hash-algorithm halg) 695 (openpgp-hash-algorithm halg)
669 hashl16 696 hashl16
670 append-data 697 append-data
671 (parse-subpackets hashed-subpackets) 698 hashed-subpackets
672 (parse-subpackets unhashed-subpackets) 699 unhashed-subpackets
673 value))))) 700 value)))))
674 (else 701 (else
675 (print "Unsupported signature version: " version) 702 (print "Unsupported signature version: " version)
@@ -701,6 +728,13 @@ the issuer's OpenPGP public key extracted from KEYRING."
701 ((= type SUBPACKET-ISSUER) 728 ((= type SUBPACKET-ISSUER)
702 (cons 'issuer 729 (cons 'issuer
703 (bytevector-u64-ref data 0 (endianness big)))) 730 (bytevector-u64-ref data 0 (endianness big))))
731 ((= type SUBPACKET-ISSUER-FINGERPRINT) ;v4+ only, RFC4880bis
732 (cons 'issuer-fingerprint
733 (let* ((version (bytevector-u8-ref data 0))
734 (len (match version (4 20) (5 32)) )
735 (fingerprint (make-bytevector len)))
736 (bytevector-copy! data 1 fingerprint 0 len)
737 fingerprint)))
704 ((= type SUBPACKET-NOTATION-DATA) 738 ((= type SUBPACKET-NOTATION-DATA)
705 (let ((p (open-bytevector-input-port data))) 739 (let ((p (open-bytevector-input-port data)))
706 (let-values (((f1 nlen vlen) 740 (let-values (((f1 nlen vlen)
diff --git a/tests/openpgp.scm b/tests/openpgp.scm
index 8a3c7bbeb7d..20d65171fd8 100644
--- a/tests/openpgp.scm
+++ b/tests/openpgp.scm
@@ -18,6 +18,7 @@
18 18
19(define-module (tests-openpgp) 19(define-module (tests-openpgp)
20 #:use-module (guix openpgp) 20 #:use-module (guix openpgp)
21 #:use-module (gcrypt base16)
21 #:use-module (gcrypt hash) 22 #:use-module (gcrypt hash)
22 #:use-module (gcrypt pk-crypto) 23 #:use-module (gcrypt pk-crypto)
23 #:use-module (ice-9 binary-ports) 24 #:use-module (ice-9 binary-ports)
@@ -65,6 +66,16 @@ vBSFjNSiVHsuAA==
65(define %dsa-key-id #x587918047BE8BD2C) ;dsa.key 66(define %dsa-key-id #x587918047BE8BD2C) ;dsa.key
66(define %ed25519-key-id #x771F49CBFAAE072D) ;ed25519.key 67(define %ed25519-key-id #x771F49CBFAAE072D) ;ed25519.key
67 68
69(define %rsa-key-fingerprint
70 (base16-string->bytevector
71 (string-downcase "385F86CFC86B665A5C165E6BAE25DA2A70DEED59")))
72(define %dsa-key-fingerprint
73 (base16-string->bytevector
74 (string-downcase "2884A980422330A4F33DD97F587918047BE8BD2C")))
75(define %ed25519-key-fingerprint
76 (base16-string->bytevector
77 (string-downcase "44D31E21AF7138F9B632280A771F49CBFAAE072D")))
78
68 79
69;;; The following are detached signatures created commands like: 80;;; The following are detached signatures created commands like:
70;;; echo 'Hello!' | gpg -sba --digest-algo sha512 81;;; echo 'Hello!' | gpg -sba --digest-algo sha512
@@ -160,15 +171,16 @@ Pz7oopeN72xgggYUNT37ezqN3MeCqw0=
160 "Ludovic Courtès <ludo@gnu.org>")))))) 171 "Ludovic Courtès <ludo@gnu.org>"))))))
161 172
162(test-equal "get-openpgp-detached-signature/ascii" 173(test-equal "get-openpgp-detached-signature/ascii"
163 (list `(,%dsa-key-id dsa sha256) 174 (list `(,%dsa-key-id ,%dsa-key-fingerprint dsa sha256)
164 `(,%rsa-key-id rsa sha256) 175 `(,%rsa-key-id ,%rsa-key-fingerprint rsa sha256)
165 `(,%ed25519-key-id eddsa sha256) 176 `(,%ed25519-key-id ,%ed25519-key-fingerprint eddsa sha256)
166 `(,%ed25519-key-id eddsa sha512) 177 `(,%ed25519-key-id ,%ed25519-key-fingerprint eddsa sha512)
167 `(,%ed25519-key-id eddsa sha1)) 178 `(,%ed25519-key-id ,%ed25519-key-fingerprint eddsa sha1))
168 (map (lambda (str) 179 (map (lambda (str)
169 (let ((signature (get-openpgp-detached-signature/ascii 180 (let ((signature (get-openpgp-detached-signature/ascii
170 (open-input-string str)))) 181 (open-input-string str))))
171 (list (openpgp-signature-issuer signature) 182 (list (openpgp-signature-issuer signature)
183 (openpgp-signature-issuer-fingerprint signature)
172 (openpgp-signature-public-key-algorithm signature) 184 (openpgp-signature-public-key-algorithm signature)
173 (openpgp-signature-hash-algorithm signature)))) 185 (openpgp-signature-hash-algorithm signature))))
174 (list %hello-signature/dsa 186 (list %hello-signature/dsa