OpenSSL Client Certificates and Libevent-2.0.3-alpha

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);
}
The views expressed on these pages are my own and do not represent the views of anyone else.
Built with Hugo - Theme Stack designed by Jimmy