Hello, I have a weird problem with the program below. I compile it on Mac OS 10.8.2 and if I link it against the default OpenSSL version (0.9.8) it ignores the results of the verify callback. If I link it against the newest OpenSSL version available via Mac Ports, it works as expected (if the certificate is not valid, it aborts the connection immediately).
If I test both versions with a programm not using libevent (and with blocking calls) it works as expected. I think the problem is hidden in the combination of libevent and the default OpenSSL version, but I don't know where to look or even if it is libevent or OpenSSL related. (I tried libevent 2.0.21 and an alpha version.) I think it is ok to use the Mac Ports OpenSSL version for developing purposes but later it should work without having to install it. Regards Björn #include <event2/dns.h> #include <event2/bufferevent.h> #include <event2/bufferevent_ssl.h> #include <event2/buffer.h> #include <event2/util.h> #include <event2/event.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/rand.h> #include <openssl/x509.h> #include <openssl/hmac.h> #include <stdio.h> void readcb(struct bufferevent *bev, void *ptr) { char buf[1024]; int n; struct evbuffer *input = bufferevent_get_input(bev); while ((n = evbuffer_remove(input, buf, sizeof(buf))) > 0) { fwrite(buf, 1, n, stdout); } } void eventcb(struct bufferevent *bev, short events, void *ptr) { SSL *ssl = bufferevent_openssl_get_ssl(bev); X509 *peer; if (events & BEV_EVENT_CONNECTED) { printf("Connect okay\n"); if ((peer = SSL_get_peer_certificate(ssl))) { if (SSL_get_verify_result(ssl) == X509_V_OK) { /* The client sent a certificate which verified OK */ printf("ok\n"); } } } else if (events & (BEV_EVENT_ERROR|BEV_EVENT_EOF)) { struct event_base *base = ptr; if (events & BEV_EVENT_ERROR) { int err = bufferevent_socket_get_dns_error(bev); if (err) printf("DNS error: %s\n", evutil_gai_strerror(err)); } bufferevent_free(bev); event_base_loopexit(base, NULL); } } static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { printf("preverify_ok: %d\n", preverify_ok); return preverify_ok; } int main(int argc, char **argv) { struct event_base *base; struct evdns_base *dns_base; struct bufferevent *bev; SSL_CTX *ssl_ctx; SSL *ssl; SSL_load_error_strings(); SSL_library_init(); RAND_poll(); ssl_ctx = SSL_CTX_new(SSLv3_method()); SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, verify_callback); if (SSL_CTX_load_verify_locations(ssl_ctx, "root.crt", NULL) != 1){ fprintf(stderr, "Couldn't load certificate trust store.\n"); return -1; } ssl = SSL_new(ssl_ctx); base = event_base_new(); dns_base = evdns_base_new(base, 1); bev = bufferevent_openssl_socket_new(base, -1, ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(bev, readcb, NULL, eventcb, base); bufferevent_enable(bev, EV_READ|EV_WRITE); evbuffer_add_printf(bufferevent_get_output(bev), "GET /\r\n"); bufferevent_socket_connect_hostname( bev, dns_base, AF_UNSPEC, "www.google.com", 443); event_base_dispatch(base); return 0; } *********************************************************************** To unsubscribe, send an e-mail to majord...@freehaven.net with unsubscribe libevent-users in the body.