Keys/Signature use in OSTree/Flatpak/Flathub

Tobias Mueller muelli at cryptobitch.de
Wed Oct 5 09:37:01 UTC 2016


Hi.

I've been asked to review this proposal and I'm having a few basic questions 
regarding the proposed design. Please excuse my ignorance for not knowing 
intrinsics of neither OSTree nor TUF.

On Fri, Sep 30, 2016 at 03:36:35PM +0200, Alexander Larsson wrote:
>  * OSTree doesn't have any protection against "freeze attacks". I.e
>    a MITM can cause a client to not get updates forever without this
>    being detectable.
Is this attack something worth defending against?
Or rather throwing PKI at it..?
I guess a client notices that it receives no updates simply by receiving no updates.
If a client really expects an update, it can notice that there haven't been updates for,
say, more than a month.

Introducing (expiry) dates opens up a set of problems that might not be worth dealing with.
For example, you need to find ways to deal with actual expiries or future "creation" dates.
I mean, a version presumingly doesn't get "invalid" or "untrusted" because it's too old (or too young).
It's probably still good for consumption.
The clients need to have good enough clocks, which, admittedly, should be a given. But you might still have devices whichs CMOS battery is drained and users being too impatient to wait for an NTP sync.
Anyway, it increases complexity by a non-trivial degree which might not be worth for the problem at hand.
If it's simply about detecting the stale-ness of information, including a "creation time" might be sufficient.


> Secondly we add more keys and roles. These are described in a single
> signed "root" file assigning to each role the keys that are allowed
> for it.
So the "root" file is a file kept in OSTree?
Is the app author supposed to create and sign that root file?
And is the user supposed to somehow get the key when attempting to install an app?
And does the user get this file when they first install an app?
When I check for updates, do I again download that root file?
Can the key to sign the root file with ever be changed?
How do I make sure I'm not getting an attackers root file?


> One of the roles is the "root" role, and its keys are used to
> (self-)sign this file. Note that each role can define multiple (N) keys
> and specify how many (M <= N) of them needs to sign a file for it to
> be valid. The root keys need to be highly secure and should always be
> offline and well protected.
Tough requirement for the casual app developer, but in practice a hardware token might work well.  I think by now the PKCS11 integration is good enough.

> Then we add a single entry-point to the most current state of the
> repository. Lets call it "timestamp" as it is the equivalent of
> timestamp.json in TUF. This is a very small file that is atomically
> replaced on the server side whenever something changes. It is the only
> file in the repo that is accessed via a static filename.
Ah, so the "root" file is not accessed through a static filename..?

> The keys used for the timestamp role has to be kept unencrypted on the
> server infra since this file is signed often, but if exposed it will
> only cause the ability to delay updates, not arbitrary code signing,
hm. But does the "summary" not contain references to code to be executed?
I assume that the reference code is signed again.  What do you gain by signing it with two different keys?

> The summary file is an in-file signed version of the current summary
> file.  Its signed by key(s) assigned to the "summary" role. Also, it
> contains a reference (by sha256) to the root file.
So the chain goes like this:  root -> timestamp -> summary -> root ?
It seems unusual to go in such a circle.
What attack is thwarted by referecing back from the summary to the root?

> Also, the summary file has an expiration date, which should be longer
> than the timestamp file but still limited. Should be approximately the
> regular time between summary file changes due to updates.
> 
Again, I'm not clear what the rationale is.  What's the semantic of an "expired" app?

> If the referenced root file is different from whats currently in use,
> update it and start over. This is how we add and revoke keys.
This seems like a scary operation.  I assume the signature on the new root
file still has to come from an authenticated key?  Can the signing-key be
different?  What's the mechanism to roll over keys if the root key gets lost
(instead of compromised)?
Having no mechanism is fine, but it'd better be communicated ;-)

> Interestingly, you you can go "unverified timestamp -> unverified
> summary -> root file" to get an initial version of the root keys, which
> you can then pin for later use. This is a nice way to bootstrap trust
> in a repo via SSL.
In the TUF spec <https://github.com/theupdateframework/tuf/blob/5d2c8fdc7658a9f7648c38b0c79c0aa09d234fe2/docs/tuf-spec.txt#L258>
the wording is

   The client-side of the framework must ship with trusted root keys for each
   configured repository.

Having this root of trust is a significant advantage in building a PKI,
because it reduces complexity.
The proposed method here seems to be different in that this intial trust
has to be bootstrapped not via hardcoded keys but via downloads.

> and if multiple keys are required for
> these roles we can migrate to new ones if a subset are exposed.
That sounds clever. Similarly, HPKP requires you to have a "backup key pair"
in case something bad™ happens to your key in production.
https://tools.ietf.org/html/rfc7469#section-4.3
Note that HPKP also has its share of critics who fear that your
pinning can be taken as hostage if the attacker ever gains control over
your keys.

Building a PKI and mandating clients how to define "trust" is a bit
of a minefield and you will never please everyone.  In fact, if you ever
build a working PKI, I'd nominate you for the nobel prize or, depending on
your preference, buy you a crate of beer.

Cheers,
  Tobi



More information about the xdg-app mailing list