Sparkle: Migrating from DSA to EdDSA

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

I'm trying to stop using DSA keys in favor of EdDSA. I'd like to minimize the amount of time that DSA keys are trusted. I have plenty of users in the field with old builds (using Sparkle 1.7.0).

It seems I cannot change the DSA key. If I change it, updates fail saying "DSA signature validation failed. The update has a public DSA key and is signed with a DSA key, but the new public key shipped with the update doesn't match the signature. The update will be rejected."

I cannot remove the DSA key. Doing so causes the update to fail with "A public DSA key is found in the old bundle but no public DSA key is found in the new update. For security reasons, the update will be rejected."

From this I conclude the migration path is to support both keys for time (perhaps as little as one version). I will need to keep the one of these releases in the appcast indefinitely.

Then I need to provide a way for users running this release with both keys to upgrade to the EdDSA-only version without letting users on the DSA-only releases know about it (lest they try to upgrade and get one of the aformentioned errors). I guess this means I need to use a different URL for appcasts for my Sparkle 1.21 users.

Is this correct?

Most helpful comment

Makes sense. I'm sure this code is nerve-wracking to write. It would be helpful to publish a recommendation for migrating to EdDSA. It seems there are a lot of ways to do it incorrectly, and I kind of stumbled into the solution I found.

I'm really grateful that you added EdDSA because I don't think continuing to use DSA is a good choice. Thank you for that!

All 5 comments

Ok, I tried to do that and it failed saying:

OK: EdDSA signature is correct
This app has a DSA public key, so a DSA signature is required too
There is no DSA signature in the update

This implies my new appcasts must have a DSA signature. From reading the code, it looks like an app with both DSA and EdDSA public keys can upgrade to one with only an EdDSA public key.

So I actually need to have three appcasts?

Legacy releases currently in the field with only DSA public keys have an appcast URL of legacy.xml, which has only DSA signatures. They will provide an app update to a "transitional" release.

A transitional release will both DSA and EdDSA public keys and will have an appcast URL of transitional.xml, which has both DSA and EdDSA signatures and points at a modern release.

A modern release will have only an EdDSA public key and will have an appcast URL of modern.xml, which has only EdDSA signatures and points at another modern release.

I haven't put out much thought into migration path off it yet, so Sparkle is cautious and conservative about the new keys.

In a few places we have non-trivial logic about which key is needed in what circumstances, and I didn't want to accidentally break it.

I think the best solution would be to change Sparkle itself to start ignoring old DSA completely.

I've tested using the plan I suggested and it works, but it is a pain. If you relax the requirement that an app with a DSA public key requires a DSA signature then it could get you down to two appcasts. I don't know the reasoning behind that decision, though. Is that to protect developers from their own mistakes or is there a specific vulnerability you were worried about?

There's no vulnerability per se. I've just been (too) careful not to create a logic bug.

For example, adding EdDSA signature and EdDSA key to the new app shouldn't be enough to pass EdDSA signature verification, because both signature and the key are new and therefore untrusted in this scenario. The app needs to check new signature against the old key to ensure the chain of trust is unbroken.

Technically there's no problem at all doing that. It's just that adding EdDSA already required many changes in the signature verification code, and supporting all of the combinations separately, securely and with helpful error handling, adds a ton of new code paths: {no DSA, old DSA, old EdDSA, old DSA + EdDSA} * {new DSA, new EdDSA, new DSA + EdDSA} * {app code signing, unsigned bundle, package}.

I'm sure that changing code which required "the key is valid" to "all keys are valid" is 100% secure. Changing code to "any of the keys is valid" requires security review to ensure it's not a logic bug. When I have time I'll review it and relax requirements where its safe.

Makes sense. I'm sure this code is nerve-wracking to write. It would be helpful to publish a recommendation for migrating to EdDSA. It seems there are a lot of ways to do it incorrectly, and I kind of stumbled into the solution I found.

I'm really grateful that you added EdDSA because I don't think continuing to use DSA is a good choice. Thank you for that!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ianbytchek picture ianbytchek  路  5Comments

k06a picture k06a  路  18Comments

teologov picture teologov  路  9Comments

mz2 picture mz2  路  13Comments

bdenckla-ua picture bdenckla-ua  路  5Comments