sparkle-project / Sparkle

A software update framework for macOS
https://sparkle-project.org
Other
7.34k stars 1.04k forks source link

Store private seed as the secret for newly generated keys #2472

Closed zorgiepoo closed 9 months ago

zorgiepoo commented 9 months ago

Today the private/public keypair that orlp/ed25519 generates and that we store in the Keychain is "incompatible" with other cryptography libraries/tools. In particular the private key this library generates (which includes a variation of the hashed seed) cannot be used with other libraries for signing (without modification).

For newly generated keys, this change instead stores the base64-encoded seed as the private key we store in Keychain and we use for exporting/importing keys. We still keep compatibility with older generated keys whose format more resembles a base64-encoding of hash(seed) + public_key.

Base64 encoding/decoding was kept around to allowing copying the secret from Keychain Access. I also did not want to use a different format when exporting/importing keys for consistency.

The private seed was picked because it's the minimal/defacto info needed to be able to construct the private/public keypair using any library or tool even if they may prefer a different internal representation. For instance, orlp/ed25519 internally prefers hash(seed) + public_key, CryptoKit prefers seed, golang & libsodium prefer seed + public_key, openssl prefers an OID + seed for DER files, etc. This representation we now store does not give any preference to any particular tool or internal representation. I am also not worried about performance of not using a precomputed public key or hashed seed.

As part of this change, I am also disabling command line flags that allow passing the private key as a command line argument. This option was already deprecated and should not be supported for new keys.

Fixes #2470

An example for exporting to DER file (assuming we have a newly generated key):

generate_keys -x exported_key
cat exported_key | base64 --decode > exported_key_binary
echo -n -e '\x30\x2e\x02\x01\x00\x30\x05\x06\x03\x2b\x65\x70\x04\x22\x04\x20' > oid_header
cat oid_header exported_key_binary > exported_key.der

For other libraries/tools you just need to pass exported_key_binary as the seed to construct the key-pair.

Importing from a DER file is easier:

tail -c 32 key.der | base64 > key
generate_keys -f key

Past related discussions: https://github.com/sparkle-project/Sparkle/discussions/2467 https://github.com/sparkle-project/Sparkle/discussions/2160 https://github.com/sparkle-project/Sparkle/discussions/2298

Misc Checklist

Testing

I tested and verified my change by using one or multiple of these methods:

Things to test:

macOS version tested: 14.1.1 (23B81)

zorgiepoo commented 9 months ago

cc @jozefizso