On Nov 30, 2005, at 4:42 PM, Victor Duchovni wrote:
This is completely doable. Example code to be found in many SSL applications.http://www.postfix.org/TLS_README.html#server_vrfy_client http://www.postfix.org/TLS_README.html#server_access http://www.postfix.org/postconf.5.html#permit_tls_clientcerts Source code: http://www.postfix.org/dowload.html get 2.3-20051128 and look at: src/tls/tls_verify.c src/tls/tls_server.c src/tls/tls_client.c
Sorry, I don't actually see that the postfix code is doing what I want. I see that you're computing the client's fingerprint in tls_server.c, but that's only after SSL has verified the client certificate. In my case, the client has a self-signed certificate, so the verification fails. As a result (I think), SSL_get_peer_certificate is returning NULL (see sample code below).
Sean
--
Boredom is always counterrevolutionary.
// Simple echo server using TLS
int
main(int argc, char *argv[])
{
SSL_load_error_strings();
SSL_library_init();
SSL_CTX *ctx = SSL_CTX_new(TLSv1_server_method());
assert(ctx);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
NULL);
if (!SSL_CTX_use_certificate_file(ctx, "server-cert.pem",
SSL_FILETYPE_PEM))
error("server: load cert error");
if (!SSL_CTX_use_PrivateKey_file(ctx, "server-priv.pem",
SSL_FILETYPE_PEM))
error("server: load key error");
if (!SSL_CTX_check_private_key(ctx))
error("server: private key doesn't match cert");
SSL *ssl = SSL_new(ctx);
assert(ssl);
int ssock = socket(AF_INET, SOCK_STREAM, 0);
int n = 1;
setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(2000);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(ssock, (const sockaddr*) &addr, sizeof(addr))) {
perror("bind:");
assert(0);
}
if (listen(ssock, 5))
assert(0);
while (1) {
printf("server: waiting for accept\n");
socklen_t addrlen = sizeof(addr);
int sock = accept(ssock, (sockaddr*) &addr, &addrlen);
if (sock <= 0)
assert(0);
printf("server: tcp accept succeeded\n");
if (!SSL_set_fd(ssl, sock))
assert(0);
int ret;
if ((ret = SSL_accept(ssl)) == 0) {
int err = SSL_get_error(ssl, ret);
printf("server: accept err=%d\n", err);
assert(0);
}
printf("server: ssl accept succeeded\n");
// XXX: this fails:
assert(SSL_get_verify_result(ssl) == X509_V_OK);
X509 *peer = SSL_get_peer_certificate(ssl);
// XXX: and if you comment out the above assert, this fails,
too:
assert(peer);
int n;
char readbuf[256];
while ((n = SSL_read(ssl, readbuf, sizeof(readbuf))) > 0) {
printf("server: read %d bytes\n", n);
if (SSL_write(ssl, readbuf, n) != n)
break;
printf("server: wrote %d bytes\n", n);
}
printf("server: connection closed\n");
}
return 0;
}
PGP.sig
Description: This is a digitally signed message part
