Gentoo Archives: gentoo-dev

From: "Robin H. Johnson" <robbat2@g.o>
To: Gentoo Developers <gentoo-dev@l.g.o>
Subject: [gentoo-dev] Redux: 2004.1 will not include a secure portage.
Date: Thu, 25 Mar 2004 01:57:20
In Reply to: [gentoo-dev] 2004.1 will not include a secure portage. by Kurt Lieber
OK, after reading this entire thread, I've been thinking about a usable
implementation from both the administrative and developer perspective.
One of the most important things to remember in designing this, is that while
you can prevent damage from most individual attacks, no system in existence can
withstand a multi-faceted all-out assault.

- protect against compromised developer box / rogue developer
- protect against compromised rsync server

Required operations:
1. add a key to trusted list
2. remove a key from trusted list
3. verify that a package has not been tampered with
4. sign a package

General idea:
we have a list (single file) distributed via rsync with all of keyids known
good for signing manifests. this file is must also signed, with at least one
(two or three required for more security) master key that has it's public part
widely published and it's private part kept secure. the verifiable signatures
on the trust list make it trusted. The signature for the list should be
available individually so that it can be checked frequently by portage for
changes (and if it has changed, download the list again). Some other users have
suggested using expiry times in various ways but that ignores the fact that a
portage tree snapshot taken in a known good state remains in that known good
state until altered.

Signing a package:
manifests are signed as clear-text INSIDE the Manifest file (my prototype
already did this). this is important not to bloat the tree with more files.
This also allows multiple signatures on a Manifest (basically it just nests).
add a command to repoman, 'repoman sign' that signs a manifest and have repoman
commit check that a valid signature is present before committing (and
automatically does the sign stage on commit if required).

to add a key to the trusted list:
1. add keyid into list
2. resign modified list with all required master keys

to remove a key from the trusted list:
1. remove keyid from list
2. resign modified list with all required master keys

to verified that a package has not been tampered with:
1. read in manifest file, check that the signature(s) are valid.
2. grab the keyid(s) that it was signed with, and compare them against the
trusted list (and optionally a LOCAL list for users to have their own trusted
key structure)

users can specify how many signatures a package needs to have for them to trust
it, eg a really paranoid user may require each manifest has at least 3

problem case examples:
case 1: an rsync server is compromised
if intruder modifies an ebuild/patch it doesn't pass the manifest check
anymore, and if they modify the manifest, they need a key to sign it which
won't be in the trusted list. if they modify the list it won't pass the
external signature checks anymore. this case is made mostly airtight for the
users that enable security checks.

case 2: a developers box is compromised 
this is a weakness in all of schemes floating around already. on discovery, the
keyid is removed from the trust list and an advisory issued. users requiring at
least N signatures on a package are protected unless the intruder hacks N
developer boxes. Assuming that developers keep their gpg keys with a pass-phrase
as they should (just like their ssh keys), there is minimal danger until
ssh/gpg are trojaned to capture the unencrypted key/pass-phrase.

case 3: rogue developer
this is one of the hardest things to catch in any system. just like in case 2,
users requiring at least N signatures are safe until N developers are

possible problems with this approach:
for users that specify more than 1 signature must be on a manifest, it's very
hard to keep manifests in this state if the package changes often, since any
package change requires redoing the manifest which removes the old signatures.
this could be fixed by making manifest building incremental (eg it is NOT
regenerated from scratch but instead appended until an old set of signed data
no longer applies to any files [as they have all been changed]), but that would
require a re-write of the manifest generation code.

Plan for incremental implementation:
1. roll out portage with a cleaned up version of my prototype for repoman and
   simple verification code for manifests ONLY.
2. create the trusted list and roll out a portage with support for it.

Robin Hugh Johnson
E-Mail     : robbat2@××××××××××××××.net
Home Page  :
ICQ#       : 30269588 or 41961639
GnuPG FP   : 11AC BA4F 4778 E3F6 E4ED  F38E B27B 944E 3488 4E85