MlFront_Signify.Signify
Use this module to have your software update itself or its datasets securely.
Please read the short introduction written by Ted Unangst for OpenBSD: signify: Securing OpenBSD From Us To You
You will need to:
generate_key_pair_exn
, or on Unix download "signify"
with your package manager and run "signify -G -p newkey.pub -s newkey.sec"
. This will be for the current release (ex. "2.3.0"
) and any patches or errata (ex. "2.3.1"
, "2.3.2"
, etc.) for the release. Safeguard the private (secret) key. It is only to be used for signing your artifacts, and should never be stored on your filesystem. Recommendation: Use the list at OWASP's Key Storage to find a good spot to store your private key."2.4.0"
or the major version bump "3.0.0"
) even though you likely haven't started that release yet! Safeguard the private key."https://example.com/a/b/c/my-artifact-2.3.5.zip"
. Checksum your artifact(s) with a secure hash alongside your artifact. For example, the secure hash could be saved hex or base64 encoded into the location "https://example.com/a/b/c/my-artifact-2.3.5.zip.sha256sum"
, or for multiple artifacts you can have the output of "sha256sum"
be placed into "https://example.com/a/b/c/SHA256"
. Recommendation: Even though SHA-256 is a good secure hash, if you don't know better, pick Blake3 as your hash since it scales well when you need multi-threaded downloads.sign_message_exn
with the secret key ~message
as the contents of the current release checksum file, and the ~seckey
as the the current release secret key. Save the signature alongside your checksum file. For example, "https://example.com/a/b/c/my-artifact-2.3.5.zip.sha256sum.sig"
or "https://example.com/a/b/c/SHA256.sig"
.When you are ready to do the next release:
Your software will need to periodically probe for the "next release" download URL using the steps:
"https://example.com/a/b/c/my-artifact-2.4.0.zip.sha256sum.sig"
). If that can't be downloaded, there are no updates and you should stop the probe."https://example.com/a/b/c/my-artifact-2.4.0.zip.sha256sum"
). If that can't be downloaded, there are no updates and you should stop the probe.verify_message
with the ~signature_
from the first step (C1), the ~message
from the second step (C2), and ~pubkey
has been embedded in your source code in the Release Process third step (A3).~message
) to download and verify the next release artifact URL (ex. "https://example.com/a/b/c/my-artifact-2.4.0.zip"
). If that can't be downloaded or the checksum does not match, there are no updates and you should stop the probe.Q1: How do I download verified errata/patches?
A1: In your source code not only should you embed the next release public key and next release URL (ex. "https://example.com/a/b/c/my-artifact-2.4.0.zip.sha256sum.sig"
), you should also embed the next patch URL (ex. "https://example.com/a/b/c/my-artifact-2.3.6.zip.sha256sum.sig"
).
That way when you do the "Probing in your software" steps, you can check for the next patch URL first. The only difference between a next patch URL and the next patch URL is that a patch URL uses the current release public key, not the next release public key.
fingerprint_pubkey_exn pubkey
returns the fingerprint of the base64-encoded public key pubkey
.
The public key pubkey
must not have a preceding line of comment.
Raises Invalid_argument
if the public key could not be decoded.
fingerprint_signature_exn signature_
returns the fingerprint of the base64-encoded signature signature_
.
The signature signature_
must not have a preceding line of comment.
Raises Invalid_argument
if the signature could not be decoded.
sign_message_exn ~seckey ~message ()
signs the message
with the signify-formatted secret key seckey
.
The signify format of the secret key seckey
is:
Raises Invalid_argument
if the secret key is not a signify secret key.
Raises Invalid_argument
if the secret key has its algorithm field (first two characters) anything other than "Ed"
.
val generate_key_pair_exn :
?comment:string ->
(int -> string) ->
[ `PublicKey of string ] * [ `SecretKey of string ]
generate_key_pair_exn ?comment gen
creates a key pair from the random byte generator gen
with an optional comment comment
.
The function gen sz
must take an integer size sz
and return a string of random bytes of sz
length..
The typical way to create a generator gen
and one or more key pairs is with:
Mirage_crypto_rng_unix.use_default ();
let rng = Mirage_crypto_rng.default_generator () in
let gen sz = Mirage_crypto_rng.generate ~g:rng sz in
let `PublicKey pubkey, `SecretKey seckey =
MlFront_Signify.Signify.generate_key_pair gen
in
()
Raises Invalid_argument
if the random byte generator gen sz
does not give a random byte of length sz
.
val verify_message :
pubkey:string ->
signature_:string ->
message:string ->
unit ->
(unit, [ `Msg of string ]) Stdlib.result
verify_message ~pubkey ~signature_ ~message ()
verifies the message
with the signify-formatted signature signature_
and the signify-formatted public key pubkey
.
The signify format of the public key pubkey
is:
The signify format of the signature signature_
is:
On success this returns Ok ()
.
Returns Error (`Msg "the error message")
if the message cannot be verified.