It's a good idea for server to set client-CA list, but not required. If it isn't set,
libssl server will send CertReq with an empty list, which the RFCs permit, and the browsers I have to hand (IE9, FF31, Chrome36.something) all handle. The OP's problem is more likely on the client side. From: owner-openssl-us...@openssl.org [mailto:owner-openssl-us...@openssl.org] On Behalf Of Michael Wojcik Sent: Friday, July 25, 2014 12:44 To: openssl-users@openssl.org Subject: [SPAM?] RE: Adding client peer verification to my server Unless I've overlooked it, you don't appear to be calling SSL_CTX_set_client_CA_list or SSL_CTX_add_client_CA anywhere. When an SSL/TLS server wants to request a peer certificate, it has to send a list of the CAs it recognizes to the client, so the client knows which certificate to send. (The client may have a number of certificates, issued by various CAs; for example, the client might be a browser running on behalf of a user who has an internally-issued company certificate and a personal certificate issued by a well-known commercial CA.) The simplest API to set that up in OpenSSL is SSL_CTX_load_client_CA_file: SSL_CTX_set_client_CA_list(CTX, SSL_CTX_load_client_CA_file("/path/to/CAcerts.pem")); (or with, you know, error handling, if you want to be fancy). See http://www.openssl.org/docs/ssl/SSL_load_client_CA_file.html. Michael Wojcik Technology Specialist, Micro Focus From: owner-openssl-us...@openssl.org [mailto:owner-openssl-us...@openssl.org] On Behalf Of Marco Bambini Sent: Friday, 25 July, 2014 03:36 To: openssl-users@openssl.org Subject: Adding client peer verification to my server Hello, I am adding client peer verification to my own server but I continue to receive an error: SSL3_GET_CLIENT_CERTIFICATE:no certificate returned:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s3_srvr.c:2631: Here you go some relevant code: SERVER: ssl_initialize called at startup int ssl_initialize (void) { SSL_CTX *CTX = NULL; char ssl_certificate[MAXPATH]; char root_certificate[MAXPATH]; int i, size; // initialize SSL crap SSL_library_init(); SSL_load_error_strings(); // allocate CTX opaque datatype if ((CTX = SSL_CTX_new(SSLv23_server_method())) == NULL) goto initialize_ssl_abort; // check if a root CA file is present if (get_path_to_root_ca_file(root_certificate)) { settings.ssl_verify_peer = kTRUE; if (SSL_CTX_load_verify_locations(CTX, root_certificate, NULL) != 1) { goto initialize_ssl_abort; } if (SSL_CTX_set_default_verify_paths(CTX) != 1) { goto initialize_ssl_abort; } } // try to set up SSL certificate if (get_path_to_ssl_certificate(ssl_certificate)) { if (SSL_CTX_use_certificate_file(CTX, ssl_certificate, SSL_FILETYPE_PEM) == 0) { goto initialize_ssl_abort; } else if (CTX != NULL && SSL_CTX_use_PrivateKey_file(CTX, ssl_certificate, SSL_FILETYPE_PEM) == 0) { goto initialize_ssl_abort; } } else { log_system("SSL certificate not found. SSL server could refuse connections from clients."); } // try to set up SSL chain file if (get_path_to_ssl_chain_file(ssl_certificate)) { if (SSL_CTX_use_certificate_chain_file(CTX, ssl_certificate) == 0) { goto initialize_ssl_abort; } } if (settings.ssl_verify_peer) { log_system("SSL peer verification activated."); SSL_CTX_set_verify(CTX, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback); SSL_CTX_set_verify_depth(CTX, 4); } // initialize locking callbacks, needed for thread safety. // <http://www.openssl.org/support/faq.html#PROG1> http://www.openssl.org/support/faq.html#PROG1 size = sizeof(pthread_mutex_t) * CRYPTO_num_locks(); if ((settings.ssl_mutexes = (pthread_mutex_t *) cubesql_malloc((size_t)size)) == NULL) { goto initialize_ssl_abort; } for (i = 0; i < CRYPTO_num_locks(); i++) { pthread_mutex_init(&settings.ssl_mutexes[i], NULL); } CRYPTO_set_locking_callback(&ssl_locking_callback); CRYPTO_set_id_callback(&ssl_id_callback); settings.ssl_ctx = CTX; return kTRUE; initialize_ssl_abort: DEBUG_WRITE("SSL initialization error: %s", ssl_error()); log_system("ssl_initialize failed."); return kFALSE; } and this code called each time a new client connects: client->ssl = SSL_new(settings.ssl_ctx); if (client->ssl == NULL) return kFALSE; if (client->ssl) { int r1 = 0, r2 = 0; r1 = SSL_set_fd(client->ssl, client->connfd); if (r1) r2 = SSL_accept(client->ssl); // ERROR CHECK if ((r1 != 1) || (r2 != 1)) { SSL_shutdown(client->ssl); SSL_free(client->ssl); client->ssl = NULL; return kFALSE; } if (settings.ssl_verify_peer) { if (ssl_post_connectioncheck(client) == kFALSE) { SSL_shutdown(client->ssl); SSL_free(client->ssl); client->ssl = NULL; return kFALSE; } } } SSL3_GET_CLIENT_CERTIFICATE:no certificate is returned by SSL_accept. CLIENT: init ssl: // allocate CTX opaque datatype if ((db->ssl_ctx = SSL_CTX_new(SSLv3_client_method())) == NULL) goto load_ssl_abort; // try to set up SSL certificate if (ssl_certificate != NULL) { if (SSL_CTX_use_certificate_file(db->ssl_ctx, ssl_certificate, SSL_FILETYPE_PEM) == 0) { goto load_ssl_abort; } else if (db->ssl_ctx != NULL && SSL_CTX_use_PrivateKey_file(db->ssl_ctx, ssl_certificate, SSL_FILETYPE_PEM) == 0) { goto load_ssl_abort; } } Server has root.pem and server.pem while client has client.pem Certificates has been created using: To create the root CA: $ openssl req -newkey rsa:1024 -sha1 -keyout rootkey.pem -out rootreq.pem $ openssl x509 -req -in rootreq.pem -sha1 -extensions v3_ca -signkey rootkey.pem -out rootcert.pem $ cp rootkey.pem rootkey.pem.copy $ openssl rsa -in rootkey.pem.copy -out rootkey.pem $ cat rootcert.pem rootkey.pem > root.pem To create the server CA and sign it with the root CA: $ openssl req -newkey rsa:1024 -sha1 -keyout serverCAkey.pem -out serverCAreq.pem $ openssl x509 -req -in serverCAreq.pem -sha1 -extensions v3_ca -CA root.pem -CAkey root.pem -CAcreateserial -out serverCAcert.pem $ cp serverCAkey.pem serverCAkey.pem.copy $ openssl rsa -in serverCAkey.pem.copy -out serverCAkey.pem $ cat serverCAcert.pem serverCAkey.pem rootcert.pem > serverCA.pem To create the server's certificate and sign it with the Server CA: $ openssl req -newkey rsa:1024 -sha1 -keyout serverkey.pem -out serverreq.pem $ openssl x509 -req -in serverreq.pem -sha1 -extensions usr_cert -CA serverCA.pem -CAkey serverCA.pem -CAcreateserial -out servercert.pem $ cp serverkey.pem serverkey.pem.copy $ openssl rsa -in serverkey.pem.copy -out serverkey.pem $ cat servercert.pem serverkey.pem serverCAcert.pem rootcert.pem > server.pem To create the client certificate and sign it with the Root CA $ openssl req -newkey rsa:1024 -sha1 -keyout clientkey.pem -out clientreq.pem $ openssl x509 -req -in clientreq.pem -sha1 -extensions usr_cert -CA root.pem -CAkey root.pem -CAcreateserial -out clientcert.pem $ cp clientkey.pem clientkey.pem.copy $ openssl rsa -in clientkey.pem.copy -out clientkey.pem $ cat clientcert.pem clientkey.pem rootcert.pem > client.pem Any help would be really really appreciated. Thanks a lot. -- Marco Bambini http://www.sqlabs.com http://twitter.com/sqlabs http://instagram.com/sqlabs Click here <https://www.mailcontrol.com/sr/MZbqvYs5QwJvpeaetUwhCQ==> to report this email as spam. This message has been scanned for malware by Websense. <http://www.websense.com/> www.websense.com