1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

add callback for OpenSSL client cert verification action

Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
Andy Green 2011-02-21 08:06:47 +00:00
parent c6bf2c2186
commit 6901cb3b4e
4 changed files with 95 additions and 3 deletions

View file

@ -709,6 +709,9 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
wsi->client_bio = BIO_new_socket(wsi->sock, BIO_NOCLOSE);
SSL_set_bio(wsi->ssl, wsi->client_bio, wsi->client_bio);
SSL_set_ex_data(wsi->ssl,
this->openssl_websocket_private_data_index, this);
if (SSL_connect(wsi->ssl) <= 0) {
fprintf(stderr, "SSL connect error %s\n",
ERR_error_string(ERR_get_error(), ssl_err_buf));
@ -1390,6 +1393,39 @@ static void sigpipe_handler(int x)
{
}
#ifdef LWS_OPENSSL_SUPPORT
static int
OpenSSL_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx)
{
SSL *ssl;
int n;
// struct libwebsocket_context *this;
ssl = X509_STORE_CTX_get_ex_data(x509_ctx,
SSL_get_ex_data_X509_STORE_CTX_idx());
/*
* !!! can't get this->openssl_websocket_private_data_index
* can't store as a static either
*/
// this = SSL_get_ex_data(ssl, this->openssl_websocket_private_data_index);
n = this->protocols[0].callback(NULL, NULL,
LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
x509_ctx, ssl, preverify_ok);
/* convert return code from 0 = OK to 1 = OK */
if (!n)
n = 1;
else
n = 0;
return n;
}
#endif
/**
* libwebsocket_create_context() - Create the websocket handler
@ -1553,6 +1589,9 @@ libwebsocket_create_context(int port, const char *interface,
OpenSSL_add_all_algorithms();
SSL_load_error_strings();
this->openssl_websocket_private_data_index =
SSL_get_ex_new_index(0, "libwebsockets", NULL, NULL, NULL);
/*
* Firefox insists on SSLv23 not SSLv3
* Konq disables SSLv2 by default now, SSLv23 works
@ -1613,7 +1652,8 @@ libwebsocket_create_context(int port, const char *interface,
/* absolutely require the client cert */
SSL_CTX_set_verify(this->ssl_ctx,
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
OpenSSL_verify_callback);
/*
* give user code a chance to load certs into the server
@ -1625,7 +1665,6 @@ libwebsocket_create_context(int port, const char *interface,
this->ssl_ctx, NULL, 0);
}
if (this->use_ssl) {
/* openssl init for server sockets */

View file

@ -46,6 +46,7 @@ enum libwebsocket_callback_reasons {
LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS,
LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS,
LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION,
/* external poll() management support */
LWS_CALLBACK_ADD_POLL_FD,
@ -217,6 +218,25 @@ struct libwebsocket_context;
* verify the validity of certificates returned by clients. @user
* is the server's OpenSSL SSL_CTX*
*
* LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION: if the
* libwebsockets context was created with the option
* LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this
* callback is generated during OpenSSL verification of the cert
* sent from the client. It is sent to protocol[0] callback as
* no protocol has been negotiated on the connection yet.
* Notice that the libwebsockets context and wsi are both NULL
* during this callback. See
* http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
* to understand more detail about the OpenSSL callback that
* generates this libwebsockets callback and the meanings of the
* arguments passed. In this callback, @user is the x509_ctx,
* @in is the ssl pointer and @len is preverify_ok
* Notice that this callback maintains libwebsocket return
* conventions, return 0 to mean the cert is OK or 1 to fail it.
* This also means that if you don't handle this callback then
* the default callback action of returning 0 allows the client
* certificates.
*
* The next four reasons are optional and only need taking care of if you
* will be integrating libwebsockets sockets into an external polling
* array.

View file

@ -181,6 +181,7 @@ struct libwebsocket_context {
int use_ssl;
SSL_CTX *ssl_ctx;
SSL_CTX *ssl_client_ctx;
int openssl_websocket_private_data_index;
#endif
struct libwebsocket_protocols *protocols;
int count_protocols;

View file

@ -583,12 +583,44 @@ to kill the connection.
</blockquote>
<h3>LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS</h3>
<blockquote>
if configure for
if configured for
including OpenSSL support, this callback allows your user code
to perform extra <b>SSL_CTX_load_verify_locations</b> or similar
calls to direct OpenSSL where to find certificates the client
can use to confirm the remote server identity. <tt><b>user</b></tt> is the
OpenSSL SSL_CTX*
</blockquote>
<h3>LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS</h3>
<blockquote>
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. <tt><b>user</b></tt>
is the server's OpenSSL SSL_CTX*
</blockquote>
<h3>LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION</h3>
<blockquote>
if the
libwebsockets context was created with the option
LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this
callback is generated during OpenSSL verification of the cert
sent from the client. It is sent to protocol[0] callback as
no protocol has been negotiated on the connection yet.
Notice that the libwebsockets context and wsi are both NULL
during this callback. See
</blockquote>
<h3>http</h3>
<blockquote>
//www.openssl.org/docs/ssl/SSL_CTX_set_verify.html
to understand more detail about the OpenSSL callback that
generates this libwebsockets callback and the meanings of the
arguments passed. In this callback, <tt><b>user</b></tt> is the x509_ctx,
<tt><b>in</b></tt> is the ssl pointer and <tt><b>len</b></tt> is preverify_ok
Notice that this callback maintains libwebsocket return
conventions, return 0 to mean the cert is OK or 1 to fail it.
This also means that if you don't handle this callback then
the default callback action of returning 0 allows the client
certificates.
<p>
The next four reasons are optional and only need taking care of if you
will be integrating libwebsockets sockets into an external polling