cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: those SSL certificates

From: Cris Bailiff <c.bailiff+curl_at_awayweb.com>
Date: Wed, 28 Aug 2002 12:41:52 +1000

> > Did you plan to add a ca-bundle file into the curl distribution? I know
> > it's a bit large (although it zips well), and it re-enforces the "global
> > CA monopoly"
>
> I've thought about it, but I haven't really made up my mind yet. I greatly
> appreciate your input on this.

You're welcome. I'm sure you'll do the 'right thing' after careful
consideration.

 ....

> These are certainly good points arguing *for* the inclusion of a CA bundle.
>
> The cons then? What are the drawbacks (disk and package space not taken
> into account)?
>
> Can we get our hands on a good certificate package and include it? I mean
> copyright wise? I've noticed that for example the modssl package has a huge
> bundle included. Would we be allowed to ship that or would we need to dig
> up another version somehow/somewhere?

I don't think there's any real licence issue here. modssl is liberally
licenced (apache style), but the ca-bundle itself was originally extracted
from the ca list provided with some copy of Netscape Navigator 4, which was
'free' and then 'open source' (NSPR). (Maybe the modssl file has been updated
since then). I don't recall anyone from Netscape/mozilla ever complaining
about IPR to the modssl people.

Mozilla has a newer CA list embedded within it (in the nss stuff), which can
be 'exported' or accessed directly in the source:

http://lxr.mozilla.org/seamonkey/source/security/nss/lib/ckfw/builtins/certdata.c

This file is an embeddable (C source) form generated (using certdata.perl)
from the 'raw' certificate data in:

http://lxr.mozilla.org/seamonkey/source/security/nss/lib/ckfw/builtins/certdata.txt

I guess this file is clearly MPL/GPL licenced, and you would need to consider
compatability with libcurls licence collection, but it's been generated from
other data by someone at some stage as well.

The information itself, though, is arguably in the 'public domain' - it is a
list of 'public keys', wilfully and vigourously distributed by the CA's who
made them. The CA's have paid large amounts of money to MS (and presumably
Netscape in the past) to be included in the 'blessed' list - they would no
doubt be pleased by free wide distribution, in which case, if objectionable
copyright exists only in the 'collection', rather than the certificate
information (which is usual with directories and dictionaries of public
information), another option would be for someone to download (and verify)
each CA cert in turn from each known public CA.

As a sample data-point, Thawte have the following IPR notice in their CPS
(Certification Practice Statement - every CA is supposed to have one):

"2.9.1 Property Rights in Certificates and Revocation Information CAs retain
all Intellectual Property Rights in and to the Certificates and revocation
information that they issue. Thawte and Customers grant permission to
reproduce and distribute Certificates on a nonexclusive royalty-free basis,
provided that they are reproduced in full and that use of Certificates is
subject to the Relying Party Agreement."

(They are more strict with CRL lists - they are more 'valuable' if they are
controlled, whereas root certs become more 'valuable' the wider they are
known.)

Other free applications have just directly used ca-bundle from modssl - I
have:

/usr/share/apps/kssl/caroot/ca-bundle.crt

which I guess is used by konqueror and kmail at least. I've heard no issues
there.

> It'll add an annoying installation procedure that'll cause us grief. Of
> course, we'll have some lib/ca-bundle.h file that gets generated properly
> with the to-become installed path for the CA cert bundle so that the
> library finds it smoothly. The curl-config tool should also know about the
> path if the CA cert bundle is installed.

Certainly portably installing and re-finding the bundle might be a bit
tedious, but other software manages it OK (see above). I guess a configure
option for the user to specify wouldn't hurt either (they might choose a cert
store they already have, like /usr/local/ssl). (An option to choose the
default store to be a cafile or capath might also be nice :-) )

...

> > * You could even have the library itself install the default CACERT file,
> > which would reduce the impact on existing library-using code. This would
> > remove any forced code changes for existing library using clients.
>
> Right, if we use this approach many users wouldn't even notice the upgrade
> to CA cert using connections from the previous insecure ones. At least
> those that are connecting to sites using "real" certificates.

Yes - if you set the default CA in the library, then the most users would
have the least impact (if you see what I mean).

> > Certainly a verbose error message is important - like the numerous popups
> > in a good browser - users should find it more convenient to use the
> > security, rather than to ignore it. The error could just be displayed,
> > though, when SSL verification fails with the included certs.
>
> There's no reason to even attempt an SSL connect if an insecure connect
> isn't allowed and we don't have any certificates. It would be a waste of
> time.

Well, you don't really need to put an extra check in there for this - if the
certificate store is empty, then openssl will fail the ssl handshake, if
thats what the flags say. It's likely to be the exception rather than the
rule, so I wouldn't optimise for it.

Putting an extra "if (protocol=https and CAfile==NULL or VERIFYHOST=0 or
VERIFY_PEER=0)" in there, with another check for -k, doesn't seem really
necessary, and might cause future hassles due to being a bit non-orthogonal.

I can imagine a situation, for example, where a particular version or
configuration of openssl has some other means of pre-loading the certificate
store (such as being configured to use some external LDAP server to find
certs). Although a libcurl might not supply a certificate, the connection
could still be verified, Let openssl sort it out, I say.

> > If you think it ugly that curl would need to reference a movable external
> > file, you can actually embedd default certs in the code, though this
> > makes changing certs prety inflexible. I have code for this somewhere if
> > it's of interest.
>
> I don't see that as much problem, as any libcurl-using program could always
> just set CAPATH or CAFILE to point to the CA cert of their choice. In fact,
> they should do that and not blindly trust whatever we would go ahead and
> install for them.

OK - this means a library API change (to call setting a CA bundle). Perhaps
the choice to setup using the default curl CA bundle could be another flag to
curl_global_init. (It does seem lonely with only 2 at the moment).

If you want to embedd the bundle, rather than using an external file, you can
turn the source ca-bundle into a big C struct, and have it as part of the
library (or command line) source - you can do this like this:

Split the bundle into separate certs, cert1-cerftN somehow, then:

for i in *.crt
do
openssl x509 -in cert$i.crt -C -noout|perl -pe "s/XXX/cert$i" >> ca-certs.h
done

You can do this at 'make dist' time if necessary, if you don't want to rely
on openssl command line and perl during ./configure & make. You need some
code to get this into the openssl certificate store - here's mine, but it
only does one cert - you'll need to mangle the perl rewrite of XXX above -
(becomes obvious what needs fixing if you try this - YMMV):

    X509 *cert =NULL;
    X509_STORE *store = NULL;
    unsigned char *cert_data;

    if(!(store = X509_STORE_new()))
            abort("Can't make X509 store");
    
    cert_data=&XXX_certificate[0];
    cert=d2i_X509(NULL,&cert_data,sizeof(XXX_certificate));
    X509_STORE_add_cert(store,cert);
    X509_free(cert);
    
    /* repeat ad-nauseum
    cert_data=&XXX2_certificate[0];
    cert=d2i_X509(NULL,&cert_data,sizeof(XXX2_certificate));
    X509_STORE_add_cert(store,cert);
    X509_free(cert);
    */

* One final issue worth considering: If you set up a default store, make sure
it's initialised during the first request, rather than when setting up the
curl handle. If a user specifies a different cafile, openssl will load and
add it to the certificates it has already loaded - it doesn't normally
replace the old certificate store. This would mean it would be impossible for
a user to decide *not* to trust the certificate supplied with curl, but only
to trust 'extra' certs on top of those supplied.

Anyway, hope the above info is useful,

Cris

-------------------------------------------------------
This sf.net email is sponsored by: Jabber - The world's fastest growing
real-time communications platform! Don't just IM. Build it in!
http://www.jabber.com/osdn/xim
Received on 2002-08-28