>From: [email protected] On Behalf Of Derek Cole
>Sent: Tuesday, 09 October, 2012 21:12

>I am trying to write a server that will accept an incoming SSL connection. 
        
>In psuedo, I have the following chain of function calls
        
>    SSL_CTX_load_verify_locations(ctx, root_cert_file, root_cert_dir)
>    SSL_CTX_use_certificate_chain_file(chain file)
>    SSK_CTX_use_PrivateKey_file(chain file)
>    SSL_CTX_set_verify (sets SSL_VERIFY_PEER)
>    SSL_CTS_set_verify_depth(to a depth of 4)

I assume you are checking all calls that can return an error 
indication; you suggest this below "everything goes fine".
If not, do so. But not all errors are (or can be) caught, 
so lack of error indication doesn't prove lack of error.

When you request client auth (aka client cert), it's usually 
best to specify the CAs you like, so if the client has multiple 
certs it can pick right. OpenSSL does NOT do this automatically. 
If root_cert_file (or another file) has all CA(s) you trust, you 
can use SSL_load_client_CA_file and SSL_[CTX_]set_client_CA_list .
Otherwise, e.g. if you have CA(s) present only in root_cert_dir, 
it's a little more complicated.

Note SSL_VERIFY_PEER requests client auth but doesn't require it.
To require it add SSL_VERIFY_FAIL_IF_NO_PEER_CERT .

And if you want to allow clients to use certs from a public CA, 
depth 4 doesn't leave much margin. Practically all public CAs 
today chain either 2 or 3 within the CA itself, and often 1 or 2 
more when one CA "buys" trust from another (usually older) one.
If you require clients use certs you issue with your own CA 
(see below) you can control the depth.

>       The chain file has 3 things in it - 
>       private key of the server CA
>       a signed certificate request signed by my server CA
>       the public key of the server CA
        
0. A CA doesn't sign requests (CSRs), it signs certs. 
A cert is *derived from* a CSR, but it isn't a signed CSR. 
If you have a cert issued from a CSR for your server, 
it is a cert for your server, or just your server cert.

1. A cert chain consists of certs, not publickeys. 

2. If your server cert is signed by the CA root key+cert,
you don't need any chain. Just load the server privatekey 
and the server cert. If your server cert is signed by an 
intermediate CA key+cert, and that possibly by another etc., 
you must either (1) send chain or (2) have client(s) trust
anyway, depending on client. There are several suboptions:
(1A) give the server cert and chain cert(s) in chain_file 
(1B) give the server cert and have chain cert(s) in server 
truststore (your root_cert_file and/or root_cert_dir).
OpenSSL automatically fills the chain from truststore.
(2A) have client trust the first (non-sent) intermediate 
cert as an anchor. OpenSSL doesn't but other clients may.
(2B) have all non-sent chain certs in and used from client 
truststore. OpenSSL does (automatically).
2A and 2B depend on the client(s), and so are suitable only 
if your clients are known and reasonably few. 

3. In all cases, the/each client's truststore must contain 
the CA root for the server cert. Does "my" server CA mean one 
you own and operate, or a public one you chose to use? 

3A. If the server CA is a public one like Verisign, the client 
may already trust its root, depending on the client. Windows 
and common web browsers, and some utilities like curl, and 
Java, come with truststores containing some dozens of public 
established CA roots. OpenSSL does not. If you use s_client 
or similar, you need to get at least the root used, and 
optionally others you like, and put in client truststore.

3B. If the server CA is one you created (and not delegated 
as a CA under an established CA, which AIUI is difficult and 
costly to obtain so probably not), no typical client will 
have its root already; for all clients, you must add it.

>When I create a new SSL structure everything goes fine, but when 
>I call SSL_accept() on it, I get a return of zero, which when 
>I read the error queue says "sslv3 alert bad certificate"
        
>What does this error mean exactly? Is it a problem with my server 
>certificate itself, the client certificate returned on the verify, 
>or what? 
        
"alert" means client said it didn't like your (server) auth. 
Either the client is mistaken, usually because it doesn't have 
the root in its truststore as above (though bugs are possible), 
or the cert/chain you sent is in fact bad. This occurs at a 
point the in protocol before client-auth, so no attempt was 
made to verify any client cert. If a client cert is received 
and doesn't verify, that's a different error.

The client may have displayed a more specific error. If not, 
try another client. If no better client is available, and 
you have or can get openssl on (any) client system, use s_client 
with a suitable truststore as above; it will be more specific.

Or just examine your files and calls based on the rules above.


______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    [email protected]
Automated List Manager                           [email protected]

Reply via email to