Sparkle: Make copying private key easier

Created on 5 Aug 2019  路  5Comments  路  Source: sparkle-project/Sparkle

Right now AFAICT there is no easy way to copy the ed25519 private key from one machine to another!

(I'm assuming the recommended workflow where the key stored as a "generic password" in Keychain Access. As distinct from an "Internet password" or a "key", for instance.)

Maybe I'm missing something, as this seems like a major problem for many uses cases such as:

  1. More than one build machine
  2. Only one build machine, but desire to develop the Sparkle process off the build machine before deploying it to the build machine
  3. Only one build machine _at a time_ but got a new one

I.e. AFAICT neither the generic features provided by Apple's Keychain Access, nor specific features provided by Sparkle make such key copies easy.

(Perhaps the generic features to export & import an entire keychain could be used? But that would seem to import a lot of undesired data, unless somehow the import could be filtered down to a single "password".)

Not only are key copies not easy, in fact I haven't really yet found a feasible way in which such a copy is even _possible_!

For example, attempting to manually create a copy of the key ("password") on another machine using Keychain Access seems to fail, perhaps because I can't set kSecAttrProtocol to kSecAttrProtocolSSH using the Keychain Access GUI.

Perhaps generate_keys could be extended to optionally accept a private key on the command line, allowing it to generate a copy instead of a new, unique key? Perhaps in that case it should require the public key, too, so it can generate the proper/expected comment in the "password" entry.

Or perhaps somehow /usr/bin/security can be used to generate a copy including the proper kSecAttrProtocol attribute?

Most helpful comment

perhaps somehow /usr/bin/security can be used to generate a copy

Indeed the following command can be used to generate a keychain entry that closely matches what generate_keys makes.

security add-generic-password \
    -a ed25519 \
    -s https://sparkle-project.org \
    -T /abs/path/to/Sparkle/bin/generate_appcast \
    -w

e.g.

security add-generic-password \
    -a ed25519 \
    -s https://sparkle-project.org \
    -T /Applications/Sparkle-1.21.3/bin/generate_appcast \
    -w

(This command will prompt you for the "password" (private key) and will prompt you to confirm it.)

(I didn't bother to make the command match what generate_keys makes exactly, but it matches it closely enough for the purposes of generate_appcast.)

So, though it might be nice to have generate_keys optionally be able to do this for you, I'd say the major missing "feature" at this point is just _documenting_ how to do this using the generic features of security (since the generic features of Keychain Access seem insufficient).

All 5 comments

I hoped the standard keychain functionality would be enough, but apparently not.

Ability to import a key from command-line sounds like a good idea. Could you make a PR for it?

attempting to manually create a copy of the key [...] seems to fail, perhaps because I can't set kSecAttrProtocol to kSecAttrProtocolSSH

This speculation of mine was wrong.

It is true, I couldn't set kSecAttrProtocol. But kSecAttrProtocol is meaningless/ignored on generic passwords like the one Sparkle uses to store the ed25519 private key. See #1448.

attempting to manually create a copy of the key [...] using Keychain Access seems to fail

The reason this failed is Keychain Access, AFAICT, cannot create _generic_ passwords, only _Internet_ paswords.

perhaps somehow /usr/bin/security can be used to generate a copy

Indeed the following command can be used to generate a keychain entry that closely matches what generate_keys makes.

security add-generic-password \
    -a ed25519 \
    -s https://sparkle-project.org \
    -T /abs/path/to/Sparkle/bin/generate_appcast \
    -w

e.g.

security add-generic-password \
    -a ed25519 \
    -s https://sparkle-project.org \
    -T /Applications/Sparkle-1.21.3/bin/generate_appcast \
    -w

(This command will prompt you for the "password" (private key) and will prompt you to confirm it.)

(I didn't bother to make the command match what generate_keys makes exactly, but it matches it closely enough for the purposes of generate_appcast.)

So, though it might be nice to have generate_keys optionally be able to do this for you, I'd say the major missing "feature" at this point is just _documenting_ how to do this using the generic features of security (since the generic features of Keychain Access seem insufficient).

@bdenckla-ua thanks for your example. It works :)
The only problem is that it can't work on a CI because sign_update will show a Keychain password prompt. But still, good progress. Thanks again.

Was this page helpful?
0 / 5 - 0 ratings