summaryrefslogtreecommitdiff
path: root/src/openvpn/ssl_openssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/ssl_openssl.c')
-rw-r--r--src/openvpn/ssl_openssl.c2180
1 files changed, 1185 insertions, 995 deletions
diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c
index 4f472ff..eae1e22 100644
--- a/src/openvpn/ssl_openssl.c
+++ b/src/openvpn/ssl_openssl.c
@@ -5,8 +5,8 @@
* packet encryption, packet authentication, and
* packet compression.
*
- * Copyright (C) 2002-2010 OpenVPN Technologies, Inc. <sales@openvpn.net>
- * Copyright (C) 2010 Fox Crypto B.V. <openvpn@fox-it.com>
+ * Copyright (C) 2002-2017 OpenVPN Technologies, Inc. <sales@openvpn.net>
+ * Copyright (C) 2010-2017 Fox Crypto B.V. <openvpn@fox-it.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2
@@ -71,97 +71,104 @@ int mydata_index; /* GLOBAL */
void
tls_init_lib()
{
- SSL_library_init();
+ SSL_library_init();
#ifndef ENABLE_SMALL
- SSL_load_error_strings();
+ SSL_load_error_strings();
#endif
- OpenSSL_add_all_algorithms ();
+ OpenSSL_add_all_algorithms();
- mydata_index = SSL_get_ex_new_index(0, "struct session *", NULL, NULL, NULL);
- ASSERT (mydata_index >= 0);
+ mydata_index = SSL_get_ex_new_index(0, "struct session *", NULL, NULL, NULL);
+ ASSERT(mydata_index >= 0);
}
void
tls_free_lib()
{
- EVP_cleanup();
+ EVP_cleanup();
#ifndef ENABLE_SMALL
- ERR_free_strings();
+ ERR_free_strings();
#endif
}
void
tls_clear_error()
{
- ERR_clear_error ();
+ ERR_clear_error();
}
void
tls_ctx_server_new(struct tls_root_ctx *ctx)
{
- ASSERT(NULL != ctx);
+ ASSERT(NULL != ctx);
- ctx->ctx = SSL_CTX_new (SSLv23_server_method ());
+ ctx->ctx = SSL_CTX_new(SSLv23_server_method());
- if (ctx->ctx == NULL)
- crypto_msg (M_FATAL, "SSL_CTX_new SSLv23_server_method");
+ if (ctx->ctx == NULL)
+ {
+ crypto_msg(M_FATAL, "SSL_CTX_new SSLv23_server_method");
+ }
}
void
tls_ctx_client_new(struct tls_root_ctx *ctx)
{
- ASSERT(NULL != ctx);
+ ASSERT(NULL != ctx);
- ctx->ctx = SSL_CTX_new (SSLv23_client_method ());
+ ctx->ctx = SSL_CTX_new(SSLv23_client_method());
- if (ctx->ctx == NULL)
- crypto_msg (M_FATAL, "SSL_CTX_new SSLv23_client_method");
+ if (ctx->ctx == NULL)
+ {
+ crypto_msg(M_FATAL, "SSL_CTX_new SSLv23_client_method");
+ }
}
void
tls_ctx_free(struct tls_root_ctx *ctx)
{
- ASSERT(NULL != ctx);
- if (NULL != ctx->ctx)
- SSL_CTX_free (ctx->ctx);
- ctx->ctx = NULL;
+ ASSERT(NULL != ctx);
+ if (NULL != ctx->ctx)
+ {
+ SSL_CTX_free(ctx->ctx);
+ }
+ ctx->ctx = NULL;
}
-bool tls_ctx_initialised(struct tls_root_ctx *ctx)
+bool
+tls_ctx_initialised(struct tls_root_ctx *ctx)
{
- ASSERT(NULL != ctx);
- return NULL != ctx->ctx;
+ ASSERT(NULL != ctx);
+ return NULL != ctx->ctx;
}
void
key_state_export_keying_material(struct key_state_ssl *ssl,
struct tls_session *session)
{
- if (session->opt->ekm_size > 0)
+ if (session->opt->ekm_size > 0)
{
#if (OPENSSL_VERSION_NUMBER >= 0x10001000)
- unsigned int size = session->opt->ekm_size;
- struct gc_arena gc = gc_new();
- unsigned char* ekm = (unsigned char*) gc_malloc(size, true, &gc);
-
- if (SSL_export_keying_material(ssl->ssl, ekm, size,
- session->opt->ekm_label, session->opt->ekm_label_size, NULL, 0, 0))
- {
- unsigned int len = (size * 2) + 2;
-
- const char *key = format_hex_ex (ekm, size, len, 0, NULL, &gc);
- setenv_str (session->opt->es, "exported_keying_material", key);
-
- dmsg(D_TLS_DEBUG_MED, "%s: exported keying material: %s",
- __func__, key);
- }
- else
- {
- msg (M_WARN, "WARNING: Export keying material failed!");
- setenv_del (session->opt->es, "exported_keying_material");
- }
- gc_free(&gc);
-#endif
+ unsigned int size = session->opt->ekm_size;
+ struct gc_arena gc = gc_new();
+ unsigned char *ekm = (unsigned char *) gc_malloc(size, true, &gc);
+
+ if (SSL_export_keying_material(ssl->ssl, ekm, size,
+ session->opt->ekm_label, session->opt->ekm_label_size, NULL, 0, 0))
+ {
+ unsigned int len = (size * 2) + 2;
+
+ const char *key = format_hex_ex(ekm, size, len, 0, NULL, &gc);
+ setenv_str(session->opt->es, "exported_keying_material", key);
+
+ dmsg(D_TLS_DEBUG_MED, "%s: exported keying material: %s",
+ __func__, key);
+ }
+ else
+ {
+ msg(M_WARN, "WARNING: Export keying material failed!");
+ setenv_del(session->opt->es, "exported_keying_material");
+ }
+ gc_free(&gc);
+#endif /* if (OPENSSL_VERSION_NUMBER >= 0x10001000) */
}
}
@@ -173,21 +180,21 @@ key_state_export_keying_material(struct key_state_ssl *ssl,
#define INFO_CALLBACK_SSL_CONST const
#endif
static void
-info_callback (INFO_CALLBACK_SSL_CONST SSL * s, int where, int ret)
+info_callback(INFO_CALLBACK_SSL_CONST SSL *s, int where, int ret)
{
- if (where & SSL_CB_LOOP)
+ if (where & SSL_CB_LOOP)
{
- dmsg (D_HANDSHAKE_VERBOSE, "SSL state (%s): %s",
- where & SSL_ST_CONNECT ? "connect" :
- where & SSL_ST_ACCEPT ? "accept" :
- "undefined", SSL_state_string_long (s));
+ dmsg(D_HANDSHAKE_VERBOSE, "SSL state (%s): %s",
+ where & SSL_ST_CONNECT ? "connect" :
+ where &SSL_ST_ACCEPT ? "accept" :
+ "undefined", SSL_state_string_long(s));
}
- else if (where & SSL_CB_ALERT)
+ else if (where & SSL_CB_ALERT)
{
- dmsg (D_HANDSHAKE_VERBOSE, "SSL alert (%s): %s: %s",
- where & SSL_CB_READ ? "read" : "write",
- SSL_alert_type_string_long (ret),
- SSL_alert_desc_string_long (ret));
+ dmsg(D_HANDSHAKE_VERBOSE, "SSL alert (%s): %s: %s",
+ where & SSL_CB_READ ? "read" : "write",
+ SSL_alert_type_string_long(ret),
+ SSL_alert_desc_string_long(ret));
}
}
@@ -200,632 +207,732 @@ int
tls_version_max(void)
{
#if defined(SSL_OP_NO_TLSv1_2)
- return TLS_VER_1_2;
+ return TLS_VER_1_2;
#elif defined(SSL_OP_NO_TLSv1_1)
- return TLS_VER_1_1;
+ return TLS_VER_1_1;
#else
- return TLS_VER_1_0;
+ return TLS_VER_1_0;
#endif
}
void
-tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
+tls_ctx_set_options(struct tls_root_ctx *ctx, unsigned int ssl_flags)
{
- ASSERT(NULL != ctx);
-
- /* default certificate verification flags */
- int flags = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
+ ASSERT(NULL != ctx);
- /* process SSL options including minimum TLS version we will accept from peer */
- {
- long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
- int tls_ver_max = TLS_VER_UNSPEC;
- const int tls_ver_min =
- (ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) & SSLF_TLS_VERSION_MIN_MASK;
+ /* default certificate verification flags */
+ int flags = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
- tls_ver_max =
- (ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & SSLF_TLS_VERSION_MAX_MASK;
- if (tls_ver_max <= TLS_VER_UNSPEC)
- tls_ver_max = tls_version_max();
+ /* process SSL options including minimum TLS version we will accept from peer */
+ {
+ long sslopt = SSL_OP_SINGLE_DH_USE | SSL_OP_NO_TICKET | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
+ int tls_ver_max = TLS_VER_UNSPEC;
+ const int tls_ver_min =
+ (ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) & SSLF_TLS_VERSION_MIN_MASK;
+
+ tls_ver_max =
+ (ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) & SSLF_TLS_VERSION_MAX_MASK;
+ if (tls_ver_max <= TLS_VER_UNSPEC)
+ {
+ tls_ver_max = tls_version_max();
+ }
- if (tls_ver_min > TLS_VER_1_0 || tls_ver_max < TLS_VER_1_0)
- sslopt |= SSL_OP_NO_TLSv1;
+ if (tls_ver_min > TLS_VER_1_0 || tls_ver_max < TLS_VER_1_0)
+ {
+ sslopt |= SSL_OP_NO_TLSv1;
+ }
#ifdef SSL_OP_NO_TLSv1_1
- if (tls_ver_min > TLS_VER_1_1 || tls_ver_max < TLS_VER_1_1)
- sslopt |= SSL_OP_NO_TLSv1_1;
+ if (tls_ver_min > TLS_VER_1_1 || tls_ver_max < TLS_VER_1_1)
+ {
+ sslopt |= SSL_OP_NO_TLSv1_1;
+ }
#endif
#ifdef SSL_OP_NO_TLSv1_2
- if (tls_ver_min > TLS_VER_1_2 || tls_ver_max < TLS_VER_1_2)
- sslopt |= SSL_OP_NO_TLSv1_2;
+ if (tls_ver_min > TLS_VER_1_2 || tls_ver_max < TLS_VER_1_2)
+ {
+ sslopt |= SSL_OP_NO_TLSv1_2;
+ }
#endif
#ifdef SSL_OP_NO_COMPRESSION
- /* Disable compression - flag not available in OpenSSL 0.9.8 */
- sslopt |= SSL_OP_NO_COMPRESSION;
+ /* Disable compression - flag not available in OpenSSL 0.9.8 */
+ sslopt |= SSL_OP_NO_COMPRESSION;
#endif
- SSL_CTX_set_options (ctx->ctx, sslopt);
- }
+ SSL_CTX_set_options(ctx->ctx, sslopt);
+ }
#ifdef SSL_MODE_RELEASE_BUFFERS
- SSL_CTX_set_mode (ctx->ctx, SSL_MODE_RELEASE_BUFFERS);
+ SSL_CTX_set_mode(ctx->ctx, SSL_MODE_RELEASE_BUFFERS);
#endif
- SSL_CTX_set_session_cache_mode (ctx->ctx, SSL_SESS_CACHE_OFF);
- SSL_CTX_set_default_passwd_cb (ctx->ctx, pem_password_callback);
+ SSL_CTX_set_session_cache_mode(ctx->ctx, SSL_SESS_CACHE_OFF);
+ SSL_CTX_set_default_passwd_cb(ctx->ctx, pem_password_callback);
- /* Require peer certificate verification */
+ /* Require peer certificate verification */
#if P2MP_SERVER
- if (ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)
+ if (ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)
{
- flags = 0;
+ flags = 0;
}
- else if (ssl_flags & SSLF_CLIENT_CERT_OPTIONAL)
+ else if (ssl_flags & SSLF_CLIENT_CERT_OPTIONAL)
{
- flags = SSL_VERIFY_PEER;
+ flags = SSL_VERIFY_PEER;
}
#endif
- SSL_CTX_set_verify (ctx->ctx, flags, verify_callback);
+ SSL_CTX_set_verify(ctx->ctx, flags, verify_callback);
- SSL_CTX_set_info_callback (ctx->ctx, info_callback);
+ SSL_CTX_set_info_callback(ctx->ctx, info_callback);
}
void
tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
{
- if (ciphers == NULL)
+ if (ciphers == NULL)
{
- /* Use sane default TLS cipher list */
- if(!SSL_CTX_set_cipher_list(ctx->ctx,
- /* Use openssl's default list as a basis */
- "DEFAULT"
- /* Disable export ciphers and openssl's 'low' and 'medium' ciphers */
- ":!EXP:!LOW:!MEDIUM"
- /* Disable static (EC)DH keys (no forward secrecy) */
- ":!kDH:!kECDH"
- /* Disable DSA private keys */
- ":!DSS"
- /* Disable unsupported TLS modes */
- ":!PSK:!SRP:!kRSA"))
- crypto_msg (M_FATAL, "Failed to set default TLS cipher list.");
- return;
+ /* Use sane default TLS cipher list */
+ if (!SSL_CTX_set_cipher_list(ctx->ctx,
+ /* Use openssl's default list as a basis */
+ "DEFAULT"
+ /* Disable export ciphers and openssl's 'low' and 'medium' ciphers */
+ ":!EXP:!LOW:!MEDIUM"
+ /* Disable static (EC)DH keys (no forward secrecy) */
+ ":!kDH:!kECDH"
+ /* Disable DSA private keys */
+ ":!DSS"
+ /* Disable unsupported TLS modes */
+ ":!PSK:!SRP:!kRSA"))
+ {
+ crypto_msg(M_FATAL, "Failed to set default TLS cipher list.");
+ }
+ return;
}
- /* Parse supplied cipher list and pass on to OpenSSL */
- size_t begin_of_cipher, end_of_cipher;
+ /* Parse supplied cipher list and pass on to OpenSSL */
+ size_t begin_of_cipher, end_of_cipher;
+
+ const char *current_cipher;
+ size_t current_cipher_len;
- const char *current_cipher;
- size_t current_cipher_len;
+ const tls_cipher_name_pair *cipher_pair;
- const tls_cipher_name_pair *cipher_pair;
+ char openssl_ciphers[4096];
+ size_t openssl_ciphers_len = 0;
+ openssl_ciphers[0] = '\0';
- char openssl_ciphers[4096];
- size_t openssl_ciphers_len = 0;
- openssl_ciphers[0] = '\0';
+ ASSERT(NULL != ctx);
- ASSERT(NULL != ctx);
+ /* Translate IANA cipher suite names to OpenSSL names */
+ begin_of_cipher = end_of_cipher = 0;
+ for (; begin_of_cipher < strlen(ciphers); begin_of_cipher = end_of_cipher) {
+ end_of_cipher += strcspn(&ciphers[begin_of_cipher], ":");
+ cipher_pair = tls_get_cipher_name_pair(&ciphers[begin_of_cipher], end_of_cipher - begin_of_cipher);
+
+ if (NULL == cipher_pair)
+ {
+ /* No translation found, use original */
+ current_cipher = &ciphers[begin_of_cipher];
+ current_cipher_len = end_of_cipher - begin_of_cipher;
+
+ /* Issue warning on missing translation */
+ /* %.*s format specifier expects length of type int, so guarantee */
+ /* that length is small enough and cast to int. */
+ msg(D_LOW, "No valid translation found for TLS cipher '%.*s'",
+ constrain_int(current_cipher_len, 0, 256), current_cipher);
+ }
+ else
+ {
+ /* Use OpenSSL name */
+ current_cipher = cipher_pair->openssl_name;
+ current_cipher_len = strlen(current_cipher);
- // Translate IANA cipher suite names to OpenSSL names
- begin_of_cipher = end_of_cipher = 0;
- for (; begin_of_cipher < strlen(ciphers); begin_of_cipher = end_of_cipher) {
- end_of_cipher += strcspn(&ciphers[begin_of_cipher], ":");
- cipher_pair = tls_get_cipher_name_pair(&ciphers[begin_of_cipher], end_of_cipher - begin_of_cipher);
+ if (end_of_cipher - begin_of_cipher == current_cipher_len
+ && 0 != memcmp(&ciphers[begin_of_cipher], cipher_pair->iana_name,
+ end_of_cipher - begin_of_cipher))
+ {
+ /* Non-IANA name used, show warning */
+ msg(M_WARN, "Deprecated TLS cipher name '%s', please use IANA name '%s'", cipher_pair->openssl_name, cipher_pair->iana_name);
+ }
+ }
- if (NULL == cipher_pair)
+ /* Make sure new cipher name fits in cipher string */
+ if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) < current_cipher_len)
{
- // No translation found, use original
- current_cipher = &ciphers[begin_of_cipher];
- current_cipher_len = end_of_cipher - begin_of_cipher;
-
- // Issue warning on missing translation
- // %.*s format specifier expects length of type int, so guarantee
- // that length is small enough and cast to int.
- msg (D_LOW, "No valid translation found for TLS cipher '%.*s'",
- constrain_int(current_cipher_len, 0, 256), current_cipher);
+ msg(M_FATAL,
+ "Failed to set restricted TLS cipher list, too long (>%d).",
+ (int)sizeof(openssl_ciphers)-1);
}
- else
- {
- // Use OpenSSL name
- current_cipher = cipher_pair->openssl_name;
- current_cipher_len = strlen(current_cipher);
-
- if (end_of_cipher - begin_of_cipher == current_cipher_len &&
- 0 != memcmp (&ciphers[begin_of_cipher], cipher_pair->iana_name,
- end_of_cipher - begin_of_cipher))
- {
- // Non-IANA name used, show warning
- msg (M_WARN, "Deprecated TLS cipher name '%s', please use IANA name '%s'", cipher_pair->openssl_name, cipher_pair->iana_name);
- }
- }
-
- // Make sure new cipher name fits in cipher string
- if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) < current_cipher_len)
- {
- msg (M_FATAL,
- "Failed to set restricted TLS cipher list, too long (>%d).",
- (int)sizeof(openssl_ciphers)-1);
- }
-
- // Concatenate cipher name to OpenSSL cipher string
- memcpy(&openssl_ciphers[openssl_ciphers_len], current_cipher, current_cipher_len);
- openssl_ciphers_len += current_cipher_len;
- openssl_ciphers[openssl_ciphers_len] = ':';
- openssl_ciphers_len++;
-
- end_of_cipher++;
- }
-
- if (openssl_ciphers_len > 0)
- openssl_ciphers[openssl_ciphers_len-1] = '\0';
-
- // Set OpenSSL cipher list
- if(!SSL_CTX_set_cipher_list(ctx->ctx, openssl_ciphers))
- crypto_msg (M_FATAL, "Failed to set restricted TLS cipher list: %s", openssl_ciphers);
+
+ /* Concatenate cipher name to OpenSSL cipher string */
+ memcpy(&openssl_ciphers[openssl_ciphers_len], current_cipher, current_cipher_len);
+ openssl_ciphers_len += current_cipher_len;
+ openssl_ciphers[openssl_ciphers_len] = ':';
+ openssl_ciphers_len++;
+
+ end_of_cipher++;
+ }
+
+ if (openssl_ciphers_len > 0)
+ {
+ openssl_ciphers[openssl_ciphers_len-1] = '\0';
+ }
+
+ /* Set OpenSSL cipher list */
+ if (!SSL_CTX_set_cipher_list(ctx->ctx, openssl_ciphers))
+ {
+ crypto_msg(M_FATAL, "Failed to set restricted TLS cipher list: %s", openssl_ciphers);
+ }
}
void
-tls_ctx_check_cert_time (const struct tls_root_ctx *ctx)
+tls_ctx_check_cert_time(const struct tls_root_ctx *ctx)
{
- int ret;
- const X509 *cert;
+ int ret;
+ const X509 *cert;
- ASSERT (ctx);
+ ASSERT(ctx);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L && !defined(LIBRESSL_VERSION_NUMBER)
- /* OpenSSL 1.0.2 and up */
- cert = SSL_CTX_get0_certificate (ctx->ctx);
+ /* OpenSSL 1.0.2 and up */
+ cert = SSL_CTX_get0_certificate(ctx->ctx);
#else
- /* OpenSSL 1.0.1 and earlier need an SSL object to get at the certificate */
- SSL *ssl = SSL_new (ctx->ctx);
- cert = SSL_get_certificate (ssl);
+ /* OpenSSL 1.0.1 and earlier need an SSL object to get at the certificate */
+ SSL *ssl = SSL_new(ctx->ctx);
+ cert = SSL_get_certificate(ssl);
#endif
- if (cert == NULL)
+ if (cert == NULL)
{
- goto cleanup; /* Nothing to check if there is no certificate */
+ goto cleanup; /* Nothing to check if there is no certificate */
}
- ret = X509_cmp_time (X509_get_notBefore (cert), NULL);
- if (ret == 0)
+ ret = X509_cmp_time(X509_get_notBefore(cert), NULL);
+ if (ret == 0)
{
- msg (D_TLS_DEBUG_MED, "Failed to read certificate notBefore field.");
+ msg(D_TLS_DEBUG_MED, "Failed to read certificate notBefore field.");
}
- if (ret > 0)
+ if (ret > 0)
{
- msg (M_WARN, "WARNING: Your certificate is not yet valid!");
+ msg(M_WARN, "WARNING: Your certificate is not yet valid!");
}
- ret = X509_cmp_time (X509_get_notAfter (cert), NULL);
- if (ret == 0)
+ ret = X509_cmp_time(X509_get_notAfter(cert), NULL);
+ if (ret == 0)
{
- msg (D_TLS_DEBUG_MED, "Failed to read certificate notAfter field.");
+ msg(D_TLS_DEBUG_MED, "Failed to read certificate notAfter field.");
}
- if (ret < 0)
+ if (ret < 0)
{
- msg (M_WARN, "WARNING: Your certificate has expired!");
+ msg(M_WARN, "WARNING: Your certificate has expired!");
}
cleanup:
#if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER)
- SSL_free (ssl);
+ SSL_free(ssl);
#endif
- return;
+ return;
}
void
-tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file,
- const char *dh_file_inline
- )
+tls_ctx_load_dh_params(struct tls_root_ctx *ctx, const char *dh_file,
+ const char *dh_file_inline
+ )
{
- DH *dh;
- BIO *bio;
+ DH *dh;
+ BIO *bio;
- ASSERT(NULL != ctx);
+ ASSERT(NULL != ctx);
- if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_file_inline)
+ if (!strcmp(dh_file, INLINE_FILE_TAG) && dh_file_inline)
{
- if (!(bio = BIO_new_mem_buf ((char *)dh_file_inline, -1)))
- crypto_msg (M_FATAL, "Cannot open memory BIO for inline DH parameters");
+ if (!(bio = BIO_new_mem_buf((char *)dh_file_inline, -1)))
+ {
+ crypto_msg(M_FATAL, "Cannot open memory BIO for inline DH parameters");
+ }
}
- else
+ else
{
- /* Get Diffie Hellman Parameters */
- if (!(bio = BIO_new_file (dh_file, "r")))
- crypto_msg (M_FATAL, "Cannot open %s for DH parameters", dh_file);
+ /* Get Diffie Hellman Parameters */
+ if (!(bio = BIO_new_file(dh_file, "r")))
+ {
+ crypto_msg(M_FATAL, "Cannot open %s for DH parameters", dh_file);
+ }
}
- dh = PEM_read_bio_DHparams (bio, NULL, NULL, NULL);
- BIO_free (bio);
+ dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
+ BIO_free(bio);
- if (!dh)
- crypto_msg (M_FATAL, "Cannot load DH parameters from %s", dh_file);
- if (!SSL_CTX_set_tmp_dh (ctx->ctx, dh))
- crypto_msg (M_FATAL, "SSL_CTX_set_tmp_dh");
+ if (!dh)
+ {
+ crypto_msg(M_FATAL, "Cannot load DH parameters from %s", dh_file);
+ }
+ if (!SSL_CTX_set_tmp_dh(ctx->ctx, dh))
+ {
+ crypto_msg(M_FATAL, "SSL_CTX_set_tmp_dh");
+ }
- msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with %d bit key",
- 8 * DH_size (dh));
+ msg(D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with %d bit key",
+ 8 * DH_size(dh));
- DH_free (dh);
+ DH_free(dh);
}
void
-tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name
- )
+tls_ctx_load_ecdh_params(struct tls_root_ctx *ctx, const char *curve_name
+ )
{
#ifndef OPENSSL_NO_EC
- int nid = NID_undef;
- EC_KEY *ecdh = NULL;
- const char *sname = NULL;
+ int nid = NID_undef;
+ EC_KEY *ecdh = NULL;
+ const char *sname = NULL;
- /* Generate a new ECDH key for each SSL session (for non-ephemeral ECDH) */
- SSL_CTX_set_options(ctx->ctx, SSL_OP_SINGLE_ECDH_USE);
+ /* Generate a new ECDH key for each SSL session (for non-ephemeral ECDH) */
+ SSL_CTX_set_options(ctx->ctx, SSL_OP_SINGLE_ECDH_USE);
#if OPENSSL_VERSION_NUMBER >= 0x10002000L
- /* OpenSSL 1.0.2 and newer can automatically handle ECDH parameter loading */
- if (NULL == curve_name) {
- SSL_CTX_set_ecdh_auto(ctx->ctx, 1);
- return;
- }
+ /* OpenSSL 1.0.2 and newer can automatically handle ECDH parameter loading */
+ if (NULL == curve_name)
+ {
+ SSL_CTX_set_ecdh_auto(ctx->ctx, 1);
+ return;
+ }
#endif
- /* For older OpenSSL, we'll have to do the parameter loading on our own */
- if (curve_name != NULL)
+ /* For older OpenSSL, we'll have to do the parameter loading on our own */
+ if (curve_name != NULL)
{
- /* Use user supplied curve if given */
- msg (D_TLS_DEBUG, "Using user specified ECDH curve (%s)", curve_name);
- nid = OBJ_sn2nid(curve_name);
+ /* Use user supplied curve if given */
+ msg(D_TLS_DEBUG, "Using user specified ECDH curve (%s)", curve_name);
+ nid = OBJ_sn2nid(curve_name);
}
- else
+ else
{
- /* Extract curve from key */
- EC_KEY *eckey = NULL;
- const EC_GROUP *ecgrp = NULL;
- EVP_PKEY *pkey = NULL;
+ /* Extract curve from key */
+ EC_KEY *eckey = NULL;
+ const EC_GROUP *ecgrp = NULL;
+ EVP_PKEY *pkey = NULL;
- /* Little hack to get private key ref from SSL_CTX, yay OpenSSL... */
- SSL ssl;
- ssl.cert = ctx->ctx->cert;
- pkey = SSL_get_privatekey(&ssl);
+ /* Little hack to get private key ref from SSL_CTX, yay OpenSSL... */
+ SSL ssl;
+ ssl.cert = ctx->ctx->cert;
+ pkey = SSL_get_privatekey(&ssl);
- msg (D_TLS_DEBUG, "Extracting ECDH curve from private key");
+ msg(D_TLS_DEBUG, "Extracting ECDH curve from private key");
- if (pkey != NULL && (eckey = EVP_PKEY_get1_EC_KEY(pkey)) != NULL &&
- (ecgrp = EC_KEY_get0_group(eckey)) != NULL)
- nid = EC_GROUP_get_curve_name(ecgrp);
+ if (pkey != NULL && (eckey = EVP_PKEY_get1_EC_KEY(pkey)) != NULL
+ && (ecgrp = EC_KEY_get0_group(eckey)) != NULL)
+ {
+ nid = EC_GROUP_get_curve_name(ecgrp);
+ }
}
- /* Translate NID back to name , just for kicks */
- sname = OBJ_nid2sn(nid);
- if (sname == NULL) sname = "(Unknown)";
+ /* Translate NID back to name , just for kicks */
+ sname = OBJ_nid2sn(nid);
+ if (sname == NULL)
+ {
+ sname = "(Unknown)";
+ }
- /* Create new EC key and set as ECDH key */
- if (NID_undef == nid || NULL == (ecdh = EC_KEY_new_by_curve_name(nid)))
+ /* Create new EC key and set as ECDH key */
+ if (NID_undef == nid || NULL == (ecdh = EC_KEY_new_by_curve_name(nid)))
{
- /* Creating key failed, fall back on sane default */
- ecdh = EC_KEY_new_by_curve_name(NID_secp384r1);
- const char *source = (NULL == curve_name) ?
- "extract curve from certificate" : "use supplied curve";
- msg (D_TLS_DEBUG_LOW,
- "Failed to %s (%s), using secp384r1 instead.", source, sname);
- sname = OBJ_nid2sn(NID_secp384r1);
+ /* Creating key failed, fall back on sane default */
+ ecdh = EC_KEY_new_by_curve_name(NID_secp384r1);
+ const char *source = (NULL == curve_name) ?
+ "extract curve from certificate" : "use supplied curve";
+ msg(D_TLS_DEBUG_LOW,
+ "Failed to %s (%s), using secp384r1 instead.", source, sname);
+ sname = OBJ_nid2sn(NID_secp384r1);
}
- if (!SSL_CTX_set_tmp_ecdh(ctx->ctx, ecdh))
- crypto_msg (M_FATAL, "SSL_CTX_set_tmp_ecdh: cannot add curve");
+ if (!SSL_CTX_set_tmp_ecdh(ctx->ctx, ecdh))
+ {
+ crypto_msg(M_FATAL, "SSL_CTX_set_tmp_ecdh: cannot add curve");
+ }
- msg (D_TLS_DEBUG_LOW, "ECDH curve %s added", sname);
+ msg(D_TLS_DEBUG_LOW, "ECDH curve %s added", sname);
- EC_KEY_free(ecdh);
-#else
- msg (M_DEBUG, "Your OpenSSL library was built without elliptic curve support."
- " Skipping ECDH parameter loading.");
+ EC_KEY_free(ecdh);
+#else /* ifndef OPENSSL_NO_EC */
+ msg(M_DEBUG, "Your OpenSSL library was built without elliptic curve support."
+ " Skipping ECDH parameter loading.");
#endif /* OPENSSL_NO_EC */
}
int
tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
- const char *pkcs12_file_inline,
- bool load_ca_file
- )
+ const char *pkcs12_file_inline,
+ bool load_ca_file
+ )
{
- FILE *fp;
- EVP_PKEY *pkey;
- X509 *cert;
- STACK_OF(X509) *ca = NULL;
- PKCS12 *p12;
- int i;
- char password[256];
-
- ASSERT(NULL != ctx);
-
- if (!strcmp (pkcs12_file, INLINE_FILE_TAG) && pkcs12_file_inline)
- {
- BIO *b64 = BIO_new(BIO_f_base64());
- BIO *bio = BIO_new_mem_buf((void *) pkcs12_file_inline,
- (int) strlen(pkcs12_file_inline));
- ASSERT(b64 && bio);
- BIO_push(b64, bio);
- p12 = d2i_PKCS12_bio(b64, NULL);
- if (!p12)
- crypto_msg (M_FATAL, "Error reading inline PKCS#12 file");
- BIO_free(b64);
- BIO_free(bio);
- }
- else
- {
- /* Load the PKCS #12 file */
- if (!(fp = platform_fopen(pkcs12_file, "rb")))
- crypto_msg (M_FATAL, "Error opening file %s", pkcs12_file);
- p12 = d2i_PKCS12_fp(fp, NULL);
- fclose(fp);
- if (!p12)
- crypto_msg (M_FATAL, "Error reading PKCS#12 file %s", pkcs12_file);
- }
-
- /* Parse the PKCS #12 file */
- if (!PKCS12_parse(p12, "", &pkey, &cert, &ca))
- {
- pem_password_callback (password, sizeof(password) - 1, 0, NULL);
- /* Reparse the PKCS #12 file with password */
- ca = NULL;
- if (!PKCS12_parse(p12, password, &pkey, &cert, &ca))
- {
+ FILE *fp;
+ EVP_PKEY *pkey;
+ X509 *cert;
+ STACK_OF(X509) *ca = NULL;
+ PKCS12 *p12;
+ int i;
+ char password[256];
+
+ ASSERT(NULL != ctx);
+
+ if (!strcmp(pkcs12_file, INLINE_FILE_TAG) && pkcs12_file_inline)
+ {
+ BIO *b64 = BIO_new(BIO_f_base64());
+ BIO *bio = BIO_new_mem_buf((void *) pkcs12_file_inline,
+ (int) strlen(pkcs12_file_inline));
+ ASSERT(b64 && bio);
+ BIO_push(b64, bio);
+ p12 = d2i_PKCS12_bio(b64, NULL);
+ if (!p12)
+ {
+ crypto_msg(M_FATAL, "Error reading inline PKCS#12 file");
+ }
+ BIO_free(b64);
+ BIO_free(bio);
+ }
+ else
+ {
+ /* Load the PKCS #12 file */
+ if (!(fp = platform_fopen(pkcs12_file, "rb")))
+ {
+ crypto_msg(M_FATAL, "Error opening file %s", pkcs12_file);
+ }
+ p12 = d2i_PKCS12_fp(fp, NULL);
+ fclose(fp);
+ if (!p12)
+ {
+ crypto_msg(M_FATAL, "Error reading PKCS#12 file %s", pkcs12_file);
+ }
+ }
+
+ /* Parse the PKCS #12 file */
+ if (!PKCS12_parse(p12, "", &pkey, &cert, &ca))
+ {
+ pem_password_callback(password, sizeof(password) - 1, 0, NULL);
+ /* Reparse the PKCS #12 file with password */
+ ca = NULL;
+ if (!PKCS12_parse(p12, password, &pkey, &cert, &ca))
+ {
#ifdef ENABLE_MANAGEMENT
- if (management && (ERR_GET_REASON (ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE))
- management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL);
+ if (management && (ERR_GET_REASON(ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE))
+ {
+ management_auth_failure(management, UP_TYPE_PRIVATE_KEY, NULL);
+ }
#endif
- PKCS12_free(p12);
- return 1;
- }
- }
- PKCS12_free(p12);
-
- /* Load Certificate */
- if (!SSL_CTX_use_certificate (ctx->ctx, cert))
- crypto_msg (M_FATAL, "Cannot use certificate");
-
- /* Load Private Key */
- if (!SSL_CTX_use_PrivateKey (ctx->ctx, pkey))
- crypto_msg (M_FATAL, "Cannot use private key");
-
- /* Check Private Key */
- if (!SSL_CTX_check_private_key (ctx->ctx))
- crypto_msg (M_FATAL, "Private key does not match the certificate");
-
- /* Set Certificate Verification chain */
- if (load_ca_file)
- {
- /* Add CAs from PKCS12 to the cert store and mark them as trusted.
- * They're also used to fill in the chain of intermediate certs as
- * necessary.
- */
- if (ca && sk_X509_num(ca))
- {
- for (i = 0; i < sk_X509_num(ca); i++)
- {
- if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i)))
- crypto_msg (M_FATAL,"Cannot add certificate to certificate chain (X509_STORE_add_cert)");
- if (!SSL_CTX_add_client_CA(ctx->ctx, sk_X509_value(ca, i)))
- crypto_msg (M_FATAL,"Cannot add certificate to client CA list (SSL_CTX_add_client_CA)");
- }
- }
- } else {
- /* If trusted CA certs were loaded from a PEM file, and we ignore the
- * ones in PKCS12, do load PKCS12-provided certs to the client extra
- * certs chain just in case they include intermediate CAs needed to
- * prove my identity to the other end. This does not make them trusted.
- */
- if (ca && sk_X509_num(ca))
- {
- for (i = 0; i < sk_X509_num(ca); i++)
- {
- if (!SSL_CTX_add_extra_chain_cert(ctx->ctx,sk_X509_value(ca, i)))
- crypto_msg (M_FATAL, "Cannot add extra certificate to chain (SSL_CTX_add_extra_chain_cert)");
- }
- }
- }
- return 0;
+ PKCS12_free(p12);
+ return 1;
+ }
+ }
+ PKCS12_free(p12);
+
+ /* Load Certificate */
+ if (!SSL_CTX_use_certificate(ctx->ctx, cert))
+ {
+ crypto_msg(M_FATAL, "Cannot use certificate");
+ }
+
+ /* Load Private Key */
+ if (!SSL_CTX_use_PrivateKey(ctx->ctx, pkey))
+ {
+ crypto_msg(M_FATAL, "Cannot use private key");
+ }
+
+ /* Check Private Key */
+ if (!SSL_CTX_check_private_key(ctx->ctx))
+ {
+ crypto_msg(M_FATAL, "Private key does not match the certificate");
+ }
+
+ /* Set Certificate Verification chain */
+ if (load_ca_file)
+ {
+ /* Add CAs from PKCS12 to the cert store and mark them as trusted.
+ * They're also used to fill in the chain of intermediate certs as
+ * necessary.
+ */
+ if (ca && sk_X509_num(ca))
+ {
+ for (i = 0; i < sk_X509_num(ca); i++)
+ {
+ if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i)))
+ {
+ crypto_msg(M_FATAL,"Cannot add certificate to certificate chain (X509_STORE_add_cert)");
+ }
+ if (!SSL_CTX_add_client_CA(ctx->ctx, sk_X509_value(ca, i)))
+ {
+ crypto_msg(M_FATAL,"Cannot add certificate to client CA list (SSL_CTX_add_client_CA)");
+ }
+ }
+ }
+ }
+ else
+ {
+ /* If trusted CA certs were loaded from a PEM file, and we ignore the
+ * ones in PKCS12, do load PKCS12-provided certs to the client extra
+ * certs chain just in case they include intermediate CAs needed to
+ * prove my identity to the other end. This does not make them trusted.
+ */
+ if (ca && sk_X509_num(ca))
+ {
+ for (i = 0; i < sk_X509_num(ca); i++)
+ {
+ if (!SSL_CTX_add_extra_chain_cert(ctx->ctx,sk_X509_value(ca, i)))
+ {
+ crypto_msg(M_FATAL, "Cannot add extra certificate to chain (SSL_CTX_add_extra_chain_cert)");
+ }
+ }
+ }
+ }
+ return 0;
}
#ifdef ENABLE_CRYPTOAPI
void
tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)
{
- ASSERT(NULL != ctx);
+ ASSERT(NULL != ctx);
- /* Load Certificate and Private Key */
- if (!SSL_CTX_use_CryptoAPI_certificate (ctx->ctx, cryptoapi_cert))
- crypto_msg (M_FATAL, "Cannot load certificate \"%s\" from Microsoft Certificate Store", cryptoapi_cert);
+ /* Load Certificate and Private Key */
+ if (!SSL_CTX_use_CryptoAPI_certificate(ctx->ctx, cryptoapi_cert))
+ {
+ crypto_msg(M_FATAL, "Cannot load certificate \"%s\" from Microsoft Certificate Store", cryptoapi_cert);
+ }
}
#endif /* ENABLE_CRYPTOAPI */
static void
-tls_ctx_add_extra_certs (struct tls_root_ctx *ctx, BIO *bio)
+tls_ctx_add_extra_certs(struct tls_root_ctx *ctx, BIO *bio)
{
- X509 *cert;
- for (;;)
+ X509 *cert;
+ for (;; )
{
- cert = NULL;
- if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */
- break;
- if (!cert)
- crypto_msg (M_FATAL, "Error reading extra certificate");
- if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1)
- crypto_msg (M_FATAL, "Error adding extra certificate");
+ cert = NULL;
+ if (!PEM_read_bio_X509(bio, &cert, 0, NULL)) /* takes ownership of cert */
+ {
+ break;
+ }
+ if (!cert)
+ {
+ crypto_msg(M_FATAL, "Error reading extra certificate");
+ }
+ if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1)
+ {
+ crypto_msg(M_FATAL, "Error adding extra certificate");
+ }
}
}
/* Like tls_ctx_load_cert, but returns a copy of the certificate in **X509 */
static void
-tls_ctx_load_cert_file_and_copy (struct tls_root_ctx *ctx,
- const char *cert_file, const char *cert_file_inline, X509 **x509
- )
+tls_ctx_load_cert_file_and_copy(struct tls_root_ctx *ctx,
+ const char *cert_file, const char *cert_file_inline, X509 **x509
+ )
{
- BIO *in = NULL;
- X509 *x = NULL;
- int ret = 0;
- bool inline_file = false;
+ BIO *in = NULL;
+ X509 *x = NULL;
+ int ret = 0;
+ bool inline_file = false;
- ASSERT (NULL != ctx);
- if (NULL != x509)
- ASSERT (NULL == *x509);
+ ASSERT(NULL != ctx);
+ if (NULL != x509)
+ {
+ ASSERT(NULL == *x509);
+ }
- inline_file = (strcmp (cert_file, INLINE_FILE_TAG) == 0);
+ inline_file = (strcmp(cert_file, INLINE_FILE_TAG) == 0);
- if (inline_file && cert_file_inline)
- in = BIO_new_mem_buf ((char *)cert_file_inline, -1);
- else
- in = BIO_new_file (cert_file, "r");
+ if (inline_file && cert_file_inline)
+ {
+ in = BIO_new_mem_buf((char *)cert_file_inline, -1);
+ }
+ else
+ {
+ in = BIO_new_file(cert_file, "r");
+ }
- if (in == NULL)
+ if (in == NULL)
{
- SSLerr (SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
- goto end;
+ SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB);
+ goto end;
}
- x = PEM_read_bio_X509 (in, NULL, ctx->ctx->default_passwd_callback,
- ctx->ctx->default_passwd_callback_userdata);
- if (x == NULL)
+ x = PEM_read_bio_X509(in, NULL, ctx->ctx->default_passwd_callback,
+ ctx->ctx->default_passwd_callback_userdata);
+ if (x == NULL)
{
- SSLerr (SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB);
- goto end;
+ SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB);
+ goto end;
}
- ret = SSL_CTX_use_certificate (ctx->ctx, x);
- if (ret)
- tls_ctx_add_extra_certs (ctx, in);
+ ret = SSL_CTX_use_certificate(ctx->ctx, x);
+ if (ret)
+ {
+ tls_ctx_add_extra_certs(ctx, in);
+ }
end:
- if (!ret)
+ if (!ret)
{
- if (inline_file)
- crypto_msg (M_FATAL, "Cannot load inline certificate file");
- else
- crypto_msg (M_FATAL, "Cannot load certificate file %s", cert_file);
+ if (inline_file)
+ {
+ crypto_msg(M_FATAL, "Cannot load inline certificate file");
+ }
+ else
+ {
+ crypto_msg(M_FATAL, "Cannot load certificate file %s", cert_file);
+ }
}
- if (in != NULL)
- BIO_free(in);
- if (x509)
- *x509 = x;
- else if (x)
- X509_free (x);
+ if (in != NULL)
+ {
+ BIO_free(in);
+ }
+ if (x509)
+ {
+ *x509 = x;
+ }
+ else if (x)
+ {
+ X509_free(x);
+ }
}
void
-tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
- const char *cert_file_inline)
+tls_ctx_load_cert_file(struct tls_root_ctx *ctx, const char *cert_file,
+ const char *cert_file_inline)
{
- tls_ctx_load_cert_file_and_copy (ctx, cert_file, cert_file_inline, NULL);
+ tls_ctx_load_cert_file_and_copy(ctx, cert_file, cert_file_inline, NULL);
}
void
-tls_ctx_free_cert_file (X509 *x509)
+tls_ctx_free_cert_file(X509 *x509)
{
- X509_free(x509);
+ X509_free(x509);
}
int
-tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file,
- const char *priv_key_file_inline
- )
+tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file,
+ const char *priv_key_file_inline
+ )
{
- SSL_CTX *ssl_ctx = NULL;
- BIO *in = NULL;
- EVP_PKEY *pkey = NULL;
- int ret = 1;
+ SSL_CTX *ssl_ctx = NULL;
+ BIO *in = NULL;
+ EVP_PKEY *pkey = NULL;
+ int ret = 1;
- ASSERT(NULL != ctx);
+ ASSERT(NULL != ctx);
- ssl_ctx = ctx->ctx;
+ ssl_ctx = ctx->ctx;
- if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_file_inline)
- in = BIO_new_mem_buf ((char *)priv_key_file_inline, -1);
- else
- in = BIO_new_file (priv_key_file, "r");
+ if (!strcmp(priv_key_file, INLINE_FILE_TAG) && priv_key_file_inline)
+ {
+ in = BIO_new_mem_buf((char *)priv_key_file_inline, -1);
+ }
+ else
+ {
+ in = BIO_new_file(priv_key_file, "r");
+ }
- if (!in)
- goto end;
+ if (!in)
+ {
+ goto end;
+ }
- pkey = PEM_read_bio_PrivateKey (in, NULL,
- ssl_ctx->default_passwd_callback,
- ssl_ctx->default_passwd_callback_userdata);
- if (!pkey)
- goto end;
+ pkey = PEM_read_bio_PrivateKey(in, NULL,
+ ssl_ctx->default_passwd_callback,
+ ssl_ctx->default_passwd_callback_userdata);
+ if (!pkey)
+ {
+ goto end;
+ }
- if (!SSL_CTX_use_PrivateKey (ssl_ctx, pkey))
+ if (!SSL_CTX_use_PrivateKey(ssl_ctx, pkey))
{
#ifdef ENABLE_MANAGEMENT
- if (management && (ERR_GET_REASON (ERR_peek_error()) == EVP_R_BAD_DECRYPT))
- management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL);
+ if (management && (ERR_GET_REASON(ERR_peek_error()) == EVP_R_BAD_DECRYPT))
+ {
+ management_auth_failure(management, UP_TYPE_PRIVATE_KEY, NULL);
+ }
#endif
- crypto_msg (M_WARN, "Cannot load private key file %s", priv_key_file);
- goto end;
+ crypto_msg(M_WARN, "Cannot load private key file %s", priv_key_file);
+ goto end;
}
- /* Check Private Key */
- if (!SSL_CTX_check_private_key (ssl_ctx))
- crypto_msg (M_FATAL, "Private key does not match the certificate");
- ret = 0;
+ /* Check Private Key */
+ if (!SSL_CTX_check_private_key(ssl_ctx))
+ {
+ crypto_msg(M_FATAL, "Private key does not match the certificate");
+ }
+ ret = 0;
end:
- if (pkey)
- EVP_PKEY_free (pkey);
- if (in)
- BIO_free (in);
- return ret;
+ if (pkey)
+ {
+ EVP_PKEY_free(pkey);
+ }
+ if (in)
+ {
+ BIO_free(in);
+ }
+ return ret;
}
void
backend_tls_ctx_reload_crl(struct tls_root_ctx *ssl_ctx, const char *crl_file,
- const char *crl_inline)
+ const char *crl_inline)
{
- X509_CRL *crl = NULL;
- BIO *in = NULL;
+ X509_CRL *crl = NULL;
+ BIO *in = NULL;
- X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
- if (!store)
- crypto_msg (M_FATAL, "Cannot get certificate store");
+ X509_STORE *store = SSL_CTX_get_cert_store(ssl_ctx->ctx);
+ if (!store)
+ {
+ crypto_msg(M_FATAL, "Cannot get certificate store");
+ }
- /* Always start with a cleared CRL list, for that we
- * we need to manually find the CRL object from the stack
- * and remove it */
- for (int i = 0; i < sk_X509_OBJECT_num(store->objs); i++)
+ /* Always start with a cleared CRL list, for that we
+ * we need to manually find the CRL object from the stack
+ * and remove it */
+ for (int i = 0; i < sk_X509_OBJECT_num(store->objs); i++)
{
- X509_OBJECT* obj = sk_X509_OBJECT_value(store->objs, i);
- ASSERT(obj);
- if (obj->type == X509_LU_CRL)
- {
- sk_X509_OBJECT_delete(store->objs, i);
- X509_OBJECT_free_contents(obj);
- OPENSSL_free(obj);
- }
+ X509_OBJECT *obj = sk_X509_OBJECT_value(store->objs, i);
+ ASSERT(obj);
+ if (obj->type == X509_LU_CRL)
+ {
+ sk_X509_OBJECT_delete(store->objs, i);
+ X509_OBJECT_free_contents(obj);
+ OPENSSL_free(obj);
+ }
}
- X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
+ X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
- if (!strcmp (crl_file, INLINE_FILE_TAG) && crl_inline)
- in = BIO_new_mem_buf ((char *)crl_inline, -1);
- else
- in = BIO_new_file (crl_file, "r");
+ if (!strcmp(crl_file, INLINE_FILE_TAG) && crl_inline)
+ {
+ in = BIO_new_mem_buf((char *)crl_inline, -1);
+ }
+ else
+ {
+ in = BIO_new_file(crl_file, "r");
+ }
- if (in == NULL)
+ if (in == NULL)
{
- msg (M_WARN, "CRL: cannot read: %s", crl_file);
- goto end;
+ msg(M_WARN, "CRL: cannot read: %s", crl_file);
+ goto end;
}
- crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
- if (crl == NULL)
+ crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
+ if (crl == NULL)
{
- msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file);
- goto end;
+ msg(M_WARN, "CRL: cannot read CRL from file %s", crl_file);
+ goto end;
}
- if (!X509_STORE_add_crl(store, crl))
+ if (!X509_STORE_add_crl(store, crl))
{
- msg (M_WARN, "CRL: cannot add %s to store", crl_file);
- goto end;
+ msg(M_WARN, "CRL: cannot add %s to store", crl_file);
+ goto end;
}
end:
- X509_CRL_free(crl);
- BIO_free(in);
+ X509_CRL_free(crl);
+ BIO_free(in);
}
@@ -835,294 +942,352 @@ end:
static int
rsa_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
- ASSERT(0);
- return -1;
+ ASSERT(0);
+ return -1;
}
/* verify arbitrary data */
static int
rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
- ASSERT(0);
- return -1;
+ ASSERT(0);
+ return -1;
}
/* decrypt */
static int
rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
- ASSERT(0);
- return -1;
+ ASSERT(0);
+ return -1;
}
/* called at RSA_free */
static int
rsa_finish(RSA *rsa)
{
- free ((void*)rsa->meth);
- rsa->meth = NULL;
- return 1;
+ free((void *)rsa->meth);
+ rsa->meth = NULL;
+ return 1;
}
/* sign arbitrary data */
static int
rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
{
- /* optional app data in rsa->meth->app_data; */
- char *in_b64 = NULL;
- char *out_b64 = NULL;
- int ret = -1;
- int len;
-
- if (padding != RSA_PKCS1_PADDING)
- {
- RSAerr (RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
- goto done;
- }
-
- /* convert 'from' to base64 */
- if (openvpn_base64_encode (from, flen, &in_b64) <= 0)
- goto done;
-
- /* call MI for signature */
- if (management)
- out_b64 = management_query_rsa_sig (management, in_b64);
- if (!out_b64)
- goto done;
-
- /* decode base64 signature to binary */
- len = RSA_size(rsa);
- ret = openvpn_base64_decode (out_b64, to, len);
-
- /* verify length */
- if (ret != len)
- ret = -1;
-
- done:
- if (in_b64)
- free (in_b64);
- if (out_b64)
- free (out_b64);
- return ret;
-}
+ /* optional app data in rsa->meth->app_data; */
+ char *in_b64 = NULL;
+ char *out_b64 = NULL;
+ int ret = -1;
+ int len;
-int
-tls_ctx_use_external_private_key (struct tls_root_ctx *ctx,
- const char *cert_file, const char *cert_file_inline)
-{
- RSA *rsa = NULL;
- RSA *pub_rsa;
- RSA_METHOD *rsa_meth;
- X509 *cert = NULL;
+ if (padding != RSA_PKCS1_PADDING)
+ {
+ RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+ goto done;
+ }
- ASSERT (NULL != ctx);
+ /* convert 'from' to base64 */
+ if (openvpn_base64_encode(from, flen, &in_b64) <= 0)
+ {
+ goto done;
+ }
- tls_ctx_load_cert_file_and_copy (ctx, cert_file, cert_file_inline, &cert);
+ /* call MI for signature */
+ if (management)
+ {
+ out_b64 = management_query_rsa_sig(management, in_b64);
+ }
+ if (!out_b64)
+ {
+ goto done;
+ }
- ASSERT (NULL != cert);
+ /* decode base64 signature to binary */
+ len = RSA_size(rsa);
+ ret = openvpn_base64_decode(out_b64, to, len);
- /* allocate custom RSA method object */
- ALLOC_OBJ_CLEAR (rsa_meth, RSA_METHOD);
- rsa_meth->name = "OpenVPN external private key RSA Method";
- rsa_meth->rsa_pub_enc = rsa_pub_enc;
- rsa_meth->rsa_pub_dec = rsa_pub_dec;
- rsa_meth->rsa_priv_enc = rsa_priv_enc;
- rsa_meth->rsa_priv_dec = rsa_priv_dec;
- rsa_meth->init = NULL;
- rsa_meth->finish = rsa_finish;
- rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
- rsa_meth->app_data = NULL;
+ /* verify length */
+ if (ret != len)
+ {
+ ret = -1;
+ }
- /* allocate RSA object */
- rsa = RSA_new();
- if (rsa == NULL)
+done:
+ if (in_b64)
{
- SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE);
- goto err;
+ free(in_b64);
}
+ if (out_b64)
+ {
+ free(out_b64);
+ }
+ return ret;
+}
- /* get the public key */
- ASSERT(cert->cert_info->key->pkey); /* NULL before SSL_CTX_use_certificate() is called */
- pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
+int
+tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
+ const char *cert_file, const char *cert_file_inline)
+{
+ RSA *rsa = NULL;
+ RSA *pub_rsa;
+ RSA_METHOD *rsa_meth;
+ X509 *cert = NULL;
+
+ ASSERT(NULL != ctx);
+
+ tls_ctx_load_cert_file_and_copy(ctx, cert_file, cert_file_inline, &cert);
+
+ ASSERT(NULL != cert);
+
+ /* allocate custom RSA method object */
+ ALLOC_OBJ_CLEAR(rsa_meth, RSA_METHOD);
+ rsa_meth->name = "OpenVPN external private key RSA Method";
+ rsa_meth->rsa_pub_enc = rsa_pub_enc;
+ rsa_meth->rsa_pub_dec = rsa_pub_dec;
+ rsa_meth->rsa_priv_enc = rsa_priv_enc;
+ rsa_meth->rsa_priv_dec = rsa_priv_dec;
+ rsa_meth->init = NULL;
+ rsa_meth->finish = rsa_finish;
+ rsa_meth->flags = RSA_METHOD_FLAG_NO_CHECK;
+ rsa_meth->app_data = NULL;
+
+ /* allocate RSA object */
+ rsa = RSA_new();
+ if (rsa == NULL)
+ {
+ SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
- /* initialize RSA object */
- rsa->n = BN_dup(pub_rsa->n);
- rsa->flags |= RSA_FLAG_EXT_PKEY;
- if (!RSA_set_method(rsa, rsa_meth))
- goto err;
+ /* get the public key */
+ ASSERT(cert->cert_info->key->pkey); /* NULL before SSL_CTX_use_certificate() is called */
+ pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
- /* bind our custom RSA object to ssl_ctx */
- if (!SSL_CTX_use_RSAPrivateKey(ctx->ctx, rsa))
- goto err;
+ /* initialize RSA object */
+ rsa->n = BN_dup(pub_rsa->n);
+ rsa->flags |= RSA_FLAG_EXT_PKEY;
+ if (!RSA_set_method(rsa, rsa_meth))
+ {
+ goto err;
+ }
- X509_free(cert);
- RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */
- return 1;
+ /* bind our custom RSA object to ssl_ctx */
+ if (!SSL_CTX_use_RSAPrivateKey(ctx->ctx, rsa))
+ {
+ goto err;
+ }
- err:
- if (cert)
X509_free(cert);
- if (rsa)
- RSA_free(rsa);
- else
+ RSA_free(rsa); /* doesn't necessarily free, just decrements refcount */
+ return 1;
+
+err:
+ if (cert)
+ {
+ X509_free(cert);
+ }
+ if (rsa)
+ {
+ RSA_free(rsa);
+ }
+ else
{
- if (rsa_meth)
- free(rsa_meth);
+ if (rsa_meth)
+ {
+ free(rsa_meth);
+ }
}
- crypto_msg (M_FATAL, "Cannot enable SSL external private key capability");
- return 0;
+ crypto_msg(M_FATAL, "Cannot enable SSL external private key capability");
+ return 0;
}
-#endif
+#endif /* ifdef MANAGMENT_EXTERNAL_KEY */
static int
-sk_x509_name_cmp(const X509_NAME * const *a, const X509_NAME * const *b)
+sk_x509_name_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
{
- return X509_NAME_cmp (*a, *b);
+ return X509_NAME_cmp(*a, *b);
}
void
-tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
- const char *ca_file_inline,
- const char *ca_path, bool tls_server
- )
+tls_ctx_load_ca(struct tls_root_ctx *ctx, const char *ca_file,
+ const char *ca_file_inline,
+ const char *ca_path, bool tls_server
+ )
{
- STACK_OF(X509_INFO) *info_stack = NULL;
- STACK_OF(X509_NAME) *cert_names = NULL;
- X509_LOOKUP *lookup = NULL;
- X509_STORE *store = NULL;
- X509_NAME *xn = NULL;
- BIO *in = NULL;
- int i, added = 0, prev = 0;
-
- ASSERT(NULL != ctx);
-
- store = SSL_CTX_get_cert_store(ctx->ctx);
- if (!store)
- crypto_msg (M_FATAL, "Cannot get certificate store");
+ STACK_OF(X509_INFO) *info_stack = NULL;
+ STACK_OF(X509_NAME) *cert_names = NULL;
+ X509_LOOKUP *lookup = NULL;
+ X509_STORE *store = NULL;
+ X509_NAME *xn = NULL;
+ BIO *in = NULL;
+ int i, added = 0, prev = 0;
+
+ ASSERT(NULL != ctx);
+
+ store = SSL_CTX_get_cert_store(ctx->ctx);
+ if (!store)
+ {
+ crypto_msg(M_FATAL, "Cannot get certificate store");
+ }
- /* Try to add certificates and CRLs from ca_file */
- if (ca_file)
+ /* Try to add certificates and CRLs from ca_file */
+ if (ca_file)
{
- if (!strcmp (ca_file, INLINE_FILE_TAG) && ca_file_inline)
- in = BIO_new_mem_buf ((char *)ca_file_inline, -1);
- else
- in = BIO_new_file (ca_file, "r");
+ if (!strcmp(ca_file, INLINE_FILE_TAG) && ca_file_inline)
+ {
+ in = BIO_new_mem_buf((char *)ca_file_inline, -1);
+ }
+ else
+ {
+ in = BIO_new_file(ca_file, "r");
+ }
- if (in)
- info_stack = PEM_X509_INFO_read_bio (in, NULL, NULL, NULL);
+ if (in)
+ {
+ info_stack = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
+ }
- if (info_stack)
+ if (info_stack)
{
- for (i = 0; i < sk_X509_INFO_num (info_stack); i++)
+ for (i = 0; i < sk_X509_INFO_num(info_stack); i++)
{
- X509_INFO *info = sk_X509_INFO_value (info_stack, i);
- if (info->crl)
- X509_STORE_add_crl (store, info->crl);
-
- if (tls_server && !info->x509)
+ X509_INFO *info = sk_X509_INFO_value(info_stack, i);
+ if (info->crl)
{
- crypto_msg (M_FATAL, "X509 name was missing in TLS mode");
+ X509_STORE_add_crl(store, info->crl);
}
- if (info->x509)
+ if (tls_server && !info->x509)
{
- X509_STORE_add_cert (store, info->x509);
- added++;
+ crypto_msg(M_FATAL, "X509 name was missing in TLS mode");
+ }
- if (!tls_server)
- continue;
+ if (info->x509)
+ {
+ X509_STORE_add_cert(store, info->x509);
+ added++;
- /* Use names of CAs as a client CA list */
- if (cert_names == NULL)
+ if (!tls_server)
{
- cert_names = sk_X509_NAME_new (sk_x509_name_cmp);
- if (!cert_names)
continue;
}
- xn = X509_get_subject_name (info->x509);
- if (!xn)
- continue;
+ /* Use names of CAs as a client CA list */
+ if (cert_names == NULL)
+ {
+ cert_names = sk_X509_NAME_new(sk_x509_name_cmp);
+ if (!cert_names)
+ {
+ continue;
+ }
+ }
- /* Don't add duplicate CA names */
- if (sk_X509_NAME_find (cert_names, xn) == -1)
+ xn = X509_get_subject_name(info->x509);
+ if (!xn)
{
- xn = X509_NAME_dup (xn);
- if (!xn)
continue;
- sk_X509_NAME_push (cert_names, xn);
+ }
+
+ /* Don't add duplicate CA names */
+ if (sk_X509_NAME_find(cert_names, xn) == -1)
+ {
+ xn = X509_NAME_dup(xn);
+ if (!xn)
+ {
+ continue;
+ }
+ sk_X509_NAME_push(cert_names, xn);
}
}
- if (tls_server) {
- int cnum = sk_X509_NAME_num (cert_names);
- if (cnum != (prev + 1))
- {
- crypto_msg (M_WARN,
- "Cannot load CA certificate file %s (entry %d did not validate)",
- np(ca_file), added);
- }
- prev = cnum;
- }
+ if (tls_server)
+ {
+ int cnum = sk_X509_NAME_num(cert_names);
+ if (cnum != (prev + 1))
+ {
+ crypto_msg(M_WARN,
+ "Cannot load CA certificate file %s (entry %d did not validate)",
+ np(ca_file), added);
+ }
+ prev = cnum;
+ }
}
- sk_X509_INFO_pop_free (info_stack, X509_INFO_free);
+ sk_X509_INFO_pop_free(info_stack, X509_INFO_free);
}
- if (tls_server)
- SSL_CTX_set_client_CA_list (ctx->ctx, cert_names);
+ if (tls_server)
+ {
+ SSL_CTX_set_client_CA_list(ctx->ctx, cert_names);
+ }
- if (!added)
- {
- crypto_msg (M_FATAL,
- "Cannot load CA certificate file %s (no entries were read)",
- np(ca_file));
- }
+ if (!added)
+ {
+ crypto_msg(M_FATAL,
+ "Cannot load CA certificate file %s (no entries were read)",
+ np(ca_file));
+ }
- if (tls_server) {
- int cnum = sk_X509_NAME_num (cert_names);
- if (cnum != added)
- {
- crypto_msg (M_FATAL, "Cannot load CA certificate file %s (only %d "
- "of %d entries were valid X509 names)",
- np(ca_file), cnum, added);
- }
- }
+ if (tls_server)
+ {
+ int cnum = sk_X509_NAME_num(cert_names);
+ if (cnum != added)
+ {
+ crypto_msg(M_FATAL, "Cannot load CA certificate file %s (only %d "
+ "of %d entries were valid X509 names)",
+ np(ca_file), cnum, added);
+ }
+ }
- if (in)
- BIO_free (in);
+ if (in)
+ {
+ BIO_free(in);
+ }
}
- /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */
- if (ca_path)
+ /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */
+ if (ca_path)
{
- lookup = X509_STORE_add_lookup (store, X509_LOOKUP_hash_dir ());
- if (lookup && X509_LOOKUP_add_dir (lookup, ca_path, X509_FILETYPE_PEM))
- msg(M_WARN, "WARNING: experimental option --capath %s", ca_path);
- else
- crypto_msg (M_FATAL, "Cannot add lookup at --capath %s", ca_path);
- X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
+ lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir());
+ if (lookup && X509_LOOKUP_add_dir(lookup, ca_path, X509_FILETYPE_PEM))
+ {
+ msg(M_WARN, "WARNING: experimental option --capath %s", ca_path);
+ }
+ else
+ {
+ crypto_msg(M_FATAL, "Cannot add lookup at --capath %s", ca_path);
+ }
+ X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
}
}
void
-tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file,
- const char *extra_certs_file_inline
- )
+tls_ctx_load_extra_certs(struct tls_root_ctx *ctx, const char *extra_certs_file,
+ const char *extra_certs_file_inline
+ )
{
- BIO *in;
- if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline)
- in = BIO_new_mem_buf ((char *)extra_certs_file_inline, -1);
- else
- in = BIO_new_file (extra_certs_file, "r");
-
- if (in == NULL)
- crypto_msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file);
- else
- tls_ctx_add_extra_certs (ctx, in);
-
- BIO_free (in);
+ BIO *in;
+ if (!strcmp(extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline)
+ {
+ in = BIO_new_mem_buf((char *)extra_certs_file_inline, -1);
+ }
+ else
+ {
+ in = BIO_new_file(extra_certs_file, "r");
+ }
+
+ if (in == NULL)
+ {
+ crypto_msg(M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file);
+ }
+ else
+ {
+ tls_ctx_add_extra_certs(ctx, in);
+ }
+
+ BIO_free(in);
}
/* **************************************
@@ -1148,56 +1313,58 @@ static const int biofp_reopen_interval = 600; /* GLOBAL */
static void
close_biofp()
{
- if (biofp)
+ if (biofp)
{
- ASSERT (!fclose (biofp));
- biofp = NULL;
+ ASSERT(!fclose(biofp));
+ biofp = NULL;
}
}
static void
open_biofp()
{
- const time_t current = time (NULL);
- const pid_t pid = getpid ();
+ const time_t current = time(NULL);
+ const pid_t pid = getpid();
- if (biofp_last_open + biofp_reopen_interval < current)
- close_biofp();
- if (!biofp)
+ if (biofp_last_open + biofp_reopen_interval < current)
+ {
+ close_biofp();
+ }
+ if (!biofp)
{
- char fn[256];
- openvpn_snprintf(fn, sizeof(fn), "bio/%d-%d.log", pid, biofp_toggle);
- biofp = fopen (fn, "w");
- ASSERT (biofp);
- biofp_last_open = time (NULL);
- biofp_toggle ^= 1;
+ char fn[256];
+ openvpn_snprintf(fn, sizeof(fn), "bio/%d-%d.log", pid, biofp_toggle);
+ biofp = fopen(fn, "w");
+ ASSERT(biofp);
+ biofp_last_open = time(NULL);
+ biofp_toggle ^= 1;
}
}
static void
-bio_debug_data (const char *mode, BIO *bio, const uint8_t *buf, int len, const char *desc)
+bio_debug_data(const char *mode, BIO *bio, const uint8_t *buf, int len, const char *desc)
{
- struct gc_arena gc = gc_new ();
- if (len > 0)
+ struct gc_arena gc = gc_new();
+ if (len > 0)
{
- open_biofp();
- fprintf(biofp, "BIO_%s %s time=" time_format " bio=" ptr_format " len=%d data=%s\n",
- mode, desc, time (NULL), (ptr_type)bio, len, format_hex (buf, len, 0, &gc));
- fflush (biofp);
+ open_biofp();
+ fprintf(biofp, "BIO_%s %s time=" time_format " bio=" ptr_format " len=%d data=%s\n",
+ mode, desc, time(NULL), (ptr_type)bio, len, format_hex(buf, len, 0, &gc));
+ fflush(biofp);
}
- gc_free (&gc);
+ gc_free(&gc);
}
static void
-bio_debug_oc (const char *mode, BIO *bio)
+bio_debug_oc(const char *mode, BIO *bio)
{
- open_biofp();
- fprintf(biofp, "BIO %s time=" time_format " bio=" ptr_format "\n",
- mode, time (NULL), (ptr_type)bio);
- fflush (biofp);
+ open_biofp();
+ fprintf(biofp, "BIO %s time=" time_format " bio=" ptr_format "\n",
+ mode, time(NULL), (ptr_type)bio);
+ fflush(biofp);
}
-#endif
+#endif /* ifdef BIO_DEBUG */
/*
* OpenVPN's interface to SSL/TLS authentication,
@@ -1205,64 +1372,65 @@ bio_debug_oc (const char *mode, BIO *bio)
* through "memory BIOs".
*/
static BIO *
-getbio (BIO_METHOD * type, const char *desc)
+getbio(BIO_METHOD *type, const char *desc)
{
- BIO *ret;
- ret = BIO_new (type);
- if (!ret)
- crypto_msg (M_FATAL, "Error creating %s BIO", desc);
- return ret;
+ BIO *ret;
+ ret = BIO_new(type);
+ if (!ret)
+ {
+ crypto_msg(M_FATAL, "Error creating %s BIO", desc);
+ }
+ return ret;
}
/*
* Write to an OpenSSL BIO in non-blocking mode.
*/
static int
-bio_write (BIO *bio, const uint8_t *data, int size, const char *desc)
+bio_write(BIO *bio, const uint8_t *data, int size, const char *desc)
{
- int i;
- int ret = 0;
- ASSERT (size >= 0);
- if (size)
- {
- /*
- * Free the L_TLS lock prior to calling BIO routines
- * so that foreground thread can still call
- * tls_pre_decrypt or tls_pre_encrypt,
- * allowing tunnel packet forwarding to continue.
- */
+ int i;
+ int ret = 0;
+ ASSERT(size >= 0);
+ if (size)
+ {
+ /*
+ * Free the L_TLS lock prior to calling BIO routines
+ * so that foreground thread can still call
+ * tls_pre_decrypt or tls_pre_encrypt,
+ * allowing tunnel packet forwarding to continue.
+ */
#ifdef BIO_DEBUG
- bio_debug_data ("write", bio, data, size, desc);
+ bio_debug_data("write", bio, data, size, desc);
#endif
- i = BIO_write (bio, data, size);
-
- if (i < 0)
- {
- if (BIO_should_retry (bio))
- {
- ;
- }
- else
- {
- crypto_msg (D_TLS_ERRORS, "TLS ERROR: BIO write %s error", desc);
- ret = -1;
- ERR_clear_error ();
- }
- }
- else if (i != size)
- {
- crypto_msg (D_TLS_ERRORS, "TLS ERROR: BIO write %s incomplete %d/%d",
- desc, i, size);
- ret = -1;
- ERR_clear_error ();
- }
- else
- { /* successful write */
- dmsg (D_HANDSHAKE_VERBOSE, "BIO write %s %d bytes", desc, i);
- ret = 1;
- }
- }
- return ret;
+ i = BIO_write(bio, data, size);
+
+ if (i < 0)
+ {
+ if (BIO_should_retry(bio))
+ {
+ }
+ else
+ {
+ crypto_msg(D_TLS_ERRORS, "TLS ERROR: BIO write %s error", desc);
+ ret = -1;
+ ERR_clear_error();
+ }
+ }
+ else if (i != size)
+ {
+ crypto_msg(D_TLS_ERRORS, "TLS ERROR: BIO write %s incomplete %d/%d",
+ desc, i, size);
+ ret = -1;
+ ERR_clear_error();
+ }
+ else
+ { /* successful write */
+ dmsg(D_HANDSHAKE_VERBOSE, "BIO write %s %d bytes", desc, i);
+ ret = 1;
+ }
+ }
+ return ret;
}
/*
@@ -1271,12 +1439,12 @@ bio_write (BIO *bio, const uint8_t *data, int size, const char *desc)
*/
static void
-bio_write_post (const int status, struct buffer *buf)
+bio_write_post(const int status, struct buffer *buf)
{
- if (status == 1) /* success status return from bio_write? */
+ if (status == 1) /* success status return from bio_write? */
{
- memset (BPTR (buf), 0, BLEN (buf)); /* erase data just written */
- buf->len = 0;
+ memset(BPTR(buf), 0, BLEN(buf)); /* erase data just written */
+ buf->len = 0;
}
}
@@ -1284,183 +1452,191 @@ bio_write_post (const int status, struct buffer *buf)
* Read from an OpenSSL BIO in non-blocking mode.
*/
static int
-bio_read (BIO *bio, struct buffer *buf, int maxlen, const char *desc)
+bio_read(BIO *bio, struct buffer *buf, int maxlen, const char *desc)
{
- int i;
- int ret = 0;
- ASSERT (buf->len >= 0);
- if (buf->len)
+ int i;
+ int ret = 0;
+ ASSERT(buf->len >= 0);
+ if (buf->len)
{
- ;
}
- else
+ else
{
- int len = buf_forward_capacity (buf);
- if (maxlen < len)
- len = maxlen;
+ int len = buf_forward_capacity(buf);
+ if (maxlen < len)
+ {
+ len = maxlen;
+ }
- /*
- * BIO_read brackets most of the serious RSA
- * key negotiation number crunching.
- */
- i = BIO_read (bio, BPTR (buf), len);
+ /*
+ * BIO_read brackets most of the serious RSA
+ * key negotiation number crunching.
+ */
+ i = BIO_read(bio, BPTR(buf), len);
- VALGRIND_MAKE_READABLE ((void *) &i, sizeof (i));
+ VALGRIND_MAKE_READABLE((void *) &i, sizeof(i));
#ifdef BIO_DEBUG
- bio_debug_data ("read", bio, BPTR (buf), i, desc);
+ bio_debug_data("read", bio, BPTR(buf), i, desc);
#endif
- if (i < 0)
- {
- if (BIO_should_retry (bio))
- {
- ;
- }
- else
- {
- crypto_msg (D_TLS_ERRORS, "TLS_ERROR: BIO read %s error", desc);
- buf->len = 0;
- ret = -1;
- ERR_clear_error ();
- }
- }
- else if (!i)
- {
- buf->len = 0;
- }
- else
- { /* successful read */
- dmsg (D_HANDSHAKE_VERBOSE, "BIO read %s %d bytes", desc, i);
- buf->len = i;
- ret = 1;
- VALGRIND_MAKE_READABLE ((void *) BPTR (buf), BLEN (buf));
- }
- }
- return ret;
+ if (i < 0)
+ {
+ if (BIO_should_retry(bio))
+ {
+ }
+ else
+ {
+ crypto_msg(D_TLS_ERRORS, "TLS_ERROR: BIO read %s error", desc);
+ buf->len = 0;
+ ret = -1;
+ ERR_clear_error();
+ }
+ }
+ else if (!i)
+ {
+ buf->len = 0;
+ }
+ else
+ { /* successful read */
+ dmsg(D_HANDSHAKE_VERBOSE, "BIO read %s %d bytes", desc, i);
+ buf->len = i;
+ ret = 1;
+ VALGRIND_MAKE_READABLE((void *) BPTR(buf), BLEN(buf));
+ }
+ }
+ return ret;
}
void
key_state_ssl_init(struct key_state_ssl *ks_ssl, const struct tls_root_ctx *ssl_ctx, bool is_server, struct tls_session *session)
{
- ASSERT(NULL != ssl_ctx);
- ASSERT(ks_ssl);
- CLEAR (*ks_ssl);
+ ASSERT(NULL != ssl_ctx);
+ ASSERT(ks_ssl);
+ CLEAR(*ks_ssl);
- ks_ssl->ssl = SSL_new (ssl_ctx->ctx);
- if (!ks_ssl->ssl)
- crypto_msg (M_FATAL, "SSL_new failed");
+ ks_ssl->ssl = SSL_new(ssl_ctx->ctx);
+ if (!ks_ssl->ssl)
+ {
+ crypto_msg(M_FATAL, "SSL_new failed");
+ }
- /* put session * in ssl object so we can access it
- from verify callback*/
- SSL_set_ex_data (ks_ssl->ssl, mydata_index, session);
+ /* put session * in ssl object so we can access it
+ * from verify callback*/
+ SSL_set_ex_data(ks_ssl->ssl, mydata_index, session);
- ks_ssl->ssl_bio = getbio (BIO_f_ssl (), "ssl_bio");
- ks_ssl->ct_in = getbio (BIO_s_mem (), "ct_in");
- ks_ssl->ct_out = getbio (BIO_s_mem (), "ct_out");
+ ks_ssl->ssl_bio = getbio(BIO_f_ssl(), "ssl_bio");
+ ks_ssl->ct_in = getbio(BIO_s_mem(), "ct_in");
+ ks_ssl->ct_out = getbio(BIO_s_mem(), "ct_out");
#ifdef BIO_DEBUG
- bio_debug_oc ("open ssl_bio", ks_ssl->ssl_bio);
- bio_debug_oc ("open ct_in", ks_ssl->ct_in);
- bio_debug_oc ("open ct_out", ks_ssl->ct_out);
+ bio_debug_oc("open ssl_bio", ks_ssl->ssl_bio);
+ bio_debug_oc("open ct_in", ks_ssl->ct_in);
+ bio_debug_oc("open ct_out", ks_ssl->ct_out);
#endif
- if (is_server)
- SSL_set_accept_state (ks_ssl->ssl);
- else
- SSL_set_connect_state (ks_ssl->ssl);
+ if (is_server)
+ {
+ SSL_set_accept_state(ks_ssl->ssl);
+ }
+ else
+ {
+ SSL_set_connect_state(ks_ssl->ssl);
+ }
- SSL_set_bio (ks_ssl->ssl, ks_ssl->ct_in, ks_ssl->ct_out);
- BIO_set_ssl (ks_ssl->ssl_bio, ks_ssl->ssl, BIO_NOCLOSE);
+ SSL_set_bio(ks_ssl->ssl, ks_ssl->ct_in, ks_ssl->ct_out);
+ BIO_set_ssl(ks_ssl->ssl_bio, ks_ssl->ssl, BIO_NOCLOSE);
}
-void key_state_ssl_free(struct key_state_ssl *ks_ssl)
+void
+key_state_ssl_free(struct key_state_ssl *ks_ssl)
{
- if (ks_ssl->ssl) {
+ if (ks_ssl->ssl)
+ {
#ifdef BIO_DEBUG
- bio_debug_oc ("close ssl_bio", ks_ssl->ssl_bio);
- bio_debug_oc ("close ct_in", ks_ssl->ct_in);
- bio_debug_oc ("close ct_out", ks_ssl->ct_out);
+ bio_debug_oc("close ssl_bio", ks_ssl->ssl_bio);
+ bio_debug_oc("close ct_in", ks_ssl->ct_in);
+ bio_debug_oc("close ct_out", ks_ssl->ct_out);
#endif
- BIO_free_all(ks_ssl->ssl_bio);
- SSL_free (ks_ssl->ssl);
- }
+ BIO_free_all(ks_ssl->ssl_bio);
+ SSL_free(ks_ssl->ssl);
+ }
}
int
-key_state_write_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf)
+key_state_write_plaintext(struct key_state_ssl *ks_ssl, struct buffer *buf)
{
- int ret = 0;
- perf_push (PERF_BIO_WRITE_PLAINTEXT);
+ int ret = 0;
+ perf_push(PERF_BIO_WRITE_PLAINTEXT);
#ifdef ENABLE_CRYPTO_OPENSSL
- ASSERT (NULL != ks_ssl);
+ ASSERT(NULL != ks_ssl);
- ret = bio_write (ks_ssl->ssl_bio, BPTR(buf), BLEN(buf),
- "tls_write_plaintext");
- bio_write_post (ret, buf);
+ ret = bio_write(ks_ssl->ssl_bio, BPTR(buf), BLEN(buf),
+ "tls_write_plaintext");
+ bio_write_post(ret, buf);
#endif /* ENABLE_CRYPTO_OPENSSL */
- perf_pop ();
- return ret;
+ perf_pop();
+ return ret;
}
int
-key_state_write_plaintext_const (struct key_state_ssl *ks_ssl, const uint8_t *data, int len)
+key_state_write_plaintext_const(struct key_state_ssl *ks_ssl, const uint8_t *data, int len)
{
- int ret = 0;
- perf_push (PERF_BIO_WRITE_PLAINTEXT);
+ int ret = 0;
+ perf_push(PERF_BIO_WRITE_PLAINTEXT);
- ASSERT (NULL != ks_ssl);
+ ASSERT(NULL != ks_ssl);
- ret = bio_write (ks_ssl->ssl_bio, data, len, "tls_write_plaintext_const");
+ ret = bio_write(ks_ssl->ssl_bio, data, len, "tls_write_plaintext_const");
- perf_pop ();
- return ret;
+ perf_pop();
+ return ret;
}
int
-key_state_read_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf,
- int maxlen)
+key_state_read_ciphertext(struct key_state_ssl *ks_ssl, struct buffer *buf,
+ int maxlen)
{
- int ret = 0;
- perf_push (PERF_BIO_READ_CIPHERTEXT);
+ int ret = 0;
+ perf_push(PERF_BIO_READ_CIPHERTEXT);
- ASSERT (NULL != ks_ssl);
+ ASSERT(NULL != ks_ssl);
- ret = bio_read (ks_ssl->ct_out, buf, maxlen, "tls_read_ciphertext");
+ ret = bio_read(ks_ssl->ct_out, buf, maxlen, "tls_read_ciphertext");
- perf_pop ();
- return ret;
+ perf_pop();
+ return ret;
}
int
-key_state_write_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf)
+key_state_write_ciphertext(struct key_state_ssl *ks_ssl, struct buffer *buf)
{
- int ret = 0;
- perf_push (PERF_BIO_WRITE_CIPHERTEXT);
+ int ret = 0;
+ perf_push(PERF_BIO_WRITE_CIPHERTEXT);
- ASSERT (NULL != ks_ssl);
+ ASSERT(NULL != ks_ssl);
- ret = bio_write (ks_ssl->ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext");
- bio_write_post (ret, buf);
+ ret = bio_write(ks_ssl->ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext");
+ bio_write_post(ret, buf);
- perf_pop ();
- return ret;
+ perf_pop();
+ return ret;
}
int
-key_state_read_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf,
- int maxlen)
+key_state_read_plaintext(struct key_state_ssl *ks_ssl, struct buffer *buf,
+ int maxlen)
{
- int ret = 0;
- perf_push (PERF_BIO_READ_PLAINTEXT);
+ int ret = 0;
+ perf_push(PERF_BIO_READ_PLAINTEXT);
- ASSERT (NULL != ks_ssl);
+ ASSERT(NULL != ks_ssl);
- ret = bio_read (ks_ssl->ssl_bio, buf, maxlen, "tls_read_plaintext");
+ ret = bio_read(ks_ssl->ssl_bio, buf, maxlen, "tls_read_plaintext");
- perf_pop ();
- return ret;
+ perf_pop();
+ return ret;
}
/* **************************************
@@ -1471,84 +1647,91 @@ key_state_read_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf,
*
***************************************/
void
-print_details (struct key_state_ssl * ks_ssl, const char *prefix)
+print_details(struct key_state_ssl *ks_ssl, const char *prefix)
{
- const SSL_CIPHER *ciph;
- X509 *cert;
- char s1[256];
- char s2[256];
-
- s1[0] = s2[0] = 0;
- ciph = SSL_get_current_cipher (ks_ssl->ssl);
- openvpn_snprintf (s1, sizeof (s1), "%s %s, cipher %s %s",
- prefix,
- SSL_get_version (ks_ssl->ssl),
- SSL_CIPHER_get_version (ciph),
- SSL_CIPHER_get_name (ciph));
- cert = SSL_get_peer_certificate (ks_ssl->ssl);
- if (cert != NULL)
- {
- EVP_PKEY *pkey = X509_get_pubkey (cert);
- if (pkey != NULL)
- {
- if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
- && pkey->pkey.rsa->n != NULL)
- {
- openvpn_snprintf (s2, sizeof (s2), ", %d bit RSA",
- BN_num_bits (pkey->pkey.rsa->n));
- }
- else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
- && pkey->pkey.dsa->p != NULL)
- {
- openvpn_snprintf (s2, sizeof (s2), ", %d bit DSA",
- BN_num_bits (pkey->pkey.dsa->p));
- }
- EVP_PKEY_free (pkey);
- }
- X509_free (cert);
- }
- /* The SSL API does not allow us to look at temporary RSA/DH keys,
- * otherwise we should print their lengths too */
- msg (D_HANDSHAKE, "%s%s", s1, s2);
+ const SSL_CIPHER *ciph;
+ X509 *cert;
+ char s1[256];
+ char s2[256];
+
+ s1[0] = s2[0] = 0;
+ ciph = SSL_get_current_cipher(ks_ssl->ssl);
+ openvpn_snprintf(s1, sizeof(s1), "%s %s, cipher %s %s",
+ prefix,
+ SSL_get_version(ks_ssl->ssl),
+ SSL_CIPHER_get_version(ciph),
+ SSL_CIPHER_get_name(ciph));
+ cert = SSL_get_peer_certificate(ks_ssl->ssl);
+ if (cert != NULL)
+ {
+ EVP_PKEY *pkey = X509_get_pubkey(cert);
+ if (pkey != NULL)
+ {
+ if (pkey->type == EVP_PKEY_RSA && pkey->pkey.rsa != NULL
+ && pkey->pkey.rsa->n != NULL)
+ {
+ openvpn_snprintf(s2, sizeof(s2), ", %d bit RSA",
+ BN_num_bits(pkey->pkey.rsa->n));
+ }
+ else if (pkey->type == EVP_PKEY_DSA && pkey->pkey.dsa != NULL
+ && pkey->pkey.dsa->p != NULL)
+ {
+ openvpn_snprintf(s2, sizeof(s2), ", %d bit DSA",
+ BN_num_bits(pkey->pkey.dsa->p));
+ }
+ EVP_PKEY_free(pkey);
+ }
+ X509_free(cert);
+ }
+ /* The SSL API does not allow us to look at temporary RSA/DH keys,
+ * otherwise we should print their lengths too */
+ msg(D_HANDSHAKE, "%s%s", s1, s2);
}
void
-show_available_tls_ciphers (const char *cipher_list)
+show_available_tls_ciphers(const char *cipher_list)
{
- struct tls_root_ctx tls_ctx;
- SSL *ssl;
- const char *cipher_name;
- const tls_cipher_name_pair *pair;
- int priority = 0;
-
- tls_ctx.ctx = SSL_CTX_new (SSLv23_method ());
- if (!tls_ctx.ctx)
- crypto_msg (M_FATAL, "Cannot create SSL_CTX object");
+ struct tls_root_ctx tls_ctx;
+ SSL *ssl;
+ const char *cipher_name;
+ const tls_cipher_name_pair *pair;
+ int priority = 0;
+
+ tls_ctx.ctx = SSL_CTX_new(SSLv23_method());
+ if (!tls_ctx.ctx)
+ {
+ crypto_msg(M_FATAL, "Cannot create SSL_CTX object");
+ }
- ssl = SSL_new (tls_ctx.ctx);
- if (!ssl)
- crypto_msg (M_FATAL, "Cannot create SSL object");
+ ssl = SSL_new(tls_ctx.ctx);
+ if (!ssl)
+ {
+ crypto_msg(M_FATAL, "Cannot create SSL object");
+ }
- tls_ctx_restrict_ciphers(&tls_ctx, cipher_list);
+ tls_ctx_restrict_ciphers(&tls_ctx, cipher_list);
- printf ("Available TLS Ciphers,\n");
- printf ("listed in order of preference:\n\n");
- while ((cipher_name = SSL_get_cipher_list (ssl, priority++)))
+ printf("Available TLS Ciphers,\n");
+ printf("listed in order of preference:\n\n");
+ while ((cipher_name = SSL_get_cipher_list(ssl, priority++)))
{
- pair = tls_get_cipher_name_pair(cipher_name, strlen(cipher_name));
+ pair = tls_get_cipher_name_pair(cipher_name, strlen(cipher_name));
- if (NULL == pair) {
- // No translation found, print warning
- printf ("%s (No IANA name known to OpenVPN, use OpenSSL name.)\n", cipher_name);
- } else {
- printf ("%s\n", pair->iana_name);
- }
+ if (NULL == pair)
+ {
+ /* No translation found, print warning */
+ printf("%s (No IANA name known to OpenVPN, use OpenSSL name.)\n", cipher_name);
+ }
+ else
+ {
+ printf("%s\n", pair->iana_name);
+ }
}
- printf ("\n" SHOW_TLS_CIPHER_LIST_WARNING);
+ printf("\n" SHOW_TLS_CIPHER_LIST_WARNING);
- SSL_free (ssl);
- SSL_CTX_free (tls_ctx.ctx);
+ SSL_free(ssl);
+ SSL_CTX_free(tls_ctx.ctx);
}
/*
@@ -1559,54 +1742,61 @@ void
show_available_curves()
{
#ifndef OPENSSL_NO_EC
- EC_builtin_curve *curves = NULL;
- size_t crv_len = 0;
- size_t n = 0;
-
- crv_len = EC_get_builtin_curves(NULL, 0);
- ALLOC_ARRAY(curves, EC_builtin_curve, crv_len);
- if (EC_get_builtin_curves(curves, crv_len))
- {
- printf ("Available Elliptic curves:\n");
- for (n = 0; n < crv_len; n++)
- {
- const char *sname;
- sname = OBJ_nid2sn(curves[n].nid);
- if (sname == NULL) sname = "";
-
- printf("%s\n", sname);
- }
- }
- else
- {
- crypto_msg (M_FATAL, "Cannot get list of builtin curves");
- }
- free(curves);
-#else
- msg (M_WARN, "Your OpenSSL library was built without elliptic curve support. "
- "No curves available.");
-#endif
+ EC_builtin_curve *curves = NULL;
+ size_t crv_len = 0;
+ size_t n = 0;
+
+ crv_len = EC_get_builtin_curves(NULL, 0);
+ ALLOC_ARRAY(curves, EC_builtin_curve, crv_len);
+ if (EC_get_builtin_curves(curves, crv_len))
+ {
+ printf("Available Elliptic curves:\n");
+ for (n = 0; n < crv_len; n++)
+ {
+ const char *sname;
+ sname = OBJ_nid2sn(curves[n].nid);
+ if (sname == NULL)
+ {
+ sname = "";
+ }
+
+ printf("%s\n", sname);
+ }
+ }
+ else
+ {
+ crypto_msg(M_FATAL, "Cannot get list of builtin curves");
+ }
+ free(curves);
+#else /* ifndef OPENSSL_NO_EC */
+ msg(M_WARN, "Your OpenSSL library was built without elliptic curve support. "
+ "No curves available.");
+#endif /* ifndef OPENSSL_NO_EC */
}
void
-get_highest_preference_tls_cipher (char *buf, int size)
+get_highest_preference_tls_cipher(char *buf, int size)
{
- SSL_CTX *ctx;
- SSL *ssl;
- const char *cipher_name;
-
- ctx = SSL_CTX_new (SSLv23_method ());
- if (!ctx)
- crypto_msg (M_FATAL, "Cannot create SSL_CTX object");
- ssl = SSL_new (ctx);
- if (!ssl)
- crypto_msg (M_FATAL, "Cannot create SSL object");
-
- cipher_name = SSL_get_cipher_list (ssl, 0);
- strncpynt (buf, cipher_name, size);
-
- SSL_free (ssl);
- SSL_CTX_free (ctx);
+ SSL_CTX *ctx;
+ SSL *ssl;
+ const char *cipher_name;
+
+ ctx = SSL_CTX_new(SSLv23_method());
+ if (!ctx)
+ {
+ crypto_msg(M_FATAL, "Cannot create SSL_CTX object");
+ }
+ ssl = SSL_new(ctx);
+ if (!ssl)
+ {
+ crypto_msg(M_FATAL, "Cannot create SSL object");
+ }
+
+ cipher_name = SSL_get_cipher_list(ssl, 0);
+ strncpynt(buf, cipher_name, size);
+
+ SSL_free(ssl);
+ SSL_CTX_free(ctx);
}
const char *