Dear list,

This is too basic for not having been discussed here before, but despite the fact I keep looking in the archives, manual pages and tutorials, I simply can't find a solution. :(

Basically, I wrote a C server and a client and I want them to authenticate each other using X509 certificates (and I'm also using openssl to encrypt the connection).

My problem is that my server simply won't request my client's certificate. I believe the problem is on my server, because if I use "openssl s_server" with my client, everything works fine (using "openssl s_client" with my server also does not work).

What I've done:

I created a CA (ca.crt/ca.key).
I created a key for my client (client.key) and generated a certificate request (client.csr).
My CA signed the key (generating client.crt).
I did the same thing with the server (server.key / .csr / .crt).

Then I wrote a server that does the following (without the error checking):

// Variable declarations
X509 *peerCert;
X509_NAME *xname;
SSL_CTX *ctx;
SSL *ssl;
BIO *bio, *abio, *out, *sbio;
char buf[256];
STACK_OF(X509_NAME) *ca_names;
const unsigned char ctx_id[] = "my_server";

// Library initialisation
SSL_load_error_strings();
SSL_library_init();
ERR_load_BIO_strings();
ERR_load_SSL_strings();
OpenSSL_add_all_algorithms();

// CTX setup
ctx = SSL_CTX_new(SSLv23_server_method());
SSL_CTX_set_quiet_shutdown(ctx, 1);
SSL_CTX_load_verify_locations(ctx, "ca.crt", NULL);
SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_ONCE, NULL);
SSL_CTX_set_session_id_context(ctx, ctx_id, sizeof(ctx_id));
ca_names = SSL_load_client_CA_file("ca.crt");
SSL_CTX_set_client_CA_list(ctx, ca_names);

// BIO
bio = BIO_new_ssl(ctx, 0);
BIO_get_ssl(bio, &ssl);
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
SSL_set_accept_state(ssl);
abio = BIO_new_accept("9443");
BIO_set_accept_bios(abio, bio);
while(1) {
 BIO_do_accept(abio);
 BIO_do_accept(abio);
 out = BIO_pop(abio);
 BIO_do_handshake(out);
 peerCert = SSL_get_peer_certificate(ssl);
 xname = X509_get_subject_name(peerCert);
 X509_NAME_get_text_by_NID(xname, NID_commonName, buf, sizeof(buf));
 // do stuff
 BIO_free_all(out);
}

I believe my client is irrelevant at this point, because if I use "openssl s_server", it works beautifully with my client. However, when I use my server and my client (or openssl s_client), it fails accusing my client of not providing the certificate. All points to my server not requesting the client certificate properly.

Here is how I use openssl s_server to debug:
openssl s_server -accept 9443 -Verify 0 -cert server.crt -key server.key -CAfile ca.crt

Verify 0 or 1 works the same in this case, since my CA signed the certificates directly.

Would anyone know what is wrong? =S

Regards,
Felipe
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to