ssl config for http client

This commit is contained in:
Joel Winarske 2017-02-20 20:53:58 -08:00 committed by Andy Green
parent 88d6c1a63b
commit 390ba34400
3 changed files with 80 additions and 13 deletions

View file

@ -95,6 +95,10 @@ static const char * const paths_vhosts[] = {
"vhosts[].mounts[].pmo[].*",
"vhosts[].headers[].*",
"vhosts[].headers[]",
"vhosts[].client-ssl-key",
"vhosts[].client-ssl-cert",
"vhosts[].client-ssl-ca",
"vhosts[].client-ssl-ciphers",
};
enum lejp_vhost_paths {
@ -137,6 +141,10 @@ enum lejp_vhost_paths {
LEJPVP_PMO,
LEJPVP_HEADERS_NAME,
LEJPVP_HEADERS,
LEJPVP_CLIENT_SSL_KEY,
LEJPVP_CLIENT_SSL_CERT,
LEJPVP_CLIENT_SSL_CA,
LEJPVP_CLIENT_CIPHERS,
};
static const char * const parser_errs[] = {
@ -313,6 +321,22 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
a->info->ssl_cert_filepath = NULL;
a->info->ssl_private_key_filepath = NULL;
a->info->ssl_ca_filepath = NULL;
a->info->client_ssl_cert_filepath = NULL;
a->info->client_ssl_private_key_filepath = NULL;
a->info->client_ssl_ca_filepath = NULL;
a->info->client_ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:"
"ECDHE-RSA-AES256-GCM-SHA384:"
"DHE-RSA-AES256-GCM-SHA384:"
"ECDHE-RSA-AES256-SHA384:"
"HIGH:!aNULL:!eNULL:!EXPORT:"
"!DES:!MD5:!PSK:!RC4:!HMAC_SHA1:"
"!SHA1:!DHE-RSA-AES128-GCM-SHA256:"
"!DHE-RSA-AES128-SHA256:"
"!AES128-GCM-SHA256:"
"!AES128-SHA256:"
"!DHE-RSA-AES256-SHA256:"
"!AES256-GCM-SHA384:"
"!AES256-SHA256";
a->info->timeout_secs = 5;
a->info->ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:"
"ECDHE-RSA-AES256-GCM-SHA384:"
@ -406,7 +430,15 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
a->any_vhosts = 1;
if (a->enable_client_ssl) {
const char *cert_filepath = a->info->client_ssl_cert_filepath;
const char *private_key_filepath = a->info->client_ssl_private_key_filepath;
const char *ca_filepath = a->info->client_ssl_ca_filepath;
const char *cipher_list = a->info->client_ssl_cipher_list;
memset(a->info, 0, sizeof(*a->info));
a->info->client_ssl_cert_filepath = cert_filepath;
a->info->client_ssl_private_key_filepath = private_key_filepath;
a->info->client_ssl_ca_filepath = ca_filepath;
a->info->client_ssl_cipher_list = cipher_list;
a->info->options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
lws_init_vhost_client_ssl(a->info, vhost);
}
@ -538,6 +570,9 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
case LEJPVP_KEEPALIVE_TIMEOUT:
a->info->keepalive_timeout = atoi(ctx->buf);
return 0;
case LEJPVP_CLIENT_CIPHERS:
a->info->client_ssl_cipher_list = a->p;
break;
case LEJPVP_CIPHERS:
a->info->ssl_cipher_list = a->p;
break;
@ -613,6 +648,15 @@ lejp_vhosts_cb(struct lejp_ctx *ctx, char reason)
case LEJPVP_ENABLE_CLIENT_SSL:
a->enable_client_ssl = arg_to_bool(ctx->buf);
return 0;
case LEJPVP_CLIENT_SSL_KEY:
a->info->client_ssl_private_key_filepath = a->p;
break;
case LEJPVP_CLIENT_SSL_CERT:
a->info->client_ssl_cert_filepath = a->p;
break;
case LEJPVP_CLIENT_SSL_CA:
a->info->client_ssl_ca_filepath = a->p;
break;
case LEJPVP_NOIPV6:
if (arg_to_bool(ctx->buf))

View file

@ -1870,6 +1870,29 @@ struct lws_context_creation_info {
* succeeded to create.
*/
#ifdef LWS_OPENSSL_SUPPORT
/**< CONTEXT: NULL or struct lws_token_limits pointer which is initialized
* with a token length limit for each possible WSI_TOKEN_ */
const char *client_ssl_private_key_password;
/**< VHOST: NULL or the passphrase needed for the private key */
const char *client_ssl_cert_filepath;
/**< VHOST: If libwebsockets was compiled to use ssl, and you want
* to listen using SSL, set to the filepath to fetch the
* server cert from, otherwise NULL for unencrypted */
const char *client_ssl_private_key_filepath;
/**< VHOST: filepath to private key if wanting SSL mode;
* if this is set to NULL but sll_cert_filepath is set, the
* OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY callback is called
* to allow setting of the private key directly via openSSL
* library calls */
const char *client_ssl_ca_filepath;
/**< VHOST: CA certificate filepath or NULL */
const char *client_ssl_cipher_list;
/**< VHOST: List of valid ciphers to use (eg,
* "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL"
* or you can leave it as NULL to get "DEFAULT" */
#endif
/* Add new things just above here ---^
* This is part of the ABI, don't needlessly break compatibility
*

View file

@ -479,9 +479,9 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
#endif
SSL_CTX_set_options(vhost->ssl_client_ctx,
SSL_OP_CIPHER_SERVER_PREFERENCE);
if (info->ssl_cipher_list)
if (info->client_ssl_cipher_list)
SSL_CTX_set_cipher_list(vhost->ssl_client_ctx,
info->ssl_cipher_list);
info->client_ssl_cipher_list);
#ifdef LWS_SSL_CLIENT_USE_OS_CA_CERTS
if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS))
@ -490,7 +490,7 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
#endif
/* openssl init for cert verification (for client sockets) */
if (!info->ssl_ca_filepath) {
if (!info->client_ssl_ca_filepath) {
if (!SSL_CTX_load_verify_locations(
vhost->ssl_client_ctx, NULL,
LWS_OPENSSL_CLIENT_CERTS))
@ -501,12 +501,12 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
"going to work\n", LWS_OPENSSL_CLIENT_CERTS);
} else
if (!SSL_CTX_load_verify_locations(
vhost->ssl_client_ctx, info->ssl_ca_filepath,
vhost->ssl_client_ctx, info->client_ssl_ca_filepath,
NULL)) {
lwsl_err(
"Unable to load SSL Client certs "
"file from %s -- client ssl isn't "
"going to work\n", info->ssl_ca_filepath);
"going to work\n", info->client_ssl_ca_filepath);
lws_ssl_elaborate_error();
}
else
@ -518,32 +518,32 @@ int lws_context_init_client_ssl(struct lws_context_creation_info *info,
*/
/* support for client-side certificate authentication */
if (info->ssl_cert_filepath) {
if (info->client_ssl_cert_filepath) {
lwsl_notice("%s: doing cert filepath\n", __func__);
n = SSL_CTX_use_certificate_chain_file(vhost->ssl_client_ctx,
info->ssl_cert_filepath);
info->client_ssl_cert_filepath);
if (n < 1) {
lwsl_err("problem %d getting cert '%s'\n", n,
info->ssl_cert_filepath);
info->client_ssl_cert_filepath);
lws_ssl_elaborate_error();
return 1;
}
lwsl_notice("Loaded client cert %s\n", info->ssl_cert_filepath);
lwsl_notice("Loaded client cert %s\n", info->client_ssl_cert_filepath);
}
if (info->ssl_private_key_filepath) {
if (info->client_ssl_private_key_filepath) {
lwsl_notice("%s: doing private key filepath\n", __func__);
lws_ssl_bind_passphrase(vhost->ssl_client_ctx, info);
/* set the private key from KeyFile */
if (SSL_CTX_use_PrivateKey_file(vhost->ssl_client_ctx,
info->ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
info->client_ssl_private_key_filepath, SSL_FILETYPE_PEM) != 1) {
lwsl_err("use_PrivateKey_file '%s'\n",
info->ssl_private_key_filepath);
info->client_ssl_private_key_filepath);
lws_ssl_elaborate_error();
return 1;
}
lwsl_notice("Loaded client cert private key %s\n",
info->ssl_private_key_filepath);
info->client_ssl_private_key_filepath);
/* verify private key */
if (!SSL_CTX_check_private_key(vhost->ssl_client_ctx)) {