On 03/18/2013 02:01 AM, Craig Ringer wrote:
> This appears to match Ian's description of having a validation-only cert
> list and a separate list of certs used to verify clients. I'd like to
> follow Apache's model:

Ready for some more good news?

It's possible that I'm missing something, but Apache (mod_ssl) appears
to exhibit the exact same behavior.

Tested on Fedora 18, with the following packages:

  httpd-2.4.3-15.fc18.x86_64
  mod_ssl-2.4.3-15.fc18.x86_64
  openssl-1.0.1e-3.fc18.x86_64

I have set the following in /etc/httpd/conf.d/ssl.conf:

  Listen 44443 https
  <VirtualHost _default_:44443>
  ServerName postgres.example.com
  SSLCertificateFile /etc/pki/tls/certs/postgres.crt
  SSLCertificateKeyFile /etc/pki/tls/private/postgres.key
  SSLCACertificateFile /etc/pki/tls/certs/client-ca.chain
  SSLCADNRequestFile /etc/pki/tls/certs/client-ca.crt
  SSLVerifyClient require
  SSLVerifyDepth  10

Notes:

  * The port is set to 44443, because that's hard-coded into the
    (attached) test client.
  * I am using the certificates that I previously sent.
  * ServerName is set to postgres.example.com to match its certificate.
  * postgres.crt contains its entire chain (postgres.crt + server-ca.crt
    + root-ca.crt), so that I don't have to specify a
    SSLCertificateChainFile.
  * client-ca.chain is client-ca.crt + root-ca.crt.  As with PostgreSQL,
    I found that I have to provide the root CA certificate in order for
    any client to connect.

With this configuration, the test client is able to connect with the
"good" client certificate, but it is also able to connect with the "bad"
client certificate when it presents a certificate chain that includes
the server CA certificate.

-- 
========================================================================
Ian Pilcher                                         arequip...@gmail.com
Sometimes there's nothing left to do but crash and burn...or die trying.
========================================================================
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <openssl/ssl.h>
#include <openssl/err.h>

int main(int argc, char *argv[])
{
    SSL_CTX *ctx;
    SSL *ssl;
    struct sockaddr_in server_addr;
    int sock_fd;

    if (argc != 3) {
	fprintf(stderr, "USAGE: %s <client_cert> <client_key>\n", argv[0]);
	exit(__LINE__);
    }

    SSL_load_error_strings();
    SSL_library_init();

    if ((ctx = SSL_CTX_new(SSLv23_client_method())) == NULL) {
	ERR_print_errors_fp(stderr);
	exit(__LINE__);
    }

    if (SSL_CTX_use_certificate_chain_file(ctx, argv[1]) != 1) {
	ERR_print_errors_fp(stderr);
	exit(__LINE__);
    }

    if (SSL_CTX_use_PrivateKey_file(ctx, argv[2], SSL_FILETYPE_PEM) != 1) {
	ERR_print_errors_fp(stderr);
	exit(__LINE__);
    }

    if (SSL_CTX_check_private_key(ctx) != 1) {
	ERR_print_errors_fp(stderr);
	exit(__LINE__);
    }

    memset(&server_addr, 0, sizeof server_addr);
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(44443);
    server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);

    if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
	perror("socket");
	exit(__LINE__);
    }

    if (connect(sock_fd, (struct sockaddr *)&server_addr,
		sizeof server_addr) == -1) {
	perror("connect");
	exit(__LINE__);
    }

    puts("Connected.  Starting SSL handshake.");

    if ((ssl = SSL_new(ctx)) == NULL) {
	ERR_print_errors_fp(stderr);
	exit(__LINE__);
    }

    if (SSL_set_fd(ssl, sock_fd) == 0) {
	ERR_print_errors_fp(stderr);
	exit(__LINE__);
    }

    if (SSL_connect(ssl) != 1) {
	ERR_print_errors_fp(stderr);
	exit(__LINE__);
    }

    puts("SSL handshake successful.  Shutting down.");

    return 0;
}
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to