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:
parent
c6bf2c2186
commit
6901cb3b4e
4 changed files with 95 additions and 3 deletions
|
@ -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 */
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue