diff options
author | Ludovic Courtès <ludo@gnu.org> | 2020-01-02 00:03:58 +0100 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2020-05-04 09:56:12 +0200 |
commit | 43408e304ffb1149f35cb539b40d673d567c9116 (patch) | |
tree | 8d7fac5cf9a00fd75191e1763337b464719cbb40 | |
parent | c91e27c60864faa229198f6f0caf620275c429a2 (diff) |
Add (guix openpgp).
* guix/openpgp.scm, tests/openpgp.scm, tests/civodul.key,
tests/dsa.key, tests/ed25519.key, tests/rsa.key,
tests/ed25519.sec: New files.
* Makefile.am (MODULES): Add guix/openpgp.scm.
(SCM_TESTS): Add tests/openpgp.scm.
(EXTRA_DIST): Add tests/*.key and tests/ed25519.sec.
-rw-r--r-- | Makefile.am | 7 | ||||
-rw-r--r-- | guix/openpgp.scm | 1022 | ||||
-rw-r--r-- | tests/civodul.key | 1345 | ||||
-rw-r--r-- | tests/dsa.key | 25 | ||||
-rw-r--r-- | tests/ed25519.key | 10 | ||||
-rw-r--r-- | tests/ed25519.sec | 10 | ||||
-rw-r--r-- | tests/openpgp.scm | 248 | ||||
-rw-r--r-- | tests/rsa.key | 18 |
8 files changed, 2685 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am index d9d7ffd6c5..f4004e351e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -70,6 +70,7 @@ MODULES = \ guix/docker.scm \ guix/json.scm \ guix/records.scm \ + guix/openpgp.scm \ guix/pki.scm \ guix/progress.scm \ guix/combinators.scm \ @@ -414,6 +415,7 @@ SCM_TESTS = \ tests/nar.scm \ tests/networking.scm \ tests/opam.scm \ + tests/openpgp.scm \ tests/packages.scm \ tests/pack.scm \ tests/pki.scm \ @@ -564,6 +566,11 @@ EXTRA_DIST += \ tests/signing-key.pub \ tests/signing-key.sec \ tests/cve-sample.json \ + tests/civodul.key \ + tests/rsa.key \ + tests/dsa.key \ + tests/ed25519.key \ + tests/ed25519.sec \ build-aux/config.rpath \ bootstrap \ doc/build.scm \ diff --git a/guix/openpgp.scm b/guix/openpgp.scm new file mode 100644 index 0000000000..bfdbe4b61b --- /dev/null +++ b/guix/openpgp.scm @@ -0,0 +1,1022 @@ +;; -*- mode: scheme; coding: utf-8 -*- +;; Copyright © 2010, 2012 Göran Weinholt <goran@weinholt.se> +;; Copyright © 2020 Ludovic Courtès <ludo@gnu.org> + +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: + +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. + +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +;; FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +;; DEALINGS IN THE SOFTWARE. + +;;; This code was originally written by Göran Weinholt for Industria and +;;; released under the Expat license shown above. It was then modified by +;;; Ludovic Courtès for use in GNU Guix: turned into a native Guile module, +;;; ported to Guile-Gcrypt, and extended and simplified in other ways. + +(define-module (guix openpgp) + #:export (get-openpgp-detached-signature/ascii + (get-packet . get-openpgp-packet) + verify-openpgp-signature + port-ascii-armored? + + openpgp-signature? + openpgp-signature-issuer + openpgp-signature-public-key-algorithm + openpgp-signature-hash-algorithm + openpgp-signature-creation-time + openpgp-signature-expiration-time + + openpgp-user-id? + openpgp-user-id-value + openpgp-user-attribute? + + openpgp-public-key? + openpgp-public-key-subkey? + openpgp-public-key-value + openpgp-public-key-fingerprint openpgp-format-fingerprint + openpgp-public-key-id + + openpgp-keyring? + %empty-keyring + lookup-key-by-id + get-openpgp-keyring + + read-radix-64) + #:use-module (rnrs bytevectors) + #:use-module (rnrs io ports) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-9) + #:use-module (srfi srfi-11) + #:use-module (srfi srfi-19) + #:use-module (srfi srfi-26) + #:use-module (srfi srfi-34) + #:use-module (srfi srfi-35) + #:use-module (srfi srfi-60) + #:use-module (ice-9 match) + #:use-module ((ice-9 rdelim) #:select (read-line)) + #:use-module (ice-9 vlist) + #:use-module (gcrypt hash) + #:use-module (gcrypt pk-crypto) + #:use-module (gcrypt base64) + #:use-module (gcrypt base16) + #:use-module ((guix build utils) #:select (dump-port))) + +;;; Commentary: +;;; +;;; This module contains code to read OpenPGP messages as described in +;;; <https://tools.ietf.org/html/rfc4880>, with extensions from +;;; <https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-06> (notably +;;; EdDSA support and extra signature sub-packets). +;;; +;;; Currently this module does enough to verify detached signatures of binary +;;; data. It does _not_ perform sanity checks on self-signatures, subkey +;;; binding signatures, etc., among others. Use only in a context where this +;;; limitations are acceptable! +;;; +;;; Code: + +(define-syntax print + (syntax-rules () + ;; ((_ args ...) (pk 'openpgp args)) + ((_ args ...) (values)))) + +(define-syntax-rule (define-alias new old) + (define-syntax new (identifier-syntax old))) + +(define-alias fx+ +) +(define-alias fx- -) +(define-alias fx* *) +(define-alias fx/ /) +(define-alias fxdiv quotient) +(define-alias fxand logand) +(define-alias fxbit-set? bit-set?) +(define-alias fxbit-field bit-field) +(define-alias bitwise-bit-field bit-field) +(define-alias fxarithmetic-shift-left ash) +(define-inlinable (fxarithmetic-shift-right i n) (ash i (- n))) +(define-inlinable (port-eof? port) (eof-object? (lookahead-u8 port))) + +(define (string-hex-pad str) + (if (odd? (string-length str)) + (string-append "0" str) + str)) + +(define (unixtime n) + (time-monotonic->date (make-time 'time-monotonic 0 n))) + + +;;; +;;; Bitwise I/O. +;;; +;;; TODO: Use Bytestructures instead. +;;; + +(define-syntax-rule (integer-read size) + (lambda (port) + "Read from PORT a big-endian integer of SIZE bytes. Return the EOF object +on end-of-file." + (let ((buf (make-bytevector size))) + (match (get-bytevector-n! port buf 0 size) + (size (bytevector-uint-ref buf 0 (endianness big) size)) + (_ (eof-object)))))) + +(define get-u16 (integer-read 2)) +(define get-u32 (integer-read 4)) +(define get-u64 (integer-read 8)) + +(define-syntax get-integers + (syntax-rules () + "Read from PORT integers of the given TYPE, in big endian encoding. Each +TYPE must be one of u8, u16, u32, u64, or _, as in this example: + + (get-integers port u8 _ _ _ u32 u16) + +In the case of _ (wildcard), one byte is read and discarded. Return as many +values as there are TYPEs." + ((_ port type ...) + (letrec-syntax ((get-integer (syntax-rules (u8 u16 u32 u64) + ((x u8) (get-u8 port)) + ((x u16) (get-u16 port)) + ((x u32) (get-u32 port)) + ((x u64) (get-u64 port)))) + (values* (syntax-rules (_) + ((x (result (... ...))) + (values result (... ...))) + ((x (result (... ...)) _ rest (... ...)) + (let ((x (get-u8 port))) + (values* (result (... ...)) + rest (... ...)))) + ((x (result (... ...)) t rest (... ...)) + (let ((x (get-integer t))) + (values* (result (... ...) x) + rest (... ...))))))) + (values* () type ...))))) + +(define (bytevector->uint bv) + (bytevector-uint-ref bv 0 (endianness big) + (bytevector-length bv))) + +(define-syntax-rule (integer-write size) + (lambda (port integer) + "Write INTEGER to PORT as a SIZE-byte integer and as big endian." + (let ((bv (make-bytevector size))) + (bytevector-uint-set! bv 0 integer (endianness big) size) + (put-bytevector port bv)))) + +(define put-u16 (integer-write 2)) +(define put-u32 (integer-write 4)) +(define put-u64 (integer-write 8)) + +(define-syntax put-integers + (syntax-rules () + "Write the given integers as big endian to PORT. For example: + + (put-integers port u8 42 u32 #x7777) + +writes to PORT the value 42 as an 8-bit integer and the value #x7777 as a +32-bit integer." + ((_ port) + #t) + ((_ port type value rest ...) + (let-syntax ((put (syntax-rules (u8 u16 u32 u64) + ((_ u8 port integer) + (put-u8 port integer)) + ((_ u16 port integer) + (put-u16 port integer)) + ((_ u32 port integer) + (put-u32 port integer)) + ((_ u64 port integer) + (put-u64 port integer))))) + (begin + (put type port value) + (put-integers port rest ...)))))) + +(define-syntax-rule (integers->bytevector type value rest ...) + "Return the the TYPE/VALUE integers representation as a bytevector." + (let-values (((port get) (open-bytevector-output-port))) + (put-integers port type value rest ...) + (force-output port) + (get))) + + +(define (bytevector->bitnames bv names) + (define (bit-set? bv i) + (let ((idx (fxarithmetic-shift-right i 3)) + (bit (fxand i #b111))) + (and (< idx (bytevector-length bv)) + (fxbit-set? (bytevector-u8-ref bv idx) bit)))) + (do ((names names (cdr names)) + (i 0 (fx+ i 1)) + (bits '() + (if (bit-set? bv i) + (cons (car names) bits) + bits))) + ((null? names) (reverse bits)))) + +(define (openpgp-format-fingerprint bv) + "Return a string representing BV, a bytevector, in the conventional OpenPGP +hexadecimal format for fingerprints." + (define (h i) + (string-pad (string-upcase + (number->string + (bytevector-u16-ref bv (* i 2) (endianness big)) + 16)) + 4 #\0)) + (string-append (h 0) " " (h 1) " " (h 2) " " (h 3) " " (h 4) + " " + (h 5) " " (h 6) " " (h 7) " " (h 8) " " (h 9))) + +;;; Constants + + +(define PACKET-SESSION-KEY 1) +(define PACKET-SIGNATURE 2) +(define PACKET-SYMMETRIC-SESSION-KEY 3) +(define PACKET-ONE-PASS-SIGNATURE 4) +(define PACKET-SECRET-KEY 5) +(define PACKET-PUBLIC-KEY 6) +(define PACKET-SECRET-SUBKEY 7) +(define PACKET-COMPRESSED-DATA 8) +(define PACKET-SYMMETRIC-ENCRYPTED-DATA 9) +(define PACKET-MARKER 10) +(define PACKET-LITERAL-DATA 11) +(define PACKET-TRUST 12) +(define PACKET-USER-ID 13) +(define PACKET-PUBLIC-SUBKEY 14) +(define PACKET-USER-ATTRIBUTE 17) +(define PACKET-SYMMETRIC-ENCRYPTED/PROTECTED-DATA 18) +(define PACKET-MDC 19) + +(define PUBLIC-KEY-RSA 1) +(define PUBLIC-KEY-RSA-ENCRYPT-ONLY 2) +(define PUBLIC-KEY-RSA-SIGN-ONLY 3) +(define PUBLIC-KEY-ELGAMAL-ENCRYPT-ONLY 16) +(define PUBLIC-KEY-DSA 17) +(define PUBLIC-KEY-ECDH 18) ;RFC-6637 +(define PUBLIC-KEY-ECDSA 19) ;RFC-6639 +(define PUBLIC-KEY-ELGAMAL 20) ;encrypt + sign (legacy) +(define PUBLIC-KEY-EDDSA 22) ;"not yet assigned" says GPG + +(define (public-key-algorithm id) + (cond ((= id PUBLIC-KEY-RSA) 'rsa) + ((= id PUBLIC-KEY-DSA) 'dsa) + ((= id PUBLIC-KEY-ELGAMAL-ENCRYPT-ONLY) 'elgamal) + ((= id PUBLIC-KEY-EDDSA) 'eddsa) + (else id))) + +(define SYMMETRIC-KEY-PLAINTEXT 0) +(define SYMMETRIC-KEY-IDEA 1) +(define SYMMETRIC-KEY-TRIPLE-DES 2) +(define SYMMETRIC-KEY-CAST5-128 3) +(define SYMMETRIC-KEY-BLOWFISH-128 4) +(define SYMMETRIC-KEY-AES-128 7) +(define SYMMETRIC-KEY-AES-192 8) +(define SYMMETRIC-KEY-AES-256 9) +(define SYMMETRIC-KEY-TWOFISH-256 10) +(define SYMMETRIC-KEY-CAMELLIA-128 11) ;RFC-5581 +(define SYMMETRIC-KEY-CAMELLIA-192 12) +(define SYMMETRIC-KEY-CAMELLIA-256 13) + +(define (symmetric-key-algorithm id) + (cond ((= id SYMMETRIC-KEY-PLAINTEXT) 'plaintext) + ((= id SYMMETRIC-KEY-IDEA) 'idea) + ((= id SYMMETRIC-KEY-TRIPLE-DES) 'tdea) + ((= id SYMMETRIC-KEY-CAST5-128) 'cast5-128) + ((= id SYMMETRIC-KEY-BLOWFISH-128) 'blowfish-128) + ((= id SYMMETRIC-KEY-AES-128) 'aes-128) + ((= id SYMMETRIC-KEY-AES-192) 'aes-192) + ((= id SYMMETRIC-KEY-AES-256) 'aes-256) + ((= id SYMMETRIC-KEY-TWOFISH-256) 'twofish-256) + (else id))) + +(define HASH-MD5 1) +(define HASH-SHA-1 2) +(define HASH-RIPE-MD160 3) +(define HASH-SHA-256 8) +(define HASH-SHA-384 9) +(define HASH-SHA-512 10) +(define HASH-SHA-224 11) + +(define (openpgp-hash-algorithm id) + (cond ((= id HASH-MD5) 'md5) + ((= id HASH-SHA-1) 'sha1) + ((= id HASH-RIPE-MD160) 'rmd160) + ((= id HASH-SHA-256) 'sha256) + ((= id HASH-SHA-384) 'sha384) + ((= id HASH-SHA-512) 'sha512) + ((= id HASH-SHA-224) 'sha224) + (else (error "unknown hash algorithm" id)))) + +(define COMPRESSION-UNCOMPRESSED 0) +(define COMPRESSION-ZIP 1) ;deflate + +(define COMPRESSION-ZLIB 2) +(define COMPRESSION-BZIP2 3) + +(define (compression-algorithm id) + (cond ((= id COMPRESSION-UNCOMPRESSED) 'uncompressed) + ((= id COMPRESSION-ZIP) 'deflate) + ((= id COMPRESSION-ZLIB) 'zlib) + ((= id COMPRESSION-BZIP2) 'bzip2) + (else id))) + +(define SUBPACKET-SIGNATURE-CTIME 2) +(define SUBPACKET-SIGNATURE-ETIME 3) + ;; 4 = Exportable Certification + +(define SUBPACKET-TRUST-SIGNATURE 5) + ;; 6 = Regular Expression + +(define SUBPACKET-REVOCABLE 7) +(define SUBPACKET-KEY-ETIME 9) +(define SUBPACKET-PREFERRED-SYMMETRIC-ALGORITHMS 11) + ;; 12 = Revocation Key + +(define SUBPACKET-ISSUER 16) +;; TODO: hashed SUBPACKET-ISSUER-FINGERPRINT-V4 +(define SUBPACKET-NOTATION-DATA 20) +(define SUBPACKET-PREFERRED-HASH-ALGORITHMS 21) +(define SUBPACKET-PREFERRED-COMPRESSION-ALGORITHMS 22) +(define SUBPACKET-KEY-SERVER-PREFERENCES 23) +(define SUBPACKET-PREFERRED-KEY-SERVER 24) +(define SUBPACKET-PRIMARY-USER-ID 25) +(define SUBPACKET-POLICY-URI 26) +(define SUBPACKET-KEY-FLAGS 27) +(define SUBPACKET-SIGNER-USER-ID 28) +(define SUBPACKET-REASON-FOR-REVOCATION 29) +(define SUBPACKET-FEATURES 30) + ;; 31 = Signature Target + +(define SUBPACKET-EMBEDDED-SIGNATURE 32) + +(define SIGNATURE-BINARY #x00) +(define SIGNATURE-TEXT #x01) +(define SIGNATURE-STANDALONE #x02) +(define SIGNATURE-GENERIC-CERT #x10) +(define SIGNATURE-PERSONA-CERT #x11) +(define SIGNATURE-CASUAL-CERT #x12) +(define SIGNATURE-POSITIVE-CERT #x13) +(define SIGNATURE-SUBKEY-BINDING #x18) +(define SIGNATURE-PRIMARY-KEY-BINDING #x19) +(define SIGNATURE-DIRECT #x1f) +(define SIGNATURE-KEY-REVOCATION #x20) +(define SIGNATURE-SUBKEY-REVOCATION #x28) +(define SIGNATURE-CERT-REVOCATION #x30) +(define SIGNATURE-TIMESTAMP #x40) +(define SIGNATURE-THIRD-PARTY #x50) + +;;; Parsing + + ;; Look at the tag byte and see if it looks reasonable, if it does + ;; then the file is likely not armored. Does not move the port + ;; position. + +(define (port-ascii-armored? p) + (let ((tag (lookahead-u8 p))) + (cond ((eof-object? tag) #f) + ((not (fxbit-set? tag 7)) #t) + (else + (let ((type (if (fxbit-set? tag 6) + (fxbit-field tag 0 6) + (fxbit-field tag 2 6)))) + (not (<= PACKET-SESSION-KEY type PACKET-MDC))))))) + +(define (get-mpi/bytevector p) + (let* ((bitlen (get-u16 p)) + (bytelen (fxdiv (fx+ bitlen 7) 8))) + (get-bytevector-n p bytelen))) + +(define (get-mpi p) + (bytevector->uint (get-mpi/bytevector p))) + +(define (get-v4-length p) + ;; TODO: indeterminate length (only for data packets) + (let ((o1 (get-u8 p))) + (cond ((< o1 192) o1) + ((< o1 255) + (+ (fxarithmetic-shift-left (fx- o1 192) 8) + (get-u8 p) + 192)) + ((= o1 255) + (get-u32 p))))) + +(define (get-packet p) + (if (port-eof? p) + (eof-object) + (get-packet* p get-data))) + +(define (get-packet* p get-data) + (let ((tag (get-u8 p))) + ;; (unless (fxbit-set? tag 7) (error 'get-packet "Invalid tag" tag)) + (cond ((fxbit-set? tag 6) ;New packet format + (let ((tag (fxbit-field tag 0 6)) + (len (get-v4-length p))) + (get-data p tag len))) + (else ;Old packet format + (let ((tag (fxbit-field tag 2 6)) + (len (case (fxbit-field tag 0 2) + ((0) (get-u8 p)) + ((1) (get-u16 p)) + ((2) (get-u32 p)) + ((3) #f)))) + (get-data p tag len)))))) + +(define (get-data p tag len) + (let ((pp (if len + (open-bytevector-input-port (get-bytevector-n p len)) + p))) ;indeterminate length + (cond + ((= tag PACKET-SIGNATURE) + (get-signature pp)) + ((= tag PACKET-PUBLIC-KEY) + (get-public-key pp #f)) + ((= tag PACKET-TRUST) + 'openpgp-trust) ;XXX: non-standard format? + ((= tag PACKET-USER-ID) + (get-user-id pp len)) + ((= tag PACKET-PUBLIC-SUBKEY) + (get-public-key pp #t)) + ((= tag PACKET-USER-ATTRIBUTE) + (get-user-attribute pp len)) + ((= tag PACKET-ONE-PASS-SIGNATURE) + 'one-pass-signature) ;TODO: implement + (else + (error 'get-data "Unsupported packet type" tag))))) + +(define-record-type <openpgp-public-key> + (make-openpgp-public-key version subkey? time value fingerprint) + openpgp-public-key? + (version openpgp-public-key-version) + (subkey? openpgp-public-key-subkey?) + (time openpgp-public-key-time) + (value openpgp-public-key-value) + (fingerprint openpgp-public-key-fingerprint)) + +;;; Signatures + +(define-record-type <openpgp-signature> + (make-openpgp-signature version type pk-algorithm hash-algorithm hashl16 + append-data hashed-subpackets unhashed-subpackets + value) + openpgp-signature? + (version openpgp-signature-version) + (type openpgp-signature-type) + (pk-algorithm openpgp-signature-public-key-algorithm) + (hash-algorithm openpgp-signature-hash-algorithm) + (hashl16 openpgp-signature-hashl16) ;left 16 bits of signed hash + (append-data openpgp-signature-append-data) ;append to data when hashing + (hashed-subpackets openpgp-signature-hashed-subpackets) + (unhashed-subpackets openpgp-signature-unhashed-subpackets) + (value openpgp-signature-value)) + +(define (openpgp-signature-issuer sig) + (cond ((assq 'issuer (openpgp-signature-unhashed-subpackets sig)) => cdr) + ;; XXX: is the issuer always in the unhashed subpackets? + (else #f))) + +(define (openpgp-signature-creation-time sig) + (cond ((assq 'signature-ctime (openpgp-signature-hashed-subpackets sig)) + => (lambda (x) (unixtime (cdr x)))) + ;; XXX: should be an error? + (else #f))) + +(define (openpgp-signature-expiration-time sig) + (cond ((assq 'signature-etime (openpgp-signature-hashed-subpackets sig)) + => (lambda (x) + (unixtime (+ (cdr x) + (openpgp-signature-creation-time sig))))) + (else #f))) + + +(define (get-openpgp-detached-signature/ascii port) + "Read from PORT an ASCII-armored detached signature. Return an +<openpgp-signature> record or the end-of-file object. Raise an error if the +data read from PORT does is invalid or does not correspond to a detached +signature." + (let-values (((data type) (read-radix-64 port))) + (cond ((eof-object? data) data) + ((string=? type "PGP SIGNATURE") + (get-packet (open-bytevector-input-port data))) + (else + (error "expected PGP SIGNATURE" type))))) + +(define (hash-algorithm-name algorithm) ;XXX: should be in Guile-Gcrypt + "Return the name of ALGORITHM, a 'hash-algorithm' integer, as a symbol." + (letrec-syntax ((->name (syntax-rules () + ((_) #f) + ((_ name rest ...) + (if (= algorithm (hash-algorithm name)) + 'name + (->name rest ...)))))) + (->name sha1 sha256 sha384 sha512 sha224 + sha3-224 sha3-256 sha3-384 sha3-512))) + +(define (verify-openpgp-signature sig keyring dataport) + "Verify that the data read from DATAPORT matches SIG, an +<openpgp-signature>. Fetch the public key of the issuer of SIG from KEYRING, +a keyring as returned by 'get-openpgp-keyring'. Return two values: a status +symbol, such as 'bad-signature or 'missing-key, and additional info, such as +the issuer's OpenPGP public key extracted from KEYRING." + (define (check key sig) + (let*-values (((hash-algorithm) (lookup-hash-algorithm + (openpgp-signature-hash-algorithm sig))) + ((port get-hash) (open-hash-port hash-algorithm))) + (dump-port dataport port) + + ;; As per RFC4880 Section 5.2.4 ("Computing Signatures"), hash some of + ;; the fields from the signature packet. + (for-each (cut put-bytevector port <>) + (openpgp-signature-append-data sig)) + (close-port port) + + (let* ((signature (openpgp-signature-value sig)) + (public-key (openpgp-public-key-value key)) + (hash (get-hash)) + (key-type (key-type public-key)) + (data + ;; See "(gcrypt) Cryptographic Functions". + (sexp->canonical-sexp + (if (eq? key-type 'ecc) + `(data + (flags eddsa) + (hash-algo sha512) + (value ,hash)) + `(data + (flags ,(match key-type + ('rsa 'pkcs1) + ('dsa 'rfc6979))) + (hash ,(hash-algorithm-name hash-algorithm) + ,hash)))))) + (values (if (verify signature data public-key) + 'good-signature + 'bad-signature) + key)))) + + ;; TODO: Support SIGNATURE-TEXT. + (if (= (openpgp-signature-type sig) SIGNATURE-BINARY) + (let* ((issuer (openpgp-signature-issuer sig)) + (key-data (lookup-key-by-id keyring issuer))) + ;; Find the primary key or subkey that made the signature. + (let ((key (find (lambda (k) + (and (openpgp-public-key? k) + (= (openpgp-public-key-id k) issuer))) + key-data))) + (if key + (check key sig) + (values 'missing-key issuer)))) + (values 'unsupported-signature sig))) + +(define (get-signature p) + (define (->hex n) + (string-hex-pad (number->string n 16))) + + (define (get-sig p pkalg) + (cond ((= pkalg PUBLIC-KEY-RSA) + (print "RSA signature") + (string->canonical-sexp + (format #f "(sig-val (rsa (s #~a#)))" + (->hex (get-mpi p))))) + ((= pkalg PUBLIC-KEY-DSA) + (print "DSA signature") + (let ((r (get-mpi p)) (s (get-mpi p))) + (string->canonical-sexp + (format #f "(sig-val (dsa (r #~a#) (s #~a#)))" + (->hex r) (->hex s))))) + ((= pkalg PUBLIC-KEY-EDDSA) + (print "EdDSA signature") + (let ((r (get-mpi/bytevector p)) + (s (get-mpi/bytevector p))) + ;; XXX: 'verify' fails down the road with GPG_ERR_INV_LENGTH if + ;; we provide a 31-byte R or S below, hence the second argument + ;; to '->hex' ensuring the MPIs are represented as two-byte + ;; multiples, with leading zeros. + (define (bytevector->hex bv) + (let ((str (bytevector->base16-string bv))) + (if (odd? (bytevector-length bv)) + (string-append "00" str) + str))) + + (string->canonical-sexp + (format #f "(sig-val (eddsa (r #~a#) (s #~a#)))" + (bytevector->hex r) (bytevector->hex s))))) + (else + (list 'unsupported-algorithm + (public-key-algorithm pkalg) + (get-bytevector-all p))))) + (let ((version (get-u8 p))) + (case version + ((3) + (let-values (((hmlen type ctime keyid pkalg halg hashl16) + (get-integers p u8 u8 u32 u64 u8 u8 u16))) + (unless (= hmlen 5) + (error "invalid signature packet")) + (print "Signature type: " type " creation time: " (unixtime ctime)) + (print "Hash algorithm: " (openpgp-hash-algorithm halg)) + (let ((value (get-sig p pkalg))) + (unless (port-eof? p) + (print "Trailing data in signature: " (get-bytevector-all p))) + (make-openpgp-signature version type + (public-key-algorithm pkalg) + (openpgp-hash-algorithm halg) hashl16 + (list (integers->bytevector u8 type + u32 ctime)) + ;; Emulate hashed subpackets + (list (cons 'signature-ctime ctime)) + ;; Unhashed subpackets + (list (cons 'issuer keyid)) + value)))) + ((4) + (let*-values (((type pkalg halg) (get-integers p u8 u8 u8)) + ((hashed-subpackets) + (get-bytevector-n p (get-u16 p))) + ((unhashed-subpackets) + (get-bytevector-n p (get-u16 p))) + ((hashl16) (get-u16 p))) + (print "Signature type: " type) + (print "Hash algorithm: " (openpgp-hash-algorithm halg)) + (let ((value (get-sig p pkalg))) + (unless (port-eof? p) + (print "Trailing data in signature: " (get-bytevector-all p))) + (let* ((subpacket-len (bytevector-length hashed-subpackets)) + (append-data + (list + (integers->bytevector u8 version + u8 type + u8 pkalg + u8 halg + u16 subpacket-len) + hashed-subpackets + ;; http://www.rfc-editor.org/errata_search.php?rfc=4880 + ;; Errata ID: 2214. + (integers->bytevector u8 #x04 + u8 #xff + u32 (+ 6 subpacket-len))))) + (make-openpgp-signature version type + (public-key-algorithm pkalg) + (openpgp-hash-algorithm halg) + hashl16 + append-data + (parse-subpackets hashed-subpackets) + (parse-subpackets unhashed-subpackets) + value))))) + (else + (print "Unsupported signature version: " version) + 'unsupported-signature-version)))) + +(define (parse-subpackets bv) + (define (parse tag data) + (let ((type (fxbit-field tag 0 7)) + (critical? (fxbit-set? tag 7))) + (cond + ((= type SUBPACKET-SIGNATURE-CTIME) + (cons 'signature-ctime + (bytevector-u32-ref data 0 (endianness big)))) + ((= type SUBPACKET-SIGNATURE-ETIME) + (cons 'signature-etime + (bytevector-u32-ref data 0 (endianness big)))) + ((= type SUBPACKET-TRUST-SIGNATURE) + (cons 'trust-signature + (bytevector-u8-ref data 0))) + ((= type SUBPACKET-REVOCABLE) + (cons 'revocable + (= (bytevector-u8-ref data 0) 1))) + ((= type SUBPACKET-KEY-ETIME) + (cons 'key-etime + (bytevector-u32-ref data 0 (endianness big)))) + ((= type SUBPACKET-PREFERRED-SYMMETRIC-ALGORITHMS) + (cons 'preferred-symmetric-algorithms + (map symmetric-key-algorithm (bytevector->u8-list data)))) + ((= type SUBPACKET-ISSUER) + (cons 'issuer + (bytevector-u64-ref data 0 (endianness big)))) + ((= type SUBPACKET-NOTATION-DATA) + (let ((p (open-bytevector-input-port data))) + (let-values (((f1 nlen vlen) + (get-integers p u8 _ _ _ u16 u16))) + (let* ((name (get-bytevector-n p nlen)) + (value (get-bytevector-n p vlen))) + (cons 'notation-data + (list (utf8->string name) + (if (fxbit-set? f1 7) + (utf8->string value) + value))))))) + ((= type SUBPACKET-PREFERRED-HASH-ALGORITHMS) + (cons 'preferred-hash-algorithms + (map openpgp-hash-algorithm (bytevector->u8-list data)))) + ((= type SUBPACKET-PREFERRED-COMPRESSION-ALGORITHMS) + (cons 'preferred-compression-algorithms + (map compression-algorithm (bytevector->u8-list data)))) + ((= type SUBPACKET-KEY-SERVER-PREFERENCES) + (cons 'key-server-preferences + (if (and (>= (bytevector-length data) 1) + (fxbit-set? (bytevector-u8-ref data 0) 7)) + (list 'no-modify) + (list)))) + ((= type SUBPACKET-PREFERRED-KEY-SERVER) + (cons 'preferred-key-server (utf8->string data))) + ((= type SUBPACKET-PRIMARY-USER-ID) + (cons 'primary-user-id (not (zero? (bytevector-u8-ref data 0))))) + ((= type SUBPACKET-POLICY-URI) + (cons 'policy-uri (utf8->string data))) + ((= type SUBPACKET-KEY-FLAGS) + (cons 'key-flags (bytevector->bitnames + data + '(certification sign-data + communications-encryption + storage-encryption + split-key authentication + group-key)))) + ((= type SUBPACKET-SIGNER-USER-ID) + (cons 'signer-user-id (utf8->string data))) + ((= type SUBPACKET-REASON-FOR-REVOCATION) + (let* ((p (open-bytevector-input-port data)) + (revocation-code (get-u8 p))) + (cons 'reason-for-revocation + (list revocation-code + (if (port-eof? p) + "" + (utf8->string (get-bytevector-all p))))))) + ((= type SUBPACKET-FEATURES) + (cons 'features (bytevector->bitnames + data '(modification-detection)))) + ((= type SUBPACKET-EMBEDDED-SIGNATURE) + (cons 'embedded-signature + (get-signature (open-bytevector-input-port data)))) + (else + ;; Unknown subpacket type. If it is critical, then the signature + ;; should be considered invalid. + (print "Unknown subpacket type: " type) + (if critical? + (error "unrecognized critical signature subpacket" type) + (list 'unsupported-subpacket type data)))))) + + (let ((p (open-bytevector-input-port bv))) + (let lp ((subpackets '())) + ;; In case of multiple subpackets of the same type, the last + ;; one should be used. Therefore the list is not reversed + ;; here. + (if (port-eof? p) + (reverse subpackets) + (let* ((len (- (get-v4-length p) 1)) + (tag (get-u8 p)) + (sp (parse tag (get-bytevector-n p len)))) + (print "#;Subpacket " sp) + (lp (cons sp subpackets))))))) + +;;; Public keys + + +(define (openpgp-public-key-id k) + (let ((bv (openpgp-public-key-fingerprint k))) + (bytevector-u64-ref bv + (- (bytevector-length bv) 8) + (endianness big)))) + +(define (get-public-key p subkey?) + (define (fingerprint p) + (let ((len (port-position p))) + (set-port-position! p 0) + (let-values (((sha1-port get) + (open-hash-port (hash-algorithm sha1)))) + (put-u8 sha1-port #x99) + (put-u16 sha1-port len) + (dump-port p sha1-port) + (close-port sha1-port) + (get)))) + (define (get-key p alg) + (define (->hex n) + (string-hex-pad (number->string n 16))) + + (cond ((= alg PUBLIC-KEY-RSA) + (print "Public RSA key") + (let* ((n (get-mpi p)) (e (get-mpi p))) + (string->canonical-sexp + (format #f "(public-key (rsa (n #~a#) (e #~a#)))" + (->hex n) (->hex e))))) + ((= alg PUBLIC-KEY-DSA) + (print "Public DSA key") + (let* ((p* (get-mpi p)) (q (get-mpi p)) + (g (get-mpi p)) (y (get-mpi p))) + (string->canonical-sexp + (format #f "(public-key (dsa (p #~a#)(q #~a#)(g #~a#)(y #~a#)))" + (->hex p*) (->hex q) (->hex g) (->hex y))))) + #; + ((= alg PUBLIC-KEY-ELGAMAL-ENCRYPT-ONLY) ; ; ; ; + (print "Public El-Gamal Key") ; ; ; ; + (let* ((p* (get-mpi p)) (g (get-mpi p)) (y (get-mpi p))) ; ; ; ; + (make-public-elgamal-key p* g y))) + ((= alg PUBLIC-KEY-EDDSA) + ;; See + ;; <https://tools.ietf.org/html/draft-koch-eddsa-for-openpgp-04> + ;; and openpgp-oid.c in GnuPG. + (print "Public EdDSA key") + (let* ((len (get-u8 p)) + (oid (bytevector->uint (get-bytevector-n p len))) + (q (get-mpi p))) + (define curve + (match oid + (#x2b06010401da470f01 'Ed25519) + (#x2b060104019755010501 'Curve25519))) + + (string->canonical-sexp + (format #f "(public-key (ecc (curve ~a)(flags ~a)(q #~a#)))" + curve + (if (eq? curve 'Curve25519) 'djb-tweak 'eddsa) + (->hex q))))) + (else + (list 'unsupported-algorithm ;FIXME: throw + (public-key-algorithm alg) + (get-bytevector-all p))))) + (let ((version (get-u8 p))) + (case version + ((4) + (let-values (((ctime alg) (get-integers p u32 u8))) + (print "Key creation time: " (unixtime ctime)) + (let ((key (get-key p alg))) + (unless (port-eof? p) + ;; Probably an error? Gonna cause trouble anyway. + (print "Trailing data in public key: " (get-bytevector-all p))) + (let ((digest (fingerprint p))) + (make-openpgp-public-key version subkey? ctime key + digest))))) + (else + (print "Unsupported public key version: " version) + 'unsupported-public-key-version)))) + +(define (openpgp-public-key-primary? key) + (and (openpgp-public-key? key) + (not (openpgp-public-key-subkey? key)))) + +;;; User IDs and User attributes + + +(define-record-type <openpgp-user-id> + (make-openpgp-user-id value unparsed) + openpgp-user-id? + (value openpgp-user-id-value) + (unparsed openpgp-user-id-unparsed)) + +(define (get-user-id p len) + (let ((unparsed (get-bytevector-n p len))) + (make-openpgp-user-id (utf8->string unparsed) unparsed))) + +(define-record-type <openpgp-user-attribute> + (make-openpgp-user-attribute unparsed) + openpgp-user-attribute? + (unparsed openpgp-user-attribute-unparsed)) + +(define (get-user-attribute p len) + (let ((bv (get-bytevector-n p len))) + ;; TODO: bv contains subpackets. Type 1 is JFIF. + (make-openpgp-user-attribute bv))) + + +;;; Keyring management + +(define-record-type <openpgp-keyring> + (openpgp-keyring table) + openpgp-keyring? + (table openpgp-keyring-table)) ;vhash mapping key id to packets + +(define (lookup-key-by-id keyring id) + "Return a list of packets for the key with ID in KEYRING, or #f if ID could +not be found. ID must be the 64-bit key ID of the key, an integer." + (match (vhash-assv id (openpgp-keyring-table keyring)) + ((_ . lst) lst) + (#f '()))) + +;; Reads a keyring from the binary input port p. It must not be +;; ASCII armored. + +(define %empty-keyring + ;; The empty keyring. + (openpgp-keyring vlist-null)) + +(define* (get-openpgp-keyring port + #:optional (keyring %empty-keyring) + #:key (limit -1)) + "Read from PORT an OpenPGP keyring in binary format; return a keyring based +on all the OpenPGP primary keys that were read. The returned keyring +complements KEYRING. LIMIT is the maximum number of keys to read, or -1 if +there is no limit." + (let lp ((pkt (get-packet port)) + (limit limit) + (keyring (openpgp-keyring-table keyring))) + (print "#;key " pkt) + (cond ((or (zero? limit) (eof-object? pkt)) + (openpgp-keyring keyring)) + ((openpgp-public-key-primary? pkt) + ;; Read signatures, user id's, subkeys + (let lp* ((pkt (get-packet port)) + (pkts (list pkt)) + (key-ids (list (openpgp-public-key-id pkt)))) + (print "#;keydata " pkt) + (cond ((or (eof-object? pkt) + (eq? pkt 'unsupported-public-key-version) + (openpgp-public-key-primary? pkt)) + ;; KEYRING is indexed by key-id. Key ids for both the + ;; primary key and subkeys all point to the list of + ;; packets. + (lp pkt + (- limit 1) + (fold (cute vhash-consv <> (reverse pkts) <>) + keyring key-ids))) + ((openpgp-public-key? pkt) ;subkey + (lp* (get-packet port) (cons pkt pkts) + (cons (openpgp-public-key-id pkt) key-ids))) + (else + (lp* (get-packet port) (cons pkt pkts) key-ids))))) + (else + ;; Skip until there's a primary key. Ignore errors... + (lp (get-packet port) limit keyring))))) + + +;;; +;;; Radix-64 (RFC4880). +;;; + +(define (crc24 bv) + "Compute a CRC24 as described in RFC4880, Section 6.1." + (define poly #x1864cfb) + + (let loop ((crc #xb704ce) + (index 0)) + (if (= index (bytevector-length bv)) + (logand crc #xffffff) + (let ((crc (logxor (ash (bytevector-u8-ref bv index) 16) + crc))) + (let inner ((i 0) + (crc crc)) + (if (< i 8) + (let ((crc (ash crc 1))) + (inner (+ i 1) + (if (zero? (logand crc #x1000000)) + crc + (logxor crc poly)))) + (loop crc (+ index 1)))))))) + +(define %begin-block-prefix "-----BEGIN ") +(define %begin-block-suffix "-----") + +(define %end-block-prefix "-----END ") +(define %end-block-suffix "-----") + +(define (read-radix-64 port) + "Read from PORT an ASCII-armored Radix-64 stream, decode it, and return the +result as a bytevector as well as the type, a string such as \"PGP MESSAGE\". +Return #f if PORT does not contain a valid Radix-64 stream, and the +end-of-file object if the Radix-64 sequence was truncated." + ;; This is the same as 'get-delimited-base64', except that it implements the + ;; CRC24 check. + (define (skip-headers port) + ;; Skip the Radix-64 "armor headers". + (match (read-line port) + ((? eof-object? eof) eof) + ((= string-trim-both "") "") + (_ (skip-headers port)))) + + (let ((line (string-trim-right (read-line port)))) + (if (and (string-prefix? %begin-block-prefix line) + (string-suffix? %begin-block-suffix line)) + (let* ((kind (string-drop-right + (string-drop line (string-length %begin-block-prefix)) + (string-length %begin-block-suffix))) + (end (string-append %end-block-prefix kind + %end-block-suffix))) + (skip-headers port) + (let loop ((lines '())) + (let ((line (read-line port))) + (match line + ((? eof-object? eof) + (values eof kind)) + ((= string-trim-both "") + (loop lines)) + ((= string-trim-both str) + (if (string=? str end) + (match lines + ((crc lines ...) + ;; The last line should be the CRC, starting with an + ;; "=" sign. + (let ((crc (and (string-prefix? "=" crc) + (base64-decode (string-drop crc 1)))) + (data (base64-decode + (string-concatenate-reverse lines)))) + (if (and crc (= (bytevector->uint crc) (crc24 data))) + (values data kind) + (values #f kind)))) + (_ + (values #f kind))) + (loop (cons str lines)))))))) + (values #f #f)))) diff --git a/tests/civodul.key b/tests/civodul.key new file mode 100644 index 0000000000..272600ac93 --- /dev/null +++ b/tests/civodul.key @@ -0,0 +1,1345 @@ +-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+RjBYn+8g/BrdPTD9OUAMufM+0SDlZujhrA==
+=+/gj
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/tests/dsa.key b/tests/dsa.key new file mode 100644 index 0000000000..4727975c63 --- /dev/null +++ b/tests/dsa.key @@ -0,0 +1,25 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQMuBF4SQfARCACb/C7qcwKhOdaej1z8dK02iMJlw/C868VEeAuSvXHBE5OULm1+ +SlwPCgsLIhe8AIsW0F8zgWlNdOKbcmU1NdzUfo0PIRA8ASerZ3EFd7cloRjk1X3c +XbklFQ8D37thgFXYBOkkjzKwCvc+ebcQQsRSvJLhQODSRzknIQBYLoYjKh8skEwY +uK+rFs7fEHTrCwnriF7QCZnGqoScS56MrgEtHHwBDpKt8CruSekEHAfI5INMhb6R +fdVNTj7TL9gCOlYA6IPK6pfYKjghQ79IGMcGnaEPUdiEuAbc1AVQtfRi4e/IbbN6 +/CDmfSQ/fCYm9hQ5sAMzUCqDreqqYrpEYmVHAQC3uXiV7qjDe2vlfz4GNSFOqvHC +xHp9UYWE6IQFzVutMwgAgldl3Ql6zxIoiU76bXRDP+W+g67uW1Fnd6ltOVYb4rxp +wIRlQpwZeNPzFeZHZ1mJA1rvdD3mORnnnIIwW9Cr5Kn/e63PBJJcYJZZ6bnWYh5O +1MDzyn0CYu4btP0tj7PNxKfxvIxDX3sqfkBFsGgquwa/AwWrdWXD99//PK0iNGN4 +WewwXmC2S2SmcuHL0nB4eV6uuQZOK6u3/end1/FqAMEJAW4jC7x7UvbeFs1dwiJv +psjluTpP1QDh7ySDfBOANlxOxAM6oCfvUqZ+pifNFw7t3p1eiK3wtjB8fer7bZg3 +OT4Pl4gImmCjXs0cse0+FLpUA/gzPHxYR/rUyD/nQwf8CfFRGu+bGFju3YHbZ2T0 +cHF/9c3sCdQU7nVnYleySnv1OMDSYoZ7geqgC2q0pnHeezII7hcJB8tKx3BV+J7A +WYUL31K4gybK9VkFQC8h+BzPjnzjXEHgL5GY621cPSLJzOyFhY9lKrWUD/DVGXtu +xFjissXG2h6jgf+BAqDCKFVYyu/7TQuDA/FKPhx/8Hn9LX4A3CTFswnsRtABGt6t +U4yUfQWhnDqLDYWrjvXOEHbMQuBOAU3rPpTLLyQzyKVsQZlMBR5UrSXXY1lN76yl +J0NAyeOmgvDT75QAVHPxp9lidRTQJHXU1Ah+N/fzPYamKmgheCXZE8r5cPY3Mkvp +w7QbPGx1ZG8rdGVzdC1kc2FAY2hib3VpYi5vcmc+iJYEExEIAD4WIQQohKmAQiMw +pPM92X9YeRgEe+i9LAUCXhJB8AIbAwUJA8JnAAULCQgHAgYVCgkICwIEFgIDAQIe +AQIXgAAKCRBYeRgEe+i9LOyvAP0a2DIMruGZSHeWcQaNiRWb2/UEq4ClRw67rA7f +39sD5AD+PKeovYJkTSV+F00QKHibMhoGurxABnEUeqmetGITVSU= +=YZip +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/ed25519.key b/tests/ed25519.key new file mode 100644 index 0000000000..f6bf906783 --- /dev/null +++ b/tests/ed25519.key @@ -0,0 +1,10 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mDMEXqNaoBYJKwYBBAHaRw8BAQdArviKtelb4g0I3zx9xyDS40Oz8i1/LRXqppG6 +b23Hdim0KEVkIFR3by1GaWZ0eSA8bHVkbyt0ZXN0LWVjY0BjaGJvdWliLm9yZz6I +lgQTFggAPhYhBETTHiGvcTj5tjIoCncfScv6rgctBQJeo1qgAhsDBQkDwmcABQsJ +CAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEHcfScv6rgctq4MA/1R9G0roEwrHwmTd +DHxt211eLqupwXE0Z7xY2FH6DHk9AP4owEefBU7jQprSAzBS+c6gdS3SCCKKqAh6 +ToZ4LmbKAw== +=FXMK +-----END PGP PUBLIC KEY BLOCK----- diff --git a/tests/ed25519.sec b/tests/ed25519.sec new file mode 100644 index 0000000000..068738dfab --- /dev/null +++ b/tests/ed25519.sec @@ -0,0 +1,10 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lFgEXqNaoBYJKwYBBAHaRw8BAQdArviKtelb4g0I3zx9xyDS40Oz8i1/LRXqppG6 +b23HdikAAQDGgjcUcvqR+nGYcf5UHzy9xlO/dBZX4f9QV1ILDIGt0hAYtChFZCBU +d28tRmlmdHkgPGx1ZG8rdGVzdC1lY2NAY2hib3VpYi5vcmc+iJYEExYIAD4WIQRE +0x4hr3E4+bYyKAp3H0nL+q4HLQUCXqNaoAIbAwUJA8JnAAULCQgHAgYVCgkICwIE +FgIDAQIeAQIXgAAKCRB3H0nL+q4HLauDAP9UfRtK6BMKx8Jk3Qx8bdtdXi6rqcFx +NGe8WNhR+gx5PQD+KMBHnwVO40Ka0gMwUvnOoHUt0ggiiqgIek6GeC5mygM= +=VjjI +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tests/openpgp.scm b/tests/openpgp.scm new file mode 100644 index 0000000000..8a3c7bbeb7 --- /dev/null +++ b/tests/openpgp.scm @@ -0,0 +1,248 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2020 Ludovic Courtès <ludo@gnu.org> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it and/or modify it +;;; under the terms of the GNU General Public License as published by +;;; the Free Software Foundation; either version 3 of the License, or (at +;;; your option) any later version. +;;; +;;; GNU Guix is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (tests-openpgp) + #:use-module (guix openpgp) + #:use-module (gcrypt hash) + #:use-module (gcrypt pk-crypto) + #:use-module (ice-9 binary-ports) + #:use-module (ice-9 match) + #:use-module (rnrs bytevectors) + #:use-module (srfi srfi-1) + #:use-module (srfi srfi-11) + #:use-module (srfi srfi-64) + #:use-module (srfi srfi-71)) + +(define %radix-64-sample + ;; Example of Radix-64 encoding from Section 6.6 of RFC4880. + "\ +-----BEGIN PGP MESSAGE----- +Version: OpenPrivacy 0.99 + +yDgBO22WxBHv7O8X7O/jygAEzol56iUKiXmV+XmpCtmpqQUKiQrFqclFqUDBovzS +vBSFjNSiVHsuAA== +=njUN +-----END PGP MESSAGE-----\n") + +(define %radix-64-sample/crc-mismatch + ;; This time with a wrong CRC24 value. + "\ +-----BEGIN PGP MESSAGE----- + +yDgBO22WxBHv7O8X7O/jygAEzol56iUKiXmV+XmpCtmpqQUKiQrFqclFqUDBovzS +vBSFjNSiVHsuAA== +=AAAA +-----END PGP MESSAGE-----\n") + +(define %civodul-fingerprint + "3CE4 6455 8A84 FDC6 9DB4 0CFB 090B 1199 3D9A EBB5") + +(define %civodul-key-id #x090B11993D9AEBB5) ;civodul.key + +;; Test keys. They were generated in a container along these lines: +;; guix environment -CP --ad-hoc gnupg pinentry +;; then, within the container: +;; mkdir ~/.gnupg +;; echo pinentry-program ~/.guix-profile/bin/pinentry-tty > ~/.gnupg/gpg-agent.conf +;; gpg --quick-gen-key '<ludo+test-rsa@chbouib.org>' rsa +;; or similar. +(define %rsa-key-id #xAE25DA2A70DEED59) ;rsa.key +(define %dsa-key-id #x587918047BE8BD2C) ;dsa.key +(define %ed25519-key-id #x771F49CBFAAE072D) ;ed25519.key + + +;;; The following are detached signatures created commands like: +;;; echo 'Hello!' | gpg -sba --digest-algo sha512 +;;; They are detached (no PACKET-ONE-PASS-SIGNATURE) and uncompressed. + +(define %hello-signature/rsa + ;; Signature of the ASCII string "Hello!\n". + "\ +-----BEGIN PGP SIGNATURE----- + +iQEzBAABCAAdFiEEOF+Gz8hrZlpcFl5rriXaKnDe7VkFAl4SRF0ACgkQriXaKnDe +7VlIyQf/TU5rGUK42/C1ULoWvvm25Mjwh6xxoPPkuBxvos8bE6yKr/vJZePU3aSE +mjbVFcO7DioxHMqLd49j803bUtdllJVU18ex9MkKbKjapkgEGkJsuTTzqyONprgk +7xtZGBWuxkP1M6hJICJkA3Ys+sTdKalux/pzr5OWAe+gxytTF/vr/EyJzdmBxbJv +/fhd1SeVIXSw4c5gf2Wcvcgfy4N5CiLaUb7j4646KBTvDvmUMcDZ+vmKqC/XdQeQ +PrjArGKt40ErVd98fwvNHZnw7VQMx0A3nL3joL5g7/RckDOUb4mqKoqLsLd0wPHP +y32DiDUY9s3sy5OMzX4Y49em8vxvlg== +=ASEm +-----END PGP SIGNATURE-----") + + +(define %hello-signature/dsa + "\ +-----BEGIN PGP SIGNATURE----- + +iHUEABEIAB0WIQQohKmAQiMwpPM92X9YeRgEe+i9LAUCXhJFpQAKCRBYeRgEe+i9 +LDAaAQC0lXPQepvZBANAUtRLMZuOwL9NQPkfhIwUXtLEBBzyFQD/So8DcybXpRBi +JKOiyAQQjMs/GJ6qMEQpRAhyyJRAock= +=iAEc +-----END PGP SIGNATURE-----") + + +(define %hello-signature/ed25519/sha256 ;digest-algo: sha256 + "\ +-----BEGIN PGP SIGNATURE----- + +iHUEABYIAB0WIQRE0x4hr3E4+bYyKAp3H0nL+q4HLQUCXqRADAAKCRB3H0nL+q4H +LUImAP9/foaSjPFC/MSr52LNV5ROSL9haea4jPpUP+N6ViFGowEA+AE/xpXPIqsz +R6CdxMevURuqUpqQ7rHeiMmdUepeewU= +=tLXy +-----END PGP SIGNATURE-----") + +(define %hello-signature/ed25519/sha512 ;digest-algo: sha512 + "\ +-----BEGIN PGP SIGNATURE----- + +iHUEABYKAB0WIQRE0x4hr3E4+bYyKAp3H0nL+q4HLQUCXqRAGgAKCRB3H0nL+q4H +LTeKAP0S8LiiosJXOARlYNdhfGw9j26lHrbwJh5CORGlaqqIJAEAoMYcmtNa2b6O +inlEwB/KQM88O9RwA8xH7X5a0rodOw4= +=68r/ +-----END PGP SIGNATURE-----") + +(define %hello-signature/ed25519/sha1 ;digest-algo: sha1 + "\ +-----BEGIN PGP SIGNATURE----- + +iHUEABYCAB0WIQRE0x4hr3E4+bYyKAp3H0nL+q4HLQUCXqRALQAKCRB3H0nL+q4H +LdhEAQCfkdYhIVRa43oTNw9EL/TDFGQjXSHNRFVU0ktjkWbkQwEAjIXhvj2sqy79 +Pz7oopeN72xgggYUNT37ezqN3MeCqw0= +=AE4G +-----END PGP SIGNATURE-----") + + +(test-begin "openpgp") + +(test-equal "read-radix-64" + '(#t "PGP MESSAGE") + (let-values (((data type) + (call-with-input-string %radix-64-sample read-radix-64))) + (list (bytevector? data) type))) + +(test-equal "read-radix-64, CRC mismatch" + '(#f "PGP MESSAGE") + (call-with-values + (lambda () + (call-with-input-string %radix-64-sample/crc-mismatch + read-radix-64)) + list)) + +(test-assert "get-openpgp-keyring" + (let* ((key (search-path %load-path "tests/civodul.key")) + (keyring (get-openpgp-keyring + (open-bytevector-input-port + (call-with-input-file key read-radix-64))))) + (match (lookup-key-by-id keyring %civodul-key-id) + (((? openpgp-public-key? primary) packets ...) + (and (= (openpgp-public-key-id primary) %civodul-key-id) + (not (openpgp-public-key-subkey? primary)) + (string=? (openpgp-format-fingerprint + (openpgp-public-key-fingerprint primary)) + %civodul-fingerprint) + (string=? (openpgp-user-id-value (find openpgp-user-id? packets)) + "Ludovic Courtès <ludo@gnu.org>")))))) + +(test-equal "get-openpgp-detached-signature/ascii" + (list `(,%dsa-key-id dsa sha256) + `(,%rsa-key-id rsa sha256) + `(,%ed25519-key-id eddsa sha256) + `(,%ed25519-key-id eddsa sha512) + `(,%ed25519-key-id eddsa sha1)) + (map (lambda (str) + (let ((signature (get-openpgp-detached-signature/ascii + (open-input-string str)))) + (list (openpgp-signature-issuer signature) + (openpgp-signature-public-key-algorithm signature) + (openpgp-signature-hash-algorithm signature)))) + (list %hello-signature/dsa + %hello-signature/rsa + %hello-signature/ed25519/sha256 + %hello-signature/ed25519/sha512 + %hello-signature/ed25519/sha1))) + +(test-equal "verify-openpgp-signature, missing key" + `(missing-key ,%rsa-key-id) + (let* ((keyring (get-openpgp-keyring (%make-void-port "r"))) + (signature (get-openpgp-packet + (open-bytevector-input-port + (call-with-input-string %hello-signature/rsa + read-radix-64))))) + (let-values (((status key) + (verify-openpgp-signature signature keyring + (open-input-string "Hello!\n")))) + (list status key)))) + +(test-equal "verify-openpgp-signature, good signatures" + `((good-signature ,%rsa-key-id) + (good-signature ,%dsa-key-id) + (good-signature ,%ed25519-key-id) + (good-signature ,%ed25519-key-id) + (good-signature ,%ed25519-key-id)) + (map (lambda (key signature) + (let* ((key (search-path %load-path key)) + (keyring (get-openpgp-keyring + (open-bytevector-input-port + (call-with-input-file key read-radix-64)))) + (signature (get-openpgp-packet + (open-bytevector-input-port + (call-with-input-string signature + read-radix-64))))) + (let-values (((status key) + (verify-openpgp-signature signature keyring + (open-input-string "Hello!\n")))) + (list status (openpgp-public-key-id key))))) + (list "tests/rsa.key" "tests/dsa.key" + "tests/ed25519.key" "tests/ed25519.key" "tests/ed25519.key") + (list %hello-signature/rsa %hello-signature/dsa + %hello-signature/ed25519/sha256 + %hello-signature/ed25519/sha512 + %hello-signature/ed25519/sha1))) + +(test-equal "verify-openpgp-signature, bad signature" + `((bad-signature ,%rsa-key-id) + (bad-signature ,%dsa-key-id) + (bad-signature ,%ed25519-key-id) + (bad-signature ,%ed25519-key-id) + (bad-signature ,%ed25519-key-id)) + (let ((keyring (fold (lambda (key keyring) + (let ((key (search-path %load-path key))) + (get-openpgp-keyring + (open-bytevector-input-port + (call-with-input-file key read-radix-64)) + keyring))) + %empty-keyring + '("tests/rsa.key" "tests/dsa.key" + "tests/ed25519.key" "tests/ed25519.key" + "tests/ed25519.key")))) + (map (lambda (signature) + (let ((signature (get-openpgp-packet + (open-bytevector-input-port + (call-with-input-string signature + read-radix-64))))) + (let-values (((status key) + (verify-openpgp-signature signature keyring + (open-input-string "What?!")))) + (list status (openpgp-public-key-id key))))) + (list %hello-signature/rsa %hello-signature/dsa + %hello-signature/ed25519/sha256 + %hello-signature/ed25519/sha512 + %hello-signature/ed25519/sha1)))) + +(test-end "openpgp") diff --git a/tests/rsa.key b/tests/rsa.key new file mode 100644 index 0000000000..0ef9145ef0 --- /dev/null +++ b/tests/rsa.key @@ -0,0 +1,18 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBF4SRCYBCAC6eVyonmey9Lsa1QpWIcumkExZWmAsTNhNNrdhasU4rC0DGRnw +lJtey4h/5NRcGmur4cwwnHUyh9RhQOZgc4MkWfUECfgY98dhjq6+wSavSMwYJyKM +7yGuJgKQBBhdkfjYONP4eHbucifGNhsNRSURUREVCarOYa1AhmH4cmTPe7cUA8mH +EfQ2SOsmAUBNjn/Ba2Us8ydiZWGpJXYdzsXQ3HZl1vV2UtPEepPjAkJZa/7hm06z +9WrlOUxoro/R2R7COMWpzuhmY1Ak2VB4H6OMqPAEOk+/H5Pda1yCI9oRROawC24h +4yZYTpcRKV0EQ4cd4Z/DKA4gJdjufyRrmk0fABEBAAG0GzxsdWRvK3Rlc3QtcnNh +QGNoYm91aWIub3JnPokBVAQTAQgAPhYhBDhfhs/Ia2ZaXBZea64l2ipw3u1ZBQJe +EkQmAhsDBQkDwmcABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEK4l2ipw3u1Z +c70IAI+eBLJzXGXNlugNE5rl5YplrLQem9otL7OKIpR+ye3Wg/DRZvN9x+lvUftq +rG0+wqxo/WQTy6ZLDUI83OY13zLXDKjRgPdqPYBAYxCY8CMayjDUv8axZVEfC7IX +IYgqzZg0E0dfF3m9S+6WUfOYCS5qR2go7TxbrnDyhDiswd5r3TRX5U+asHm0iXTy +Pmb0WY301mm1UPToOHSpweMuCw/n5as15o9CWeUJa/I0J6puM66ZRqGt8+7BSCu6 +ata0BYLBCUD8aqhgNQpcMAkTRUSr8LNgfgdxr2Ozr+FF39NXGfLihL18AQEvh3SI +K/5YAnXV2oMRhOQttDJROOXByoY= +=N6XF +-----END PGP PUBLIC KEY BLOCK----- |