Tom Pusateri reported success with using OpenSSL client certificates and libevent’s builtin OpenSSL support. Here is what he wrote on the mailing list:
I tried 2.0.3 alpha against the Apple Push notification feedback service which requires a client key/certificate and it works great.
One hint… Make sure you add the key and cert to the SSL context before calling SSL_new(). Otherwise, you’ll get an error that looks like:
sslv3 alert handshake failure in SSL routines SSL3_READ_BYTESHere’s the working code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
static void init_feedback_service(struct event_base *ev_base, struct evdns_base *dns) { int rc; struct bufferevent *bev; SSL_CTX *ssl_ctx; SSL *ssl; ssl_ctx = SSL_CTX_new(SSLv3_method()); rc = SSL_CTX_use_certificate_file(ssl_ctx, "my_apple_cert_key.pem", SSL_FILETYPE_PEM); if (rc != 1) { errx(EXIT_FAILURE, "Could not load certificate file"); } rc = SSL_CTX_use_PrivateKey_file(ssl_ctx, "my_apple_cert_key.pem", SSL_FILETYPE_PEM); if (rc != 1) { errx(EXIT_FAILURE, "Could not load private key file"); } ssl = SSL_new(ssl_ctx); bev = bufferevent_openssl_socket_new(ev_base, -1, ssl, BUFFEREVENT_SSL_CONNECTING, BEV_OPT_CLOSE_ON_FREE); bufferevent_setcb(bev, feedback_read_cb, NULL, feedback_event_cb, NULL); rc = bufferevent_socket_connect_hostname(bev, dns, AF_INET, "feedback.sandbox.push.apple.com", 2196); if (rc < 0) { warnx("could not connect to feedback service: %s", evutil_socket_error_to_string(EVUTIL_SOCKET_ERROR())); bufferevent_free(bev); return; } bufferevent_enable(bev, EV_READ); }