summaryrefslogtreecommitdiffstats
path: root/Utilities/cmcurl/lib/vtls/openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmcurl/lib/vtls/openssl.c')
-rw-r--r--Utilities/cmcurl/lib/vtls/openssl.c126
1 files changed, 91 insertions, 35 deletions
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
index f6a4bd3..a487f55 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.c
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -50,9 +50,6 @@
#include "hostcheck.h"
#include "curl_printf.h"
#include <openssl/ssl.h>
-#ifdef HAVE_OPENSSL_ENGINE_H
-#include <openssl/engine.h>
-#endif
#include <openssl/rand.h>
#include <openssl/x509v3.h>
#ifndef OPENSSL_NO_DSA
@@ -72,6 +69,12 @@
#include <openssl/ocsp.h>
#endif
+#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && /* 1.0.0 or later */ \
+ !defined(OPENSSL_NO_ENGINE)
+#define USE_OPENSSL_ENGINE
+#include <openssl/engine.h>
+#endif
+
#include "warnless.h"
#include "non-ascii.h" /* for Curl_convert_from_utf8 prototype */
@@ -83,7 +86,7 @@
#error "OPENSSL_VERSION_NUMBER not defined"
#endif
-#if defined(HAVE_OPENSSL_ENGINE_H)
+#ifdef USE_OPENSSL_ENGINE
#include <openssl/ui.h>
#endif
@@ -166,6 +169,17 @@ static unsigned long OpenSSL_version_num(void)
#define HAVE_KEYLOG_CALLBACK
#endif
+/* Whether SSL_CTX_set_ciphersuites is available.
+ * OpenSSL: supported since 1.1.1 (commit a53b5be6a05)
+ * BoringSSL: no
+ * LibreSSL: no
+ */
+#if ((OPENSSL_VERSION_NUMBER >= 0x10101000L) && \
+ !defined(LIBRESSL_VERSION_NUMBER) && \
+ !defined(OPENSSL_IS_BORINGSSL))
+#define HAVE_SSL_CTX_SET_CIPHERSUITES
+#endif
+
#if defined(LIBRESSL_VERSION_NUMBER)
#define OSSL_PACKAGE "LibreSSL"
#elif defined(OPENSSL_IS_BORINGSSL)
@@ -504,7 +518,7 @@ static int do_file_type(const char *type)
return -1;
}
-#if defined(HAVE_OPENSSL_ENGINE_H)
+#ifdef USE_OPENSSL_ENGINE
/*
* Supply default password to the engine user interface conversation.
* The password is passed by OpenSSL engine from ENGINE_load_private_key()
@@ -544,8 +558,20 @@ static int ssl_ui_writer(UI *ui, UI_STRING *uis)
}
return (UI_method_get_writer(UI_OpenSSL()))(ui, uis);
}
+
+/*
+ * Check if a given string is a PKCS#11 URI
+ */
+static bool is_pkcs11_uri(const char *string)
+{
+ return (string && strncasecompare(string, "pkcs11:", 7));
+}
+
#endif
+static CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
+ const char *engine);
+
static
int cert_stuff(struct connectdata *conn,
SSL_CTX* ctx,
@@ -606,8 +632,18 @@ int cert_stuff(struct connectdata *conn,
}
break;
case SSL_FILETYPE_ENGINE:
-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
+#if defined(USE_OPENSSL_ENGINE) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
{
+ /* Implicitly use pkcs11 engine if none was provided and the
+ * cert_file is a PKCS#11 URI */
+ if(!data->state.engine) {
+ if(is_pkcs11_uri(cert_file)) {
+ if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) {
+ return 0;
+ }
+ }
+ }
+
if(data->state.engine) {
const char *cmd_name = "LOAD_CERT_CTRL";
struct {
@@ -781,9 +817,20 @@ int cert_stuff(struct connectdata *conn,
}
break;
case SSL_FILETYPE_ENGINE:
-#ifdef HAVE_OPENSSL_ENGINE_H
+#ifdef USE_OPENSSL_ENGINE
{ /* XXXX still needs some work */
EVP_PKEY *priv_key = NULL;
+
+ /* Implicitly use pkcs11 engine if none was provided and the
+ * key_file is a PKCS#11 URI */
+ if(!data->state.engine) {
+ if(is_pkcs11_uri(key_file)) {
+ if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) {
+ return 0;
+ }
+ }
+ }
+
if(data->state.engine) {
UI_METHOD *ui_method =
UI_create_method((char *)"curl user interface");
@@ -1088,7 +1135,7 @@ static int Curl_ossl_check_cxn(struct connectdata *conn)
static CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
const char *engine)
{
-#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+#ifdef USE_OPENSSL_ENGINE
ENGINE *e;
#if OPENSSL_VERSION_NUMBER >= 0x00909000L
@@ -1133,7 +1180,7 @@ static CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
*/
static CURLcode Curl_ossl_set_engine_default(struct Curl_easy *data)
{
-#ifdef HAVE_OPENSSL_ENGINE_H
+#ifdef USE_OPENSSL_ENGINE
if(data->state.engine) {
if(ENGINE_set_default(data->state.engine, ENGINE_METHOD_ALL) > 0) {
infof(data, "set default crypto engine '%s'\n",
@@ -1156,7 +1203,7 @@ static CURLcode Curl_ossl_set_engine_default(struct Curl_easy *data)
static struct curl_slist *Curl_ossl_engines_list(struct Curl_easy *data)
{
struct curl_slist *list = NULL;
-#if defined(USE_OPENSSL) && defined(HAVE_OPENSSL_ENGINE_H)
+#ifdef USE_OPENSSL_ENGINE
struct curl_slist *beg;
ENGINE *e;
@@ -1312,7 +1359,7 @@ static void Curl_ossl_session_free(void *ptr)
*/
static void Curl_ossl_close_all(struct Curl_easy *data)
{
-#ifdef HAVE_OPENSSL_ENGINE_H
+#ifdef USE_OPENSSL_ENGINE
if(data->state.engine) {
ENGINE_finish(data->state.engine);
ENGINE_free(data->state.engine);
@@ -1922,7 +1969,15 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
}
else
#endif
- {
+ if(content_type == SSL3_RT_CHANGE_CIPHER_SPEC) {
+ msg_type = *(char *)buf;
+ msg_name = "Change cipher spec";
+ }
+ else if(content_type == SSL3_RT_ALERT) {
+ msg_type = (((char *)buf)[0] << 8) + ((char *)buf)[1];
+ msg_name = SSL_alert_desc_string_long(msg_type);
+ }
+ else {
msg_type = *(char *)buf;
msg_name = ssl_msg_type(ssl_ver, msg_type);
}
@@ -1931,12 +1986,12 @@ static void ssl_tls_trace(int direction, int ssl_ver, int content_type,
verstr, direction?"OUT":"IN",
tls_rt_name, msg_name, msg_type);
if(0 <= txt_len && (unsigned)txt_len < sizeof(ssl_buf)) {
- Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len, NULL);
+ Curl_debug(data, CURLINFO_TEXT, ssl_buf, (size_t)txt_len);
}
}
Curl_debug(data, (direction == 1) ? CURLINFO_SSL_DATA_OUT :
- CURLINFO_SSL_DATA_IN, (char *)buf, len, NULL);
+ CURLINFO_SSL_DATA_IN, (char *)buf, len);
(void) ssl;
}
#endif
@@ -2064,10 +2119,6 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
long ssl_version = SSL_CONN_CONFIG(version);
long ssl_version_max = SSL_CONN_CONFIG(version_max);
- if(ssl_version_max == CURL_SSLVERSION_MAX_NONE) {
- ssl_version_max = ssl_version << 16;
- }
-
switch(ssl_version) {
case CURL_SSLVERSION_TLSv1_3:
#ifdef TLS1_3_VERSION
@@ -2099,8 +2150,7 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
#endif
/* FALLTHROUGH */
case CURL_SSLVERSION_TLSv1_0:
- *ctx_options |= SSL_OP_NO_SSLv2;
- *ctx_options |= SSL_OP_NO_SSLv3;
+ case CURL_SSLVERSION_TLSv1:
break;
}
@@ -2116,12 +2166,12 @@ set_ssl_version_min_max(long *ctx_options, struct connectdata *conn,
#endif
/* FALLTHROUGH */
case CURL_SSLVERSION_MAX_TLSv1_2:
- case CURL_SSLVERSION_MAX_DEFAULT:
#ifdef TLS1_3_VERSION
*ctx_options |= SSL_OP_NO_TLSv1_3;
#endif
break;
case CURL_SSLVERSION_MAX_TLSv1_3:
+ case CURL_SSLVERSION_MAX_DEFAULT:
#ifdef TLS1_3_VERSION
break;
#else
@@ -2305,11 +2355,6 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
switch(ssl_version) {
case CURL_SSLVERSION_SSLv3:
-#ifdef USE_TLS_SRP
- if(ssl_authtype == CURL_TLSAUTH_SRP) {
- infof(data, "Set version TLSv1.x for SRP authorisation\n");
- }
-#endif
ctx_options |= SSL_OP_NO_SSLv2;
ctx_options |= SSL_OP_NO_TLSv1;
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
@@ -2323,21 +2368,20 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
case CURL_SSLVERSION_DEFAULT:
case CURL_SSLVERSION_TLSv1:
- ctx_options |= SSL_OP_NO_SSLv2;
- ctx_options |= SSL_OP_NO_SSLv3;
- break;
-
case CURL_SSLVERSION_TLSv1_0:
case CURL_SSLVERSION_TLSv1_1:
case CURL_SSLVERSION_TLSv1_2:
case CURL_SSLVERSION_TLSv1_3:
+ /* asking for any TLS version as the minimum, means no SSL versions
+ allowed */
+ ctx_options |= SSL_OP_NO_SSLv2;
+ ctx_options |= SSL_OP_NO_SSLv3;
result = set_ssl_version_min_max(&ctx_options, conn, sockindex);
if(result != CURLE_OK)
return result;
break;
case CURL_SSLVERSION_SSLv2:
-#ifndef OPENSSL_NO_SSL2
ctx_options |= SSL_OP_NO_SSLv3;
ctx_options |= SSL_OP_NO_TLSv1;
#if OPENSSL_VERSION_NUMBER >= 0x1000100FL
@@ -2348,10 +2392,6 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
#endif
#endif
break;
-#else
- failf(data, OSSL_PACKAGE " was built without SSLv2 support");
- return CURLE_NOT_BUILT_IN;
-#endif
default:
failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
@@ -2414,6 +2454,19 @@ static CURLcode ossl_connect_step1(struct connectdata *conn, int sockindex)
infof(data, "Cipher selection: %s\n", ciphers);
}
+#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
+ {
+ char *ciphers13 = SSL_CONN_CONFIG(cipher_list13);
+ if(ciphers13) {
+ if(!SSL_CTX_set_ciphersuites(BACKEND->ctx, ciphers13)) {
+ failf(data, "failed setting TLS 1.3 cipher suite: %s", ciphers);
+ return CURLE_SSL_CIPHER;
+ }
+ infof(data, "TLS 1.3 cipher selection: %s\n", ciphers13);
+ }
+ }
+#endif
+
#ifdef USE_TLS_SRP
if(ssl_authtype == CURL_TLSAUTH_SRP) {
char * const ssl_username = SSL_SET_OPTION(username);
@@ -3754,6 +3807,9 @@ const struct Curl_ssl Curl_ssl_openssl = {
SSLSUPP_CERTINFO |
SSLSUPP_PINNEDPUBKEY |
SSLSUPP_SSL_CTX |
+#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
+ SSLSUPP_TLS13_CIPHERSUITES |
+#endif
SSLSUPP_HTTPS_PROXY,
sizeof(struct ssl_backend_data),