Hey folks, Liliana Marie Prikler <liliana.prik...@gmail.com> writes:
> Hi Ludo, > > Am Donnerstag, den 21.10.2021, 22:13 +0200 schrieb Ludovic Courtès: >> Hi! >> >> Liliana Marie Prikler <liliana.prik...@gmail.com> skribis: >> >> > let's say I wanted to add my own substitute server to my >> > config.scm. >> > At the time of writing, I would have to add said server's public >> > key to >> > the authorized-keys of my guix-configuration like so: >> > (cons* (local-file "my-key.pub") %default-authorized-guix-keys) >> > or similarily with append. This local-file incantation is however >> > pretty weak. It changes based on the current working directory and >> > even if I were to use an absolute path, I'd have to copy both that >> > file >> > and the config.scm to a new machine were I to use the same >> > configuration there as well. >> >> Note that you could use ‘plain-file’ instead of ‘local-file’ and >> inline the key canonical sexp in there. > Yes, but for that I'd have to either write a (multi-line) string > directly, which visibly "breaks" indentation of the rest of the file, > or somehow generate a string which adds at least one layer of > indentation. The former is imo unacceptable, the latter merely > inconvenient. Would some arbitrary s-expression be a workable solution? See below for an example for what I understood was your current use-case. >> > However, it turns out that the format for said key files is some >> > actually pretty readable Lisp-esque stuff. For instance, an ECC >> > key reads like >> > (public-key (ecc (curve CURVE) (q #Q#))) >> > with spaces omitted for simplicity. >> > Were it not for the (q #Q#) bit, we could construct it using >> > scheme-file. In fact, it is so simple that in my local config I >> > now do exactly that. >> >> Yeah it’s frustrating that canonical sexps are almost, but not quite, >> Scheme sexps. :-) >> >> (gcrypt pk-crypto) has a ‘canonical-sexp->sexp’ procedure: >> >> --8<---------------cut here---------------start------------->8--- >> scheme@(guile-user)> ,use(gcrypt pk-crypto) >> scheme@(guile-user)> ,use(rnrs io ports) >> scheme@(guile-user)> (string->canonical-sexp >> (call-with-input-file >> "etc/substitutes/ci.guix.info.pub" >> get-string-all)) >> $18 = #<canonical-sexp 7fce7f4e8b40 | 15d96a0> >> scheme@(guile-user)> ,pp (canonical-sexp->sexp $18) >> $19 = (public-key >> (ecc (curve Ed25519) >> (q #vu8(141 21 111 41 93 36 176 217 168 111 165 116 26 132 15 >> 242 210 79 96 247 182 196 19 72 20 173 85 98 89 113 179 148)))) >> --8<---------------cut here---------------end--------------->8--- >> >> > (define-record-type* <ecc-key> ...) >> > (define-gexp-compiler (ecc-key-compiler (ecc-key <ecc-key>) ...) >> > ...) >> > >> > (ecc-key >> > (name "my-key.pub") >> > (curve 'Ed25519) >> > (q "ABCDE...")) >> > >> > Could/should we support such formats out of the box? WDYT? >> >> With this approach, we’d end up mirroring all the canonical sexps >> used by libgcrypt, which doesn’t sound great from a maintenance POV. > Given that we can use canonical sexps, what about a single canonical- > sexp compiler then? I'd have to think about this a bit more when I > have the time to, but having a way of writing the canonical sexp > "directly" would imo be advantageous. What about something such as the following? --8<---------------cut here---------------start------------->8--- (use-modules (gcrypt base16) (gcrypt pk-crypto)) (define-record-type <canonical-sexp-wrapper> (canonical-sexp-wrapper name sexp) canonical-sexp-wrapper? (name canonical-sexp-wrapper-name) (sexp canonical-sexp-wrapper-sexp)) (define-gexp-compiler (canonical-sexp-wrapper-compiler (wrapper <canonical-sexp-wrapper>) system target) (match wrapper (($ <canonical-sexp-wrapper> name sexp) (text-file name (canonical-sexp->string (sexp->canonical-sexp sexp)) '())))) --8<---------------cut here---------------end--------------->8--- This would still leave constructing your s-expression as an exercise to the reader, which is definitely not amazing. In this specific instance, I had to look at the output of canonical-sexp->sexp, which is of course whatever the opposite of discoverable and good UX :). For the Ed25519 key: --8<---------------cut here---------------start------------->8--- (define my-public-key (canonical-sexp-wrapper "my-key.pub" `(public-key (ecc (curve Ed25519) (q ,(base16-string->bytevector (string-downcase "C9F307AE..."))))))) --8<---------------cut here---------------end--------------->8--- To improve on this, is one sexp-based-gexp-compiler + N helper functions to construct the most-used value types a direction worth exploring? - Jelle