Subject: Re: adding gpg to src/gnu/dist
To: Simon J. Gerraty <sjg@crufty.net>
From: Daniel Carosone <dan@geek.com.au>
List: tech-userlevel
Date: 05/14/2004 10:03:39
--bn6XL8m8Y51x7rzV
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Firstly, thanks Simon for the more concrete examples and discussions.

On Thu, May 13, 2004 at 11:46:44AM -0700, Simon J. Gerraty wrote:
> As Thor has mentioned, what is required at the end of the day is for
> the software installation process to be able to verify the
> authenticity and integrity of the software to be loaded.

Looking further ahead, I have longer-term objectives relating to
execution-time validation of per-file signatures, as Windows can do.
The q&d way to do this now is by preloading hashes into veriexec from
a signed document using userland tools, and perhaps it will stay that
way.

In the meantime, I'm more than happy to talk first about signing
"installation containers" of various kinds.

> We're using a certificate based trust model - which is quite
> appropriate to this case, since its the vendor's (eg NetBSD) code
> wanting to confirm that the software to be loaded came from the
> vendor.=20

Yes, although we'll at least potentially want some slightly
finer-grained distinctions within that - releases, pkgs, perhaps
patches and security updates.  This helps avoid problems with key
disclosure if everything must be signed with the same key.

> In OpenSSL a certificate is trusted if it can be located in a "trust
> store" (default is something like /etc/certs or /etc/ssl/certs).
> The basic purpose of a certificate is to bind a key to an identity,
> and they can also limit the use of that key.  GPG has similar
> functionality of course.
>=20
> If a normal package is just a tar file (.tgz), you can wrap it into a
> "signed" package containing.
>=20
> package.tgz		the real package
> package.tgz.sha1	SHA1 digest
> package.tgz.sig		signed form of package.tgz.sha1
> certs.pem		the certificate chain needed to verify
> 			that signature.
>=20
> The certs.pem should contain at minimum the certificate for the key
> used to generate the .sig
>=20
> You can get fancy with the content of .sig but at minimum=20
> the .sig can be produced by just:
>=20
> openssl sha1 -sign <keyfile> <thing> | openssl base64 > <thing>.sig
>=20
> the base64 is optional but a good idea, in the above <keyfile> is a
> PEM encoded private key, for which <cert> holds the public key and the
> identity it is bound to etc.
>=20
> Verification of the signature is a little messier (because sha1 is
> lame about extracting a pubkey from a cert):
=20
In my work, I have used the "openssl smime *" commands, rather than
working with the keys and formats quite so directly.  There are
several other reasons for this, but the major one is that it handles
all of the container cert chain and encoding issues you discuss for
you.  It's been appropriate for my needs so far, but might be less
directly applicable for this discussion (more below).

I consider this set of openssl(1) commands and functions, fwiw, to be
closest in conceptual similarity to the gpg usage.  In fact, they're
almost identical in form and function, once you've done the necessary
external setup steps to establish your trust paths.

see openssl_smime(1)

> That may sound like a lot of mucking about - especially compared to=20
> the peer to peer model of GPG or SSH, but it has advantages in terms of
> scalability (which are perhaps not particularly important here).

I have mumbled a number of times about volunteering to run a
NetBSD.org CA.  I would be happy to do so if it helped encourage these
efforts and allowed other folks to concentrate on using the certs
rather than getting overly-wrought in these issues.

> If the trust store (eg /etc/certs/) contains CruftyCA.pem  actually it
> needs 21b00b1d.0@ -> CruftyCA.pem since it is the hash of the Issuer
> name that is used for lookups, then any certificate issued by
> CruftyCA will verify successfully.

That's something that we'd need to include in the appropriate
distribution of the release that would start relying on these
signatures.

As for packaging formats and signatures, there are a number of options
and partially conflicting suggestions.  My #1 requirement in the "just
in case we don't get it right" category is that, whatever format we
choose, supports multiple independent signatures.  From a policy point
of view, then, people (with our help, of course) can then choose to
trust different sets of sigs, or to accumulate trust based on multiple
sigs - potentially saving us from the all-or-nothing failures that
cert schemes can suffer from.

For the case of key management, it's the biggest downfall of the x.509
cert format, compared to pgp.  GPG allows that inherently, which is a
good thing, and something we wouldn't want to "lose" otherwise -
though it does complexify the key trust decisions.=20

For the case of container files, we can of course always use a number
of separate detached .sig files, under any format.  That might be an
easy place to start.

If we want to build sigs into the binary package stream format, or for
that matter the ELF executable format, just please remember to allow
room for more than one sig.

As far as implementing this with C and the openssl library interface,
sorry - I'll be of no help to anyone.  For all such programming work,
I turn to Java, JCE, and bcprov for the crypto, and XML-DSIG for the
container formats.

Which leaves the implementation of policy choices and implementation,
which is always the harder part than getting the basic file formats
and crypto routines going.  That's where most systems fall down or
have weaknesses, and where careful design effort is warranted, which
is why I'd also like to deemphasise discussions of particular
technologies before the objectives are clear.

--
Dan.
--bn6XL8m8Y51x7rzV
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (NetBSD)

iD8DBQFApAzbEAVxvV4N66cRAihpAKCmJUqAiCFUu/rMfXnGLJZmUj7RNwCeLbua
iceC8JKZ+4ZLsKDTA2lA1gI=
=Hp+L
-----END PGP SIGNATURE-----

--bn6XL8m8Y51x7rzV--