In practice we're always using the same key pair,
/etc/guix/signing-key.{pub,sec}. Keeping them in cache allows us to
avoid redundant I/O and parsing when signing multiple store items in a
row.
* guix/scripts/authenticate.scm (load-key-pair): New procedure.
(sign-with-key): Remove 'key-file' parameter and add 'public-key' and
'secret-key'. Adjust accordingly.
(validate-signature): Add 'acl' parameter and pass it to
'authorized-key?'.
(guix-authenticate)[call-with-reply]: New procedure.
[with-reply]: New macro.
Call 'current-acl' upfront and cache its result. Add 'key-pairs' as an
argument to 'loop' and use it as a cache of key pairs.
Previously, we'd spawn 'guix authenticate' once for each item that has
to be signed (when exporting) or authenticated (when importing). Now,
we spawn it once for all and then follow a request/reply protocol. This
reduces the wall-clock time of:
guix archive --export -r $(guix build coreutils -d)
from 30s to 2s.
* guix/scripts/authenticate.scm (sign-with-key): Return the signature
instead of displaying it. Raise a &formatted-message instead of calling
'leave'.
(validate-signature): Likewise.
(read-command): New procedure.
(define-enumerate-type, reply-code): New macros.
(guix-authenticate)[send-reply]: New procedure.
Change to read commands from current-input-port.
* nix/libstore/local-store.cc (runAuthenticationProgram): Remove.
(authenticationAgent, readInteger, readAuthenticateReply): New
functions.
(signHash, verifySignature): Rewrite in terms of the agent.
* tests/store.scm ("import not signed"): Remove 'pk' call.
("import signed by unauthorized key"): Check the error message of C.
* tests/guix-authenticate.sh: Rewrite using the new protocol.
fixlet
There's no reason at this point to mimic the calling convention of the
'openssl' command.
* nix/libstore/local-store.cc (LocalStore::exportPath): Add only "sign"
and HASH to ARGS. Remove 'tmpDir' and 'hashFile'.
(LocalStore::importPath): Add only "verify" and SIGNATURE to
* guix/scripts/authenticate.scm (guix-authenticate): Adjust
accordingly; remove the OpenSSL-style clauses.
(read-hash-data): Remove.
(sign-with-key): Replace 'port' with 'sha256' and adjust accordingly.
(validate-signature): Export SIGNATURE to be a canonical sexp.
* tests/guix-authenticate.sh: Adjust tests accordingly.
Fixes <http://bugs.gnu.org/17312>.
* guix/scripts/authenticate.scm (guix-authenticate): Add calls to
'set-port-encoding!' and 'set-port-conversion-strategy!'. Wrap body
in 'with-fluids' form that sets '%default-port-encoding' and
'%default-port-conversion-strategy'.
* tests/guix-authenticate.sh: Add test.
* tests/pk-crypto.scm ("hash corrupt due to restrictive locale
encoding"): Add reference to bug.
* guix/scripts/authenticate.scm (guix-authenticate): Add clauses
for ("rsautl" "-sign" "-inkey" key) and ("rsautl" "-verify" "-inkey" _
"-pubin").
* tests/guix-authenticate.sh (hash): Add test using -sign and -verify in
a pipeline.
* guix/scripts/authenticate.scm (read-canonical-sexp): Change to expect
a port instead of a file name.
(read-hash-data): Likewise.
(sign-with-key, validate-signature): New procedures.
(guix-authenticate): Rewrite in terms of these two procedures.
* guix/pk-crypto.scm (bytevector->hash-data): Add #:key-type parameter.
Use the 'pkcs1' flag when KEY-TYPE is 'rsa', and 'rfc6979' when
KEY-TYPE is 'ecc' or 'dsa'.
(key-type): New procedure.
* guix/scripts/authenticate.scm (read-hash-data): Add 'key-type'
parameter. Pass it to 'bytevector->hash-data'. Adjust caller
accordingly.
* tests/pk-crypto.scm (%ecc-key-pair): New variable.
("key-type"): New test.
("sign + verify"): Pass #:key-type to 'bytevector->hash-data'.
("sign + verify, Ed25519"): New test.
* guix/pki.scm (signature-subject, signature-signed-data,
valid-signature?): New procedures.
* guix/scripts/authenticate.scm (guix-authenticate): Adjust to use
them.
* guix/scripts/authenticate.scm (signature-sexp): Remove.
(guix-authenticate): Upon '-verify', check whether the signature's
public key passes 'authorized-key?'.
* guix/scripts/authenticate.scm (signature-sexp): New procedure.
(guix-authenticate): Use it to produce the signature. Adjust
verification code accordingly.
* tests/store.scm ("import corrupt path"): Adjust test accordingly.
* guix/pk-crypto.scm: Rename procedures, variables, etc. from
'gcry-sexp' to 'canonical-sexp'. Add comment with references.
* guix/scripts/authenticate.scm, tests/pk-crypto.scm: Adjust
accordingly.