Keys/Signature use in OSTree/Flatpak/Flathub

Alexander Larsson alexl at redhat.com
Wed Oct 5 13:39:57 UTC 2016


On Wed, 2016-10-05 at 11:37 +0200, Tobias Mueller wrote:
> 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.

If there is a known security issue (think heartbleed) and everyone
needs to update their apps to not be vulnerable, then an undetected
MITM would make you think you're safe due to automatic updates. Sure,
if you're very careful and manually follow updates then you *might*
notice this. However, the goal is to turn on automatic updates and then
not have to worry (i.e. get told when something fishy is going on).

> 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.

Yeah, this is clearly a problem. In TUF only "head" of anything is ever
valid, and it has to be continually re-signed. How does that combine
with wanting to run an older version of an app?

OTOH, at what point does a GPG key lose enough trust due to risk of
exposure increasing with time, and due to the pki technology going
forward (key size increases, etc). Is using the same key for 10 years
safe? If not, what is the future-proofing plan.

Maybe the expiration date could be related to not the computer clock,
but the timestamp in the app build. That, combined with not allowing
backwards timestamps could allow key replacement over time.

> > 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?

The current OSTree model depends on a pre-setup of the public GPG key
for the repo, which is installed out-of-bands (probably got it via
https). In the TUF-like model the entire root file would be locally
available as part of bootstrapping a remote. 

It is self-signed, and the update contains a check for a new version,
which is then updated to if its properly signed.

> > 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.

I'm not saying everyone and his cat needs to have a fully secured root
key for their hobby flatpak repo. However, if the Flathub app store is
a major distributor of most upstream linux desktop application
releases, then the root gpg key for it would be very valueable. It has
to be *possible* to run such a setup in a secure fashion.

> > 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..?

No, to protect against races which causes inconsistent sets of metadata
only *one* file has a static names (the timestamp), everything else is
addressed by content.

> > 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 contains the mapping from the branch name
(app/org.spotify.Spotify/x86_64/stable) to the commit (a sha25 id).
Whenever any branch in the repo changes (new app, some app updated,
etc) the summary file needs to be re-signed. If you have this key you
can point the branch names on whatever commit you need, yes. However,
the commits are also signed, and in the TUF model with a separate key.
The advantage in this model is that the commit can be signed on a very
secure system when the app is built, and then it can at a later point
be added to the repo and have the summary re-built and re-signed. The
summary key may have to be stored on or close to the system with the
repo, but the build keys never ever have to be near it.

> > 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?

It's more like

root1 -> timestamp -> summary -> root2

I.e. given a local copy of an old, trusted root we can get to a new
one, which may have e.g. a new commit gpg key. I.e. this is how
revocation and similar operations happen.

> > 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 ;-)

There is no such mechanism (other than out-of-band), but that is no
different from the current use of a single GPG key for everything in
ostree.

> > 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/5d2c8
> fdc7658a9f7648c38b0c79c0aa09d234fe2/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.

No, this is just an optional model. The core idea is that the root keys
are pre-assigned to the remote just like we currently do with ostree.
However, in practice such trust has to be bootstrapped *somehow*, and
all the current models are "store the gpg key on some https server".
The above use just notes that this could be done no less secure via the
repo itself, if it is on https.

> 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.

I think this is expressing a similar opinion to Colin, which I take as
a hint that the practicality of something as complex as this in very
low. I guess I'll drop this then.



More information about the xdg-app mailing list