Hi all,
I hate to reply to my own posting but I managed to get certificate
chains working. The trick is in setting up the stacked client
certificate in the right order. Here's what I did:
ca.crt --- server.crt
+-- sub-ca.crt --- client.crt
the server is configured with --ca ca.crt and --cert server.crt
the client is configured with --ca ca.crt and --cert stacked.crt where
'stacked.crt' is created using
cat client.crt sub-ca.crt > stacked.crt
(my certs consist of BEGIN/END blocks only, not textual output in between)
With this setup I can connect to my server.
having said that, this still does not make a good idea to use
--ca Verisign.crt
as your server CA, as you're still wide open to anybody with a valid
Verisign cert - if you want to use certificate paths like this also
include something like a tls-verify script.
share and enjoy,
JJK
Jan Just Keijser wrote:
Hi Adriaan,
Adriaan de Jong wrote:
-----Original Message-----
From: Jan Just Keijser [mailto:janj...@nikhef.nl]
Hi Samuli, David, list,
What some people get confused about is a stacked certificate vs a
certificate chain: OpenVPN only supports stacked CA certificates,
meaning that any of the certs present in the stacked file are
considered
trusted.
What some people want is a certificate chain, like some websites use:
the website has a server certificate signed by a sub-CA which in turn
is
signed by Verisign. The webserver sends the entire chain (server cert +
sub-CA cert + verisign cert) to the client for verification. That way
the client only needs the Verisign cert to trust a particular website
(the Verisign CA cert is installed in most browser by default). OpenVPN
does not support this at the moment. It would require changing
SSL_CTX_use_certificate()
to
SSL_CTX_use_certificate_chain()
to ensure that the entire certificate chain is sent to the remote end
(client or server).
I think SSL_CTX_use_certificate_chain_file() is actually used when loading the
certificate from a separate cert file. It's just slightly confusing due to the
fact that it is loaded twice:
- SSL_CTX_use_certificate_file is used here:
http://openvpn.git.sourceforge.net/git/gitweb.cgi?p=openvpn/openvpn-testing.git;a=blob;f=ssl.c;h=a1268ac2a9291dc1512fa28e3ab4efc65085c952;hb=HEAD#l1639
- SSL_CTX_use_certificate_chain_file is used here:
http://openvpn.git.sourceforge.net/git/gitweb.cgi?p=openvpn/openvpn-testing.git;a=blob;f=ssl.c;h=a1268ac2a9291dc1512fa28e3ab4efc65085c952;hb=HEAD#l1738
I'm not entirely sure whether I'm right, and why things are done this way. Does
anyone know the reasoning behind this?
ah mea culpa - I did not read the rest of the init_ssl function. It
does seem a bit odd though:
this happens first (2.1.3 code base):
1623 if (!SSL_CTX_use_certificate_file (ctx,
options->cert_file, SSL_FILETYPE_PEM))
1624 msg (M_SSLERR, "Cannot load certificate file %s",
options->cert_file);
1625 using_cert_file = true;
so we load the cert and we set 'using_cert_file = true' . Then later:
1721 /* Enable the use of certificate chains */
1722 if (using_cert_file)
1723 {
1724 if (!SSL_CTX_use_certificate_chain_file (ctx,
options->cert_file))
1725 msg (M_SSLERR, "Cannot load certificate chain file %s
(SSL_use_certificate_chain_file)", options->cert_file);
1726 }
so the certificate is loaded again but now using
_use_certificate_chain ! It does suggest that you can use certificate
chains , however.
I just tested a setup where the client cert is a concatenation of the
client cert + intermediate CA. The client sends these certs to a
server which only trusts the "root" CA (i.e. the one that signed the
intermediate CA to begin with) but I cannot connect. It seems the
'verify_callback' function does not work with certificate chains (yet)
: only the top level cert is inspected.
to be continued...
cheers,
JJK