add callback to allow additional server verification certs
authorAndy Green <andy@warmcat.com>
Sun, 20 Feb 2011 11:10:47 +0000 (11:10 +0000)
committerAndy Green <andy@warmcat.com>
Sun, 20 Feb 2011 11:10:47 +0000 (11:10 +0000)
This adds a LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS callback
which offers a chance for the server context to be loaded with additional
certtificates allowing it to verify incoming client certs.  The callback
always comes to protocol[0].

It also introduces the context option LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT
which will enforce client cert checking on any ssl connection.

Signed-off-by: Andy Green <andy@warmcat.com>
lib/libwebsockets.c
lib/libwebsockets.h

index aaf991a..40b9a20 100644 (file)
@@ -474,6 +474,7 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
                                free(new_wsi);
                                break;
                        }
+                       
                        debug("accepted new SSL conn  "
                              "port %u on fd=%d SSL ver %s\n",
                                ntohs(cli_addr.sin_port), accept_fd,
@@ -1601,10 +1602,29 @@ libwebsocket_create_context(int port, const char *interface,
         * helping the client to verify server identity
         */
 
-       this->protocols[0].callback(this, wsi,
+       this->protocols[0].callback(this, NULL,
                LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
                this->ssl_client_ctx, NULL, 0);
 
+       /* as a server, are we requiring clients to identify themselves? */
+
+       if (options & LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT) {
+
+               /* absolutely require the client cert */
+               
+               SSL_CTX_set_verify(this->ssl_ctx,
+                      SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
+
+               /*
+                * give user code a chance to load certs into the server
+                * allowing it to verify incoming client certs
+                */
+
+               this->protocols[0].callback(this, NULL,
+                       LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
+                                                       this->ssl_ctx, NULL, 0);
+       }
+
 
        if (this->use_ssl) {
 
index 0890c9b..d4a0b02 100644 (file)
@@ -29,6 +29,7 @@
 
 enum libwebsocket_context_options {
        LWS_SERVER_OPTION_DEFEAT_CLIENT_MASK = 1,
+       LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = 2,
 };
 
 enum libwebsocket_callback_reasons {
@@ -44,6 +45,7 @@ enum libwebsocket_callback_reasons {
        LWS_CALLBACK_FILTER_NETWORK_CONNECTION,
        LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
        LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
+       LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
 
        /* external poll() management support */
        LWS_CALLBACK_ADD_POLL_FD,
@@ -202,13 +204,19 @@ struct libwebsocket_context;
  *             content before deciding to allow the handshake to proceed or
  *             to kill the connection.
  *
- *     LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: if configure for
+ *     LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: if configured for
  *             including OpenSSL support, this callback allows your user code
  *             to perform extra SSL_CTX_load_verify_locations() or similar
  *             calls to direct OpenSSL where to find certificates the client
  *             can use to confirm the remote server identity.  @user is the
  *             OpenSSL SSL_CTX*
  *
+ *     LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS: if configured for
+ *             including OpenSSL support, this callback allows your user code
+ *             to load extra certifcates into the server which allow it to
+ *             verify the validity of certificates returned by clients.  @user
+ *             is the server's OpenSSL SSL_CTX*
+ *
  *     The next four reasons are optional and only need taking care of if you
  *     will be integrating libwebsockets sockets into an external polling
  *     array.