~tslil/msr

Small public-key verification tool
a2a0a1be — Tslil Clingman 5 years ago
Small bug in interactive password reading
3649f787 — Tslil Clingman 5 years ago
Small tweaks
26d1f221 — Tslil Clingman 5 years ago
Init

refs

master
browse  log 

clone

read-only
https://git.sr.ht/~tslil/msr
read/write
git@git.sr.ht:~tslil/msr

You can also use your local clone with git send-email.

#msr

Small public key verification tool

Inspired by OpenBSD's signify and minisign I decided to spend some time learning libsodium and re-implement minisign for myself.

Currently, this programme is a superset of minisign (and so partially signify) but in the future signatures and or keys may become incompatible -- it seemed in bad taste to do that immediately.

#Usage

Compile it and run msr --help and you'll find

  -G, --generate[=FILE]      Generate a new key pair, storing in
                             `FILE.{pub,key}' (FILE defaults to msr)
  -S, --sign-detached=FILE   Sign FILE by generating a separate signature
  -T, --sign-text=FILE       Sign FILE by appending a signature
  -V, --verify-detached=FILE Verify the detached signature on FILE
  -X, --verify-text=FILE     Verify the inline text signature in FILE
  -f, --signature-file=FILE  Use FILE as the signature file for detached
                             signing and verification purposes
  -p, --pubkey-file=FILE     Use the public key in FILE
      --pubkey-string=STR    Use the public key encoded in STR
  -s, --seckey-file=FILE     Use the secret key in FILE
      --seckey-string=STR    Use the secret key encoded in STR
      --password-file=FILE   Load secret key passphrase from FILE
      --comment-pubkey=STR   Use STR for the default untrusted comment in the
                             generated public key file
      --comment-seckey=STR   Use STR for the default untrusted comment in the
                             generated secret key file
  -t, --comment-trusted=STR  Use STR for the trusted comment when making a
                             detached signature
  -u, --comment-untrusted=STR   Use STR for the default untrusted comment when
                             making a detached signature
  -q, --quiet                Produce no output
  -?, --help                 Give this help list
      --usage                Give a short usage message
      --version              Print program version

#Specifications

At the behest of libsodium, we use ed25519 for all things signing, scryptsalsa208sha256 for the KDF, and BLAKE2 for computing hashes otherwise. Thus, for what follows we have

sig_alg = Ed chk_alg = B2 kdf_alg = Sc

Finally, to minimise key collisions and provide a convenient necessary match criterion, each key is assigned a key_id which is eight random bytes.

#Secret Key Files

untrusted comment: <1024 bytes, arbitrarily changeable>
base64( <sig_alg> || <kdf_alg> || <chk_alg> || <kdf_salt> || <kdf_opsl> || <kdf_meml> || <encrypted key> )

where

  • kdf_salt = 32 random bytes
  • kdf_opsl and kdf_meml are the operations and memory limits for the KDF (defined in libsodium as crypto_pwhash_scryptsalsa208sha256_{OPS,MEM}LIMIT_SENSITIVE)
  • checksum = BLAKE2( <sig_alg> || <key id> || <secret key)
  • encrypted key = <kdf output> ^ (<key id> || <secret key> || <checksum>)

#Public Key Files

untrusted comment: <1024 bytes, arbitrarily changeable>
base64( <signature algorithm> || <key id> || <public key> )

#Signatures

Detached signatures have the format

untrusted comment: <1024 bytes, arbitrarily changeable>
base64( <signature algorithm> || <key id> || <signature> )
trusted comment: <1024 bytes, fixed at signing>
base64( <global signature> )

where

  • signature = ed25519( <file data> )
  • global signature = ed25519( <signature> || <trusted comment> )

whereas inline signatures are simply of the form

<file contents>
--- BEGIN SIGNATURE ---
base64( <signature algorithm> || <key id> || <signature> )

#Dependencies

libsodium, argp and a compiler/stdlib that will understand -D_GNU_SOURCE (for non-modifying basename)

I doubt it's that portable, but it should probably work on most unix-y systems.

#License

GPL3+

#Author's notes

The idea that you can squeeze public key verification into just a few bytes (sub ~100 for everything concerned) and have it still be "128 bit strong" is really amazing. Moreover, I felt that this would be a good learning exercise -- I haven't really done much library interfacing in C (this project entailed using both libsodium and argp), and I haven't ever concluded a mid-sized C project before. I have no doubt the code is crufty and poorly designed, but I had fun and it was an interesting paradigm shift from my usual language of choice.

All input welcome and desired!