summaryrefslogtreecommitdiff
path: root/src/openvpn/ssl_mbedtls.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvpn/ssl_mbedtls.c')
-rw-r--r--src/openvpn/ssl_mbedtls.c1514
1 files changed, 815 insertions, 699 deletions
diff --git a/src/openvpn/ssl_mbedtls.c b/src/openvpn/ssl_mbedtls.c
index 11ee65b..5c84e30 100644
--- a/src/openvpn/ssl_mbedtls.c
+++ b/src/openvpn/ssl_mbedtls.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>
* Copyright (C) 2006-2010, Brainspark B.V.
*
* This program is free software; you can redistribute it and/or modify
@@ -51,11 +51,17 @@
#include "ssl_verify_mbedtls.h"
#include <mbedtls/debug.h>
#include <mbedtls/error.h>
-#include <mbedtls/net.h>
+#include <mbedtls/version.h>
+
+#if MBEDTLS_VERSION_NUMBER >= 0x02040000
+ #include <mbedtls/net_sockets.h>
+#else
+ #include <mbedtls/net.h>
+#endif
+
#include <mbedtls/oid.h>
#include <mbedtls/pem.h>
#include <mbedtls/sha256.h>
-#include <mbedtls/version.h>
void
tls_init_lib()
@@ -75,74 +81,87 @@ tls_clear_error()
void
tls_ctx_server_new(struct tls_root_ctx *ctx)
{
- ASSERT(NULL != ctx);
- CLEAR(*ctx);
+ ASSERT(NULL != ctx);
+ CLEAR(*ctx);
- ALLOC_OBJ_CLEAR(ctx->dhm_ctx, mbedtls_dhm_context);
+ ALLOC_OBJ_CLEAR(ctx->dhm_ctx, mbedtls_dhm_context);
- ALLOC_OBJ_CLEAR(ctx->ca_chain, mbedtls_x509_crt);
+ ALLOC_OBJ_CLEAR(ctx->ca_chain, mbedtls_x509_crt);
- ctx->endpoint = MBEDTLS_SSL_IS_SERVER;
- ctx->initialised = true;
+ ctx->endpoint = MBEDTLS_SSL_IS_SERVER;
+ ctx->initialised = true;
}
void
tls_ctx_client_new(struct tls_root_ctx *ctx)
{
- ASSERT(NULL != ctx);
- CLEAR(*ctx);
+ ASSERT(NULL != ctx);
+ CLEAR(*ctx);
- ALLOC_OBJ_CLEAR(ctx->dhm_ctx, mbedtls_dhm_context);
- ALLOC_OBJ_CLEAR(ctx->ca_chain, mbedtls_x509_crt);
+ ALLOC_OBJ_CLEAR(ctx->dhm_ctx, mbedtls_dhm_context);
+ ALLOC_OBJ_CLEAR(ctx->ca_chain, mbedtls_x509_crt);
- ctx->endpoint = MBEDTLS_SSL_IS_CLIENT;
- ctx->initialised = true;
+ ctx->endpoint = MBEDTLS_SSL_IS_CLIENT;
+ ctx->initialised = true;
}
void
tls_ctx_free(struct tls_root_ctx *ctx)
{
- if (ctx)
+ if (ctx)
{
- mbedtls_pk_free(ctx->priv_key);
- if (ctx->priv_key)
- free(ctx->priv_key);
-
- mbedtls_x509_crt_free(ctx->ca_chain);
- if (ctx->ca_chain)
- free(ctx->ca_chain);
-
- mbedtls_x509_crt_free(ctx->crt_chain);
- if (ctx->crt_chain)
- free(ctx->crt_chain);
-
- mbedtls_dhm_free(ctx->dhm_ctx);
- if (ctx->dhm_ctx)
- free(ctx->dhm_ctx);
-
- mbedtls_x509_crl_free(ctx->crl);
- if (ctx->crl)
- {
- free(ctx->crl);
- }
+ mbedtls_pk_free(ctx->priv_key);
+ if (ctx->priv_key)
+ {
+ free(ctx->priv_key);
+ }
+
+ mbedtls_x509_crt_free(ctx->ca_chain);
+ if (ctx->ca_chain)
+ {
+ free(ctx->ca_chain);
+ }
+
+ mbedtls_x509_crt_free(ctx->crt_chain);
+ if (ctx->crt_chain)
+ {
+ free(ctx->crt_chain);
+ }
+
+ mbedtls_dhm_free(ctx->dhm_ctx);
+ if (ctx->dhm_ctx)
+ {
+ free(ctx->dhm_ctx);
+ }
+
+ mbedtls_x509_crl_free(ctx->crl);
+ if (ctx->crl)
+ {
+ free(ctx->crl);
+ }
#if defined(ENABLE_PKCS11)
- if (ctx->priv_key_pkcs11 != NULL) {
- mbedtls_pkcs11_priv_key_free(ctx->priv_key_pkcs11);
- free(ctx->priv_key_pkcs11);
- }
+ if (ctx->priv_key_pkcs11 != NULL)
+ {
+ mbedtls_pkcs11_priv_key_free(ctx->priv_key_pkcs11);
+ free(ctx->priv_key_pkcs11);
+ }
#endif
#if defined(MANAGMENT_EXTERNAL_KEY)
- if (ctx->external_key != NULL)
- free(ctx->external_key);
+ if (ctx->external_key != NULL)
+ {
+ free(ctx->external_key);
+ }
#endif
- if (ctx->allowed_ciphers)
- free(ctx->allowed_ciphers);
+ if (ctx->allowed_ciphers)
+ {
+ free(ctx->allowed_ciphers);
+ }
- CLEAR(*ctx);
+ CLEAR(*ctx);
- ctx->initialised = false;
+ ctx->initialised = false;
}
}
@@ -150,8 +169,8 @@ tls_ctx_free(struct tls_root_ctx *ctx)
bool
tls_ctx_initialised(struct tls_root_ctx *ctx)
{
- ASSERT(NULL != ctx);
- return ctx->initialised;
+ ASSERT(NULL != ctx);
+ return ctx->initialised;
}
void
@@ -161,226 +180,242 @@ key_state_export_keying_material(struct key_state_ssl *ssl,
}
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)
{
}
static const char *
-tls_translate_cipher_name (const char * cipher_name) {
- const tls_cipher_name_pair * pair = tls_get_cipher_name_pair(cipher_name, strlen(cipher_name));
+tls_translate_cipher_name(const char *cipher_name) {
+ const tls_cipher_name_pair *pair = tls_get_cipher_name_pair(cipher_name, strlen(cipher_name));
- if (NULL == pair)
+ if (NULL == pair)
{
- // No translation found, return original
- return cipher_name;
+ /* No translation found, return original */
+ return cipher_name;
}
- if (0 != strcmp(cipher_name, pair->iana_name))
+ if (0 != strcmp(cipher_name, pair->iana_name))
{
- // Deprecated name found, notify user
- msg(M_WARN, "Deprecated cipher suite name '%s', please use IANA name '%s'", pair->openssl_name, pair->iana_name);
+ /* Deprecated name found, notify user */
+ msg(M_WARN, "Deprecated cipher suite name '%s', please use IANA name '%s'", pair->openssl_name, pair->iana_name);
}
- return pair->iana_name;
+ return pair->iana_name;
}
void
tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
{
- char *tmp_ciphers, *tmp_ciphers_orig, *token;
- int i, cipher_count;
- int ciphers_len;
+ char *tmp_ciphers, *tmp_ciphers_orig, *token;
+ int i, cipher_count;
+ int ciphers_len;
- if (NULL == ciphers)
- return; /* Nothing to do */
+ if (NULL == ciphers)
+ {
+ return; /* Nothing to do */
- ciphers_len = strlen (ciphers);
+ }
+ ciphers_len = strlen(ciphers);
- ASSERT (NULL != ctx);
- ASSERT (0 != ciphers_len);
+ ASSERT(NULL != ctx);
+ ASSERT(0 != ciphers_len);
- /* Get number of ciphers */
- for (i = 0, cipher_count = 1; i < ciphers_len; i++)
- if (ciphers[i] == ':')
- cipher_count++;
+ /* Get number of ciphers */
+ for (i = 0, cipher_count = 1; i < ciphers_len; i++)
+ if (ciphers[i] == ':')
+ {
+ cipher_count++;
+ }
- /* Allocate an array for them */
- ALLOC_ARRAY_CLEAR(ctx->allowed_ciphers, int, cipher_count+1)
+ /* Allocate an array for them */
+ ALLOC_ARRAY_CLEAR(ctx->allowed_ciphers, int, cipher_count+1)
- /* Parse allowed ciphers, getting IDs */
- i = 0;
- tmp_ciphers_orig = tmp_ciphers = string_alloc (ciphers, NULL);
+ /* Parse allowed ciphers, getting IDs */
+ i = 0;
+ tmp_ciphers_orig = tmp_ciphers = string_alloc(ciphers, NULL);
- token = strtok (tmp_ciphers, ":");
- while(token)
+ token = strtok(tmp_ciphers, ":");
+ while (token)
{
- ctx->allowed_ciphers[i] = mbedtls_ssl_get_ciphersuite_id (
- tls_translate_cipher_name (token));
- if (0 != ctx->allowed_ciphers[i])
- i++;
- token = strtok (NULL, ":");
+ ctx->allowed_ciphers[i] = mbedtls_ssl_get_ciphersuite_id(
+ tls_translate_cipher_name(token));
+ if (0 != ctx->allowed_ciphers[i])
+ {
+ i++;
+ }
+ token = strtok(NULL, ":");
}
- free(tmp_ciphers_orig);
+ free(tmp_ciphers_orig);
}
void
-tls_ctx_check_cert_time (const struct tls_root_ctx *ctx)
+tls_ctx_check_cert_time(const struct tls_root_ctx *ctx)
{
- ASSERT (ctx);
- if (ctx->crt_chain == NULL)
+ ASSERT(ctx);
+ if (ctx->crt_chain == NULL)
{
- return; /* Nothing to check if there is no certificate */
+ return; /* Nothing to check if there is no certificate */
}
- if (mbedtls_x509_time_is_future (&ctx->crt_chain->valid_from))
+ if (mbedtls_x509_time_is_future(&ctx->crt_chain->valid_from))
{
- msg (M_WARN, "WARNING: Your certificate is not yet valid!");
+ msg(M_WARN, "WARNING: Your certificate is not yet valid!");
}
- if (mbedtls_x509_time_is_past (&ctx->crt_chain->valid_to))
+ if (mbedtls_x509_time_is_past(&ctx->crt_chain->valid_to))
{
- msg (M_WARN, "WARNING: Your certificate has expired!");
+ msg(M_WARN, "WARNING: Your certificate has expired!");
}
}
void
-tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file,
- const char *dh_inline
- )
+tls_ctx_load_dh_params(struct tls_root_ctx *ctx, const char *dh_file,
+ const char *dh_inline
+ )
{
- if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_inline)
- {
- if (!mbed_ok(mbedtls_dhm_parse_dhm(ctx->dhm_ctx,
- (const unsigned char *) dh_inline, strlen(dh_inline)+1)))
- msg (M_FATAL, "Cannot read inline DH parameters");
- }
-else
- {
- if (!mbed_ok(mbedtls_dhm_parse_dhmfile(ctx->dhm_ctx, dh_file)))
- msg (M_FATAL, "Cannot read DH parameters from file %s", dh_file);
- }
-
- msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with " counter_format " bit key",
- (counter_type) 8 * mbedtls_mpi_size(&ctx->dhm_ctx->P));
+ if (!strcmp(dh_file, INLINE_FILE_TAG) && dh_inline)
+ {
+ if (!mbed_ok(mbedtls_dhm_parse_dhm(ctx->dhm_ctx,
+ (const unsigned char *) dh_inline, strlen(dh_inline)+1)))
+ {
+ msg(M_FATAL, "Cannot read inline DH parameters");
+ }
+ }
+ else
+ {
+ if (!mbed_ok(mbedtls_dhm_parse_dhmfile(ctx->dhm_ctx, dh_file)))
+ {
+ msg(M_FATAL, "Cannot read DH parameters from file %s", dh_file);
+ }
+ }
+
+ msg(D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with " counter_format " bit key",
+ (counter_type) 8 * mbedtls_mpi_size(&ctx->dhm_ctx->P));
}
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
+ )
{
if (NULL != curve_name)
- msg(M_WARN, "WARNING: mbed TLS builds do not support specifying an ECDH "
- "curve, using default curves.");
+ {
+ msg(M_WARN, "WARNING: mbed TLS builds do not support specifying an ECDH "
+ "curve, using default curves.");
+ }
}
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
+ )
{
- msg(M_FATAL, "PKCS #12 files not yet supported for mbed TLS.");
- return 0;
+ msg(M_FATAL, "PKCS #12 files not yet supported for mbed TLS.");
+ return 0;
}
#ifdef ENABLE_CRYPTOAPI
void
tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)
{
- msg(M_FATAL, "Windows CryptoAPI not yet supported for mbed TLS.");
+ msg(M_FATAL, "Windows CryptoAPI not yet supported for mbed TLS.");
}
#endif /* _WIN32 */
void
-tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
- const char *cert_inline
- )
+tls_ctx_load_cert_file(struct tls_root_ctx *ctx, const char *cert_file,
+ const char *cert_inline
+ )
{
- ASSERT(NULL != ctx);
+ ASSERT(NULL != ctx);
- if (!ctx->crt_chain)
+ if (!ctx->crt_chain)
{
- ALLOC_OBJ_CLEAR(ctx->crt_chain, mbedtls_x509_crt);
+ ALLOC_OBJ_CLEAR(ctx->crt_chain, mbedtls_x509_crt);
}
- if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_inline)
+ if (!strcmp(cert_file, INLINE_FILE_TAG) && cert_inline)
{
- if (!mbed_ok(mbedtls_x509_crt_parse(ctx->crt_chain,
- (const unsigned char *) cert_inline, strlen(cert_inline)+1)))
- msg (M_FATAL, "Cannot load inline certificate file");
+ if (!mbed_ok(mbedtls_x509_crt_parse(ctx->crt_chain,
+ (const unsigned char *) cert_inline, strlen(cert_inline)+1)))
+ {
+ msg(M_FATAL, "Cannot load inline certificate file");
+ }
}
- else
+ else
{
- if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->crt_chain, cert_file)))
- {
- msg (M_FATAL, "Cannot load certificate file %s", cert_file);
- }
+ if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->crt_chain, cert_file)))
+ {
+ msg(M_FATAL, "Cannot load certificate file %s", cert_file);
+ }
}
}
int
-tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file,
- const char *priv_key_inline
- )
+tls_ctx_load_priv_file(struct tls_root_ctx *ctx, const char *priv_key_file,
+ const char *priv_key_inline
+ )
{
- int status;
- ASSERT(NULL != ctx);
+ int status;
+ ASSERT(NULL != ctx);
- if (!ctx->priv_key)
+ if (!ctx->priv_key)
{
- ALLOC_OBJ_CLEAR(ctx->priv_key, mbedtls_pk_context);
+ ALLOC_OBJ_CLEAR(ctx->priv_key, mbedtls_pk_context);
}
- if (!strcmp (priv_key_file, INLINE_FILE_TAG) && priv_key_inline)
+ if (!strcmp(priv_key_file, INLINE_FILE_TAG) && priv_key_inline)
{
- status = mbedtls_pk_parse_key(ctx->priv_key,
- (const unsigned char *) priv_key_inline, strlen(priv_key_inline)+1,
- NULL, 0);
-
- if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status)
- {
- char passbuf[512] = {0};
- pem_password_callback(passbuf, 512, 0, NULL);
- status = mbedtls_pk_parse_key(ctx->priv_key,
- (const unsigned char *) priv_key_inline,
- strlen(priv_key_inline)+1, (unsigned char *) passbuf,
- strlen(passbuf));
- }
+ status = mbedtls_pk_parse_key(ctx->priv_key,
+ (const unsigned char *) priv_key_inline, strlen(priv_key_inline)+1,
+ NULL, 0);
+
+ if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status)
+ {
+ char passbuf[512] = {0};
+ pem_password_callback(passbuf, 512, 0, NULL);
+ status = mbedtls_pk_parse_key(ctx->priv_key,
+ (const unsigned char *) priv_key_inline,
+ strlen(priv_key_inline)+1, (unsigned char *) passbuf,
+ strlen(passbuf));
+ }
}
- else
+ else
{
- status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, NULL);
- if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status)
- {
- char passbuf[512] = {0};
- pem_password_callback(passbuf, 512, 0, NULL);
- status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, passbuf);
- }
+ status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, NULL);
+ if (MBEDTLS_ERR_PK_PASSWORD_REQUIRED == status)
+ {
+ char passbuf[512] = {0};
+ pem_password_callback(passbuf, 512, 0, NULL);
+ status = mbedtls_pk_parse_keyfile(ctx->priv_key, priv_key_file, passbuf);
+ }
}
- if (!mbed_ok(status))
+ if (!mbed_ok(status))
{
#ifdef ENABLE_MANAGEMENT
- if (management && (MBEDTLS_ERR_PK_PASSWORD_MISMATCH == status))
- management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL);
+ if (management && (MBEDTLS_ERR_PK_PASSWORD_MISMATCH == status))
+ {
+ management_auth_failure(management, UP_TYPE_PRIVATE_KEY, NULL);
+ }
#endif
- msg (M_WARN, "Cannot load private key file %s", priv_key_file);
- return 1;
+ msg(M_WARN, "Cannot load private key file %s", priv_key_file);
+ return 1;
}
- if (!mbed_ok(mbedtls_pk_check_pair(&ctx->crt_chain->pk, ctx->priv_key)))
+ if (!mbed_ok(mbedtls_pk_check_pair(&ctx->crt_chain->pk, ctx->priv_key)))
{
- msg (M_WARN, "Private key does not match the certificate");
- return 1;
+ msg(M_WARN, "Private key does not match the certificate");
+ return 1;
}
- return 0;
+ return 0;
}
#ifdef MANAGMENT_EXTERNAL_KEY
struct external_context {
- size_t signature_length;
+ size_t signature_length;
};
/**
@@ -402,187 +437,220 @@ struct external_context {
*
* @return 0 on success, non-zero mbed TLS error code on failure.
*/
-static inline int external_pkcs1_sign( void *ctx_voidptr,
- int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode,
- mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash,
- unsigned char *sig )
+static inline int
+external_pkcs1_sign( void *ctx_voidptr,
+ int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, int mode,
+ mbedtls_md_type_t md_alg, unsigned int hashlen, const unsigned char *hash,
+ unsigned char *sig )
{
- struct external_context * const ctx = ctx_voidptr;
- char *in_b64 = NULL;
- char *out_b64 = NULL;
- int rv;
- unsigned char *p = sig;
- size_t asn_len = 0, oid_size = 0, sig_len = 0;
- const char *oid = NULL;
-
- if( NULL == ctx )
- return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
-
- if( MBEDTLS_RSA_PRIVATE != mode )
- return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
-
- /*
- * Support a wide range of hashes. TLSv1.1 and before only need SIG_RSA_RAW,
- * but TLSv1.2 needs the full suite of hashes.
- *
- * This code has been taken from mbed TLS pkcs11_sign(), under the GPLv2.0+.
- */
- if( md_alg != MBEDTLS_MD_NONE )
+ struct external_context *const ctx = ctx_voidptr;
+ char *in_b64 = NULL;
+ char *out_b64 = NULL;
+ int rv;
+ unsigned char *p = sig;
+ size_t asn_len = 0, oid_size = 0, sig_len = 0;
+ const char *oid = NULL;
+
+ if (NULL == ctx)
{
- const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
- if( md_info == NULL )
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
-
- if (!mbed_ok(mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size )))
- return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+ }
- hashlen = mbedtls_md_get_size( md_info );
- asn_len = 10 + oid_size;
+ if (MBEDTLS_RSA_PRIVATE != mode)
+ {
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
}
- sig_len = ctx->signature_length;
- if ( (SIZE_MAX - hashlen) < asn_len || (hashlen + asn_len) > sig_len )
- return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+ /*
+ * Support a wide range of hashes. TLSv1.1 and before only need SIG_RSA_RAW,
+ * but TLSv1.2 needs the full suite of hashes.
+ *
+ * This code has been taken from mbed TLS pkcs11_sign(), under the GPLv2.0+.
+ */
+ if (md_alg != MBEDTLS_MD_NONE)
+ {
+ const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg );
+ if (md_info == NULL)
+ {
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ if (!mbed_ok(mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size )))
+ {
+ return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ hashlen = mbedtls_md_get_size( md_info );
+ asn_len = 10 + oid_size;
+ }
- if( md_alg != MBEDTLS_MD_NONE )
+ sig_len = ctx->signature_length;
+ if ( (SIZE_MAX - hashlen) < asn_len || (hashlen + asn_len) > sig_len)
{
- /*
- * DigestInfo ::= SEQUENCE {
- * digestAlgorithm DigestAlgorithmIdentifier,
- * digest Digest }
- *
- * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
- *
- * Digest ::= OCTET STRING
- */
- *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
- *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
- *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
- *p++ = (unsigned char) ( 0x04 + oid_size );
- *p++ = MBEDTLS_ASN1_OID;
- *p++ = oid_size & 0xFF;
- memcpy( p, oid, oid_size );
- p += oid_size;
- *p++ = MBEDTLS_ASN1_NULL;
- *p++ = 0x00;
- *p++ = MBEDTLS_ASN1_OCTET_STRING;
- *p++ = hashlen;
+ return MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+ }
- /* Determine added ASN length */
- asn_len = p - sig;
- }
+ if (md_alg != MBEDTLS_MD_NONE)
+ {
+ /*
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * digest Digest }
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * Digest ::= OCTET STRING
+ */
+ *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
+ *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
+ *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED;
+ *p++ = (unsigned char) ( 0x04 + oid_size );
+ *p++ = MBEDTLS_ASN1_OID;
+ *p++ = oid_size & 0xFF;
+ memcpy( p, oid, oid_size );
+ p += oid_size;
+ *p++ = MBEDTLS_ASN1_NULL;
+ *p++ = 0x00;
+ *p++ = MBEDTLS_ASN1_OCTET_STRING;
+ *p++ = hashlen;
+
+ /* Determine added ASN length */
+ asn_len = p - sig;
+ }
- /* Copy the hash to be signed */
- memcpy( p, hash, hashlen );
+ /* Copy the hash to be signed */
+ memcpy( p, hash, hashlen );
- /* convert 'from' to base64 */
- if (openvpn_base64_encode (sig, asn_len + hashlen, &in_b64) <= 0)
+ /* convert 'from' to base64 */
+ if (openvpn_base64_encode(sig, asn_len + hashlen, &in_b64) <= 0)
{
- rv = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
- goto done;
+ rv = MBEDTLS_ERR_RSA_BAD_INPUT_DATA;
+ goto done;
}
- /* call MI for signature */
- if (management)
- out_b64 = management_query_rsa_sig (management, in_b64);
- if (!out_b64)
+ /* call MI for signature */
+ if (management)
+ {
+ out_b64 = management_query_rsa_sig(management, in_b64);
+ }
+ if (!out_b64)
{
- rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
- goto done;
+ rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
+ goto done;
}
- /* decode base64 signature to binary and verify length */
- if ( openvpn_base64_decode (out_b64, sig, ctx->signature_length) !=
- ctx->signature_length )
+ /* decode base64 signature to binary and verify length */
+ if (openvpn_base64_decode(out_b64, sig, ctx->signature_length) !=
+ ctx->signature_length)
{
- rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
- goto done;
+ rv = MBEDTLS_ERR_RSA_PRIVATE_FAILED;
+ goto done;
}
- rv = 0;
+ rv = 0;
done:
- if (in_b64)
- free (in_b64);
- if (out_b64)
- free (out_b64);
- return rv;
+ if (in_b64)
+ {
+ free(in_b64);
+ }
+ if (out_b64)
+ {
+ free(out_b64);
+ }
+ return rv;
}
-static inline size_t external_key_len(void *vctx)
+static inline size_t
+external_key_len(void *vctx)
{
- struct external_context * const ctx = vctx;
+ struct external_context *const ctx = vctx;
- return ctx->signature_length;
+ return ctx->signature_length;
}
int
-tls_ctx_use_external_private_key (struct tls_root_ctx *ctx,
- const char *cert_file, const char *cert_file_inline)
+tls_ctx_use_external_private_key(struct tls_root_ctx *ctx,
+ const char *cert_file, const char *cert_file_inline)
{
- ASSERT(NULL != ctx);
+ ASSERT(NULL != ctx);
- tls_ctx_load_cert_file(ctx, cert_file, cert_file_inline);
+ tls_ctx_load_cert_file(ctx, cert_file, cert_file_inline);
- if (ctx->crt_chain == NULL)
- return 0;
+ if (ctx->crt_chain == NULL)
+ {
+ return 0;
+ }
- ALLOC_OBJ_CLEAR (ctx->external_key, struct external_context);
- ctx->external_key->signature_length = mbedtls_pk_get_len (&ctx->crt_chain->pk);
+ ALLOC_OBJ_CLEAR(ctx->external_key, struct external_context);
+ ctx->external_key->signature_length = mbedtls_pk_get_len(&ctx->crt_chain->pk);
- ALLOC_OBJ_CLEAR (ctx->priv_key, mbedtls_pk_context);
- if (!mbed_ok (mbedtls_pk_setup_rsa_alt (ctx->priv_key, ctx->external_key,
- NULL, external_pkcs1_sign, external_key_len)))
- return 0;
+ ALLOC_OBJ_CLEAR(ctx->priv_key, mbedtls_pk_context);
+ if (!mbed_ok(mbedtls_pk_setup_rsa_alt(ctx->priv_key, ctx->external_key,
+ NULL, external_pkcs1_sign, external_key_len)))
+ {
+ return 0;
+ }
- return 1;
+ return 1;
}
-#endif
+#endif /* ifdef MANAGMENT_EXTERNAL_KEY */
-void tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
- const char *ca_inline, const char *ca_path, bool tls_server
- )
+void
+tls_ctx_load_ca(struct tls_root_ctx *ctx, const char *ca_file,
+ const char *ca_inline, const char *ca_path, bool tls_server
+ )
{
- if (ca_path)
- msg(M_FATAL, "ERROR: mbed TLS cannot handle the capath directive");
+ if (ca_path)
+ {
+ msg(M_FATAL, "ERROR: mbed TLS cannot handle the capath directive");
+ }
- if (ca_file && !strcmp (ca_file, INLINE_FILE_TAG) && ca_inline)
+ if (ca_file && !strcmp(ca_file, INLINE_FILE_TAG) && ca_inline)
{
- if (!mbed_ok (mbedtls_x509_crt_parse (ctx->ca_chain,
- (const unsigned char *) ca_inline, strlen(ca_inline)+1)))
- msg (M_FATAL, "Cannot load inline CA certificates");
+ if (!mbed_ok(mbedtls_x509_crt_parse(ctx->ca_chain,
+ (const unsigned char *) ca_inline, strlen(ca_inline)+1)))
+ {
+ msg(M_FATAL, "Cannot load inline CA certificates");
+ }
}
- else
+ else
{
- /* Load CA file for verifying peer supplied certificate */
- if (!mbed_ok (mbedtls_x509_crt_parse_file (ctx->ca_chain, ca_file)))
- msg (M_FATAL, "Cannot load CA certificate file %s", ca_file);
+ /* Load CA file for verifying peer supplied certificate */
+ if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->ca_chain, ca_file)))
+ {
+ msg(M_FATAL, "Cannot load CA certificate file %s", ca_file);
+ }
}
}
void
-tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file,
- const char *extra_certs_inline
- )
+tls_ctx_load_extra_certs(struct tls_root_ctx *ctx, const char *extra_certs_file,
+ const char *extra_certs_inline
+ )
{
- ASSERT(NULL != ctx);
+ ASSERT(NULL != ctx);
- if (!ctx->crt_chain)
+ if (!ctx->crt_chain)
{
- ALLOC_OBJ_CLEAR (ctx->crt_chain, mbedtls_x509_crt);
+ ALLOC_OBJ_CLEAR(ctx->crt_chain, mbedtls_x509_crt);
}
- if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_inline)
+ if (!strcmp(extra_certs_file, INLINE_FILE_TAG) && extra_certs_inline)
{
- if (!mbed_ok(mbedtls_x509_crt_parse(ctx->crt_chain,
- (const unsigned char *) extra_certs_inline,
- strlen(extra_certs_inline)+1)))
- msg (M_FATAL, "Cannot load inline extra-certs file");
+ if (!mbed_ok(mbedtls_x509_crt_parse(ctx->crt_chain,
+ (const unsigned char *) extra_certs_inline,
+ strlen(extra_certs_inline)+1)))
+ {
+ msg(M_FATAL, "Cannot load inline extra-certs file");
+ }
}
- else
+ else
{
- if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->crt_chain, extra_certs_file)))
- msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file);
+ if (!mbed_ok(mbedtls_x509_crt_parse_file(ctx->crt_chain, extra_certs_file)))
+ {
+ msg(M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file);
+ }
}
}
@@ -596,131 +664,149 @@ tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file
* "Endless buffer"
*/
-static inline void buf_free_entry(buffer_entry *entry)
+static inline void
+buf_free_entry(buffer_entry *entry)
{
- if (NULL != entry)
+ if (NULL != entry)
{
- free(entry->data);
- free(entry);
+ free(entry->data);
+ free(entry);
}
}
-static void buf_free_entries(endless_buffer *buf)
+static void
+buf_free_entries(endless_buffer *buf)
{
- while(buf->first_block)
+ while (buf->first_block)
{
- buffer_entry *cur_block = buf->first_block;
- buf->first_block = cur_block->next_block;
- buf_free_entry(cur_block);
+ buffer_entry *cur_block = buf->first_block;
+ buf->first_block = cur_block->next_block;
+ buf_free_entry(cur_block);
}
- buf->last_block = NULL;
+ buf->last_block = NULL;
}
-static int endless_buf_read( endless_buffer *in, unsigned char * out, size_t out_len )
+static int
+endless_buf_read( endless_buffer *in, unsigned char *out, size_t out_len )
{
- size_t read_len = 0;
-
- if (in->first_block == NULL)
- return MBEDTLS_ERR_SSL_WANT_READ;
+ size_t read_len = 0;
- while (in->first_block != NULL && read_len < out_len)
+ if (in->first_block == NULL)
{
- int block_len = in->first_block->length - in->data_start;
- if (block_len <= out_len - read_len)
- {
- buffer_entry *cur_entry = in->first_block;
- memcpy(out + read_len, cur_entry->data + in->data_start,
- block_len);
-
- read_len += block_len;
-
- in->first_block = cur_entry->next_block;
- in->data_start = 0;
-
- if (in->first_block == NULL)
- in->last_block = NULL;
+ return MBEDTLS_ERR_SSL_WANT_READ;
+ }
- buf_free_entry(cur_entry);
- }
- else
- {
- memcpy(out + read_len, in->first_block->data + in->data_start,
- out_len - read_len);
- in->data_start += out_len - read_len;
- read_len = out_len;
- }
+ while (in->first_block != NULL && read_len < out_len)
+ {
+ int block_len = in->first_block->length - in->data_start;
+ if (block_len <= out_len - read_len)
+ {
+ buffer_entry *cur_entry = in->first_block;
+ memcpy(out + read_len, cur_entry->data + in->data_start,
+ block_len);
+
+ read_len += block_len;
+
+ in->first_block = cur_entry->next_block;
+ in->data_start = 0;
+
+ if (in->first_block == NULL)
+ {
+ in->last_block = NULL;
+ }
+
+ buf_free_entry(cur_entry);
+ }
+ else
+ {
+ memcpy(out + read_len, in->first_block->data + in->data_start,
+ out_len - read_len);
+ in->data_start += out_len - read_len;
+ read_len = out_len;
+ }
}
- return read_len;
+ return read_len;
}
-static int endless_buf_write( endless_buffer *out, const unsigned char *in, size_t len )
+static int
+endless_buf_write( endless_buffer *out, const unsigned char *in, size_t len )
{
- buffer_entry *new_block = malloc(sizeof(buffer_entry));
- if (NULL == new_block)
- return MBEDTLS_ERR_NET_SEND_FAILED;
+ buffer_entry *new_block = malloc(sizeof(buffer_entry));
+ if (NULL == new_block)
+ {
+ return MBEDTLS_ERR_NET_SEND_FAILED;
+ }
- new_block->data = malloc(len);
- if (NULL == new_block->data)
+ new_block->data = malloc(len);
+ if (NULL == new_block->data)
{
- free(new_block);
- return MBEDTLS_ERR_NET_SEND_FAILED;
+ free(new_block);
+ return MBEDTLS_ERR_NET_SEND_FAILED;
}
- new_block->length = len;
- new_block->next_block = NULL;
+ new_block->length = len;
+ new_block->next_block = NULL;
- memcpy(new_block->data, in, len);
+ memcpy(new_block->data, in, len);
- if (NULL == out->first_block)
- out->first_block = new_block;
+ if (NULL == out->first_block)
+ {
+ out->first_block = new_block;
+ }
- if (NULL != out->last_block)
- out->last_block->next_block = new_block;
+ if (NULL != out->last_block)
+ {
+ out->last_block->next_block = new_block;
+ }
- out->last_block = new_block;
+ out->last_block = new_block;
- return len;
+ return len;
}
-static int ssl_bio_read( void *ctx, unsigned char *out, size_t out_len)
+static int
+ssl_bio_read( void *ctx, unsigned char *out, size_t out_len)
{
- bio_ctx *my_ctx = (bio_ctx *) ctx;
- return endless_buf_read (&my_ctx->in, out, out_len);
+ bio_ctx *my_ctx = (bio_ctx *) ctx;
+ return endless_buf_read(&my_ctx->in, out, out_len);
}
-static int ssl_bio_write( void *ctx, const unsigned char *in, size_t in_len)
+static int
+ssl_bio_write( void *ctx, const unsigned char *in, size_t in_len)
{
- bio_ctx *my_ctx = (bio_ctx *) ctx;
- return endless_buf_write (&my_ctx->out, in, in_len);
+ bio_ctx *my_ctx = (bio_ctx *) ctx;
+ return endless_buf_write(&my_ctx->out, in, in_len);
}
-static void my_debug( void *ctx, int level, const char *file, int line,
- const char *str )
+static void
+my_debug( void *ctx, int level, const char *file, int line,
+ const char *str )
{
- int my_loglevel = (level < 3) ? D_TLS_DEBUG_MED : D_TLS_DEBUG;
- msg (my_loglevel, "mbed TLS msg (%s:%d): %s", file, line, str);
+ int my_loglevel = (level < 3) ? D_TLS_DEBUG_MED : D_TLS_DEBUG;
+ msg(my_loglevel, "mbed TLS msg (%s:%d): %s", file, line, str);
}
/*
* Further personalise the RNG using a hash of the public key
*/
-void tls_ctx_personalise_random(struct tls_root_ctx *ctx)
+void
+tls_ctx_personalise_random(struct tls_root_ctx *ctx)
{
- static char old_sha256_hash[32] = {0};
- unsigned char sha256_hash[32] = {0};
- mbedtls_ctr_drbg_context *cd_ctx = rand_ctx_get();
+ static char old_sha256_hash[32] = {0};
+ unsigned char sha256_hash[32] = {0};
+ mbedtls_ctr_drbg_context *cd_ctx = rand_ctx_get();
- if (NULL != ctx->crt_chain)
+ if (NULL != ctx->crt_chain)
{
- mbedtls_x509_crt *cert = ctx->crt_chain;
-
- mbedtls_sha256(cert->tbs.p, cert->tbs.len, sha256_hash, false);
- if ( 0 != memcmp(old_sha256_hash, sha256_hash, sizeof(sha256_hash)))
- {
- mbedtls_ctr_drbg_update(cd_ctx, sha256_hash, 32);
- memcpy(old_sha256_hash, sha256_hash, sizeof(old_sha256_hash));
- }
+ mbedtls_x509_crt *cert = ctx->crt_chain;
+
+ mbedtls_sha256(cert->tbs.p, cert->tbs.len, sha256_hash, false);
+ if (0 != memcmp(old_sha256_hash, sha256_hash, sizeof(sha256_hash)))
+ {
+ mbedtls_ctr_drbg_update(cd_ctx, sha256_hash, 32);
+ memcpy(old_sha256_hash, sha256_hash, sizeof(old_sha256_hash));
+ }
}
}
@@ -728,11 +814,11 @@ int
tls_version_max(void)
{
#if defined(MBEDTLS_SSL_MAJOR_VERSION_3) && defined(MBEDTLS_SSL_MINOR_VERSION_3)
- return TLS_VER_1_2;
+ return TLS_VER_1_2;
#elif defined(MBEDTLS_SSL_MAJOR_VERSION_3) && defined(MBEDTLS_SSL_MINOR_VERSION_2)
- return TLS_VER_1_1;
+ return TLS_VER_1_1;
#else
- return TLS_VER_1_0;
+ return TLS_VER_1_0;
#endif
}
@@ -740,391 +826,415 @@ tls_version_max(void)
* Convert an OpenVPN tls-version variable to mbed TLS format (i.e. a major and
* minor ssl version number).
*
- * @param tls_ver The tls-version variable to convert.
- * @param major Returns the TLS major version in mbed TLS format.
- * Must be a valid pointer.
- * @param minor Returns the TLS minor version in mbed TLS format.
- * Must be a valid pointer.
+ * @param tls_ver The tls-version variable to convert.
+ * @param major Returns the TLS major version in mbed TLS format.
+ * Must be a valid pointer.
+ * @param minor Returns the TLS minor version in mbed TLS format.
+ * Must be a valid pointer.
*/
-static void tls_version_to_major_minor(int tls_ver, int *major, int *minor) {
- ASSERT(major);
- ASSERT(minor);
-
- switch (tls_ver)
- {
- case TLS_VER_1_0:
- *major = MBEDTLS_SSL_MAJOR_VERSION_3;
- *minor = MBEDTLS_SSL_MINOR_VERSION_1;
- break;
- case TLS_VER_1_1:
- *major = MBEDTLS_SSL_MAJOR_VERSION_3;
- *minor = MBEDTLS_SSL_MINOR_VERSION_2;
- break;
- case TLS_VER_1_2:
- *major = MBEDTLS_SSL_MAJOR_VERSION_3;
- *minor = MBEDTLS_SSL_MINOR_VERSION_3;
- break;
- default:
- msg(M_FATAL, "%s: invalid TLS version %d", __func__, tls_ver);
- break;
- }
+static void
+tls_version_to_major_minor(int tls_ver, int *major, int *minor) {
+ ASSERT(major);
+ ASSERT(minor);
+
+ switch (tls_ver)
+ {
+ case TLS_VER_1_0:
+ *major = MBEDTLS_SSL_MAJOR_VERSION_3;
+ *minor = MBEDTLS_SSL_MINOR_VERSION_1;
+ break;
+
+ case TLS_VER_1_1:
+ *major = MBEDTLS_SSL_MAJOR_VERSION_3;
+ *minor = MBEDTLS_SSL_MINOR_VERSION_2;
+ break;
+
+ case TLS_VER_1_2:
+ *major = MBEDTLS_SSL_MAJOR_VERSION_3;
+ *minor = MBEDTLS_SSL_MINOR_VERSION_3;
+ break;
+
+ default:
+ msg(M_FATAL, "%s: invalid TLS version %d", __func__, tls_ver);
+ break;
+ }
}
void
backend_tls_ctx_reload_crl(struct tls_root_ctx *ctx, const char *crl_file,
- const char *crl_inline)
+ const char *crl_inline)
{
- ASSERT (crl_file);
+ ASSERT(crl_file);
- if (ctx->crl == NULL)
+ if (ctx->crl == NULL)
{
- ALLOC_OBJ_CLEAR(ctx->crl, mbedtls_x509_crl);
+ ALLOC_OBJ_CLEAR(ctx->crl, mbedtls_x509_crl);
}
- mbedtls_x509_crl_free(ctx->crl);
+ mbedtls_x509_crl_free(ctx->crl);
- if (!strcmp (crl_file, INLINE_FILE_TAG) && crl_inline)
+ if (!strcmp(crl_file, INLINE_FILE_TAG) && crl_inline)
{
- if (!mbed_ok(mbedtls_x509_crl_parse(ctx->crl,
- (const unsigned char *)crl_inline, strlen(crl_inline)+1)))
- {
- msg (M_WARN, "CRL: cannot parse inline CRL");
- goto err;
- }
+ if (!mbed_ok(mbedtls_x509_crl_parse(ctx->crl,
+ (const unsigned char *)crl_inline, strlen(crl_inline)+1)))
+ {
+ msg(M_WARN, "CRL: cannot parse inline CRL");
+ goto err;
+ }
}
- else
+ else
{
- if (!mbed_ok(mbedtls_x509_crl_parse_file(ctx->crl, crl_file)))
- {
- msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file);
- goto err;
- }
+ if (!mbed_ok(mbedtls_x509_crl_parse_file(ctx->crl, crl_file)))
+ {
+ msg(M_WARN, "CRL: cannot read CRL from file %s", crl_file);
+ goto err;
+ }
}
- return;
+ return;
err:
- mbedtls_x509_crl_free(ctx->crl);
+ mbedtls_x509_crl_free(ctx->crl);
}
-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)
+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);
-
- /* Initialise SSL config */
- mbedtls_ssl_config_init(&ks_ssl->ssl_config);
- mbedtls_ssl_config_defaults(&ks_ssl->ssl_config, ssl_ctx->endpoint,
- MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
+ ASSERT(NULL != ssl_ctx);
+ ASSERT(ks_ssl);
+ CLEAR(*ks_ssl);
+
+ /* Initialise SSL config */
+ mbedtls_ssl_config_init(&ks_ssl->ssl_config);
+ mbedtls_ssl_config_defaults(&ks_ssl->ssl_config, ssl_ctx->endpoint,
+ MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT);
#ifdef MBEDTLS_DEBUG_C
- mbedtls_debug_set_threshold(3);
+ mbedtls_debug_set_threshold(3);
#endif
- mbedtls_ssl_conf_dbg (&ks_ssl->ssl_config, my_debug, NULL);
- mbedtls_ssl_conf_rng (&ks_ssl->ssl_config, mbedtls_ctr_drbg_random,
- rand_ctx_get());
+ mbedtls_ssl_conf_dbg(&ks_ssl->ssl_config, my_debug, NULL);
+ mbedtls_ssl_conf_rng(&ks_ssl->ssl_config, mbedtls_ctr_drbg_random,
+ rand_ctx_get());
- if (ssl_ctx->allowed_ciphers)
- mbedtls_ssl_conf_ciphersuites (&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers);
+ if (ssl_ctx->allowed_ciphers)
+ {
+ mbedtls_ssl_conf_ciphersuites(&ks_ssl->ssl_config, ssl_ctx->allowed_ciphers);
+ }
- /* Disable record splitting (for now). OpenVPN assumes records are sent
- * unfragmented, and changing that will require thorough review and
- * testing. Since OpenVPN is not susceptible to BEAST, we can just
- * disable record splitting as a quick fix. */
+ /* Disable record splitting (for now). OpenVPN assumes records are sent
+ * unfragmented, and changing that will require thorough review and
+ * testing. Since OpenVPN is not susceptible to BEAST, we can just
+ * disable record splitting as a quick fix. */
#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING)
- mbedtls_ssl_conf_cbc_record_splitting (&ks_ssl->ssl_config,
- MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED);
+ mbedtls_ssl_conf_cbc_record_splitting(&ks_ssl->ssl_config,
+ MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED);
#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */
- /* Initialise authentication information */
- if (is_server)
- mbed_ok (mbedtls_ssl_conf_dh_param_ctx(&ks_ssl->ssl_config,
- ssl_ctx->dhm_ctx));
+ /* Initialise authentication information */
+ if (is_server)
+ {
+ mbed_ok(mbedtls_ssl_conf_dh_param_ctx(&ks_ssl->ssl_config,
+ ssl_ctx->dhm_ctx));
+ }
- mbed_ok (mbedtls_ssl_conf_own_cert(&ks_ssl->ssl_config, ssl_ctx->crt_chain,
- ssl_ctx->priv_key));
+ mbed_ok(mbedtls_ssl_conf_own_cert(&ks_ssl->ssl_config, ssl_ctx->crt_chain,
+ ssl_ctx->priv_key));
- /* Initialise SSL verification */
+ /* Initialise SSL verification */
#if P2MP_SERVER
- if (session->opt->ssl_flags & SSLF_CLIENT_CERT_OPTIONAL)
+ if (session->opt->ssl_flags & SSLF_CLIENT_CERT_OPTIONAL)
{
- mbedtls_ssl_conf_authmode(&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_OPTIONAL);
+ mbedtls_ssl_conf_authmode(&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_OPTIONAL);
}
- else if (!(session->opt->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED))
+ else if (!(session->opt->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED))
#endif
- {
- mbedtls_ssl_conf_authmode (&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_REQUIRED);
- }
- mbedtls_ssl_conf_verify (&ks_ssl->ssl_config, verify_callback, session);
-
- /* TODO: mbed TLS does not currently support sending the CA chain to the client */
- mbedtls_ssl_conf_ca_chain (&ks_ssl->ssl_config, ssl_ctx->ca_chain, ssl_ctx->crl);
-
- /* Initialize minimum TLS version */
- {
- const int tls_version_min =
- (session->opt->ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT) &
- SSLF_TLS_VERSION_MIN_MASK;
-
- /* default to TLS 1.0 */
- int major = MBEDTLS_SSL_MAJOR_VERSION_3;
- int minor = MBEDTLS_SSL_MINOR_VERSION_1;
-
- if (tls_version_min > TLS_VER_UNSPEC)
- tls_version_to_major_minor(tls_version_min, &major, &minor);
-
- mbedtls_ssl_conf_min_version(&ks_ssl->ssl_config, major, minor);
- }
-
- /* Initialize maximum TLS version */
- {
- const int tls_version_max =
- (session->opt->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) &
- SSLF_TLS_VERSION_MAX_MASK;
-
- if (tls_version_max > TLS_VER_UNSPEC)
- {
- int major, minor;
- tls_version_to_major_minor(tls_version_max, &major, &minor);
- mbedtls_ssl_conf_max_version(&ks_ssl->ssl_config, major, minor);
- }
- }
-
- /* Initialise SSL context */
- ALLOC_OBJ_CLEAR(ks_ssl->ctx, mbedtls_ssl_context);
- mbedtls_ssl_init(ks_ssl->ctx);
- mbedtls_ssl_setup(ks_ssl->ctx, &ks_ssl->ssl_config);
-
- /* Initialise BIOs */
- CLEAR (ks_ssl->bio_ctx);
- mbedtls_ssl_set_bio (ks_ssl->ctx, &ks_ssl->bio_ctx, ssl_bio_write,
- ssl_bio_read, NULL);
+ {
+ mbedtls_ssl_conf_authmode(&ks_ssl->ssl_config, MBEDTLS_SSL_VERIFY_REQUIRED);
+ }
+ mbedtls_ssl_conf_verify(&ks_ssl->ssl_config, verify_callback, session);
+
+ /* TODO: mbed TLS does not currently support sending the CA chain to the client */
+ mbedtls_ssl_conf_ca_chain(&ks_ssl->ssl_config, ssl_ctx->ca_chain, ssl_ctx->crl);
+
+ /* Initialize minimum TLS version */
+ {
+ const int tls_version_min =
+ (session->opt->ssl_flags >> SSLF_TLS_VERSION_MIN_SHIFT)
+ &SSLF_TLS_VERSION_MIN_MASK;
+
+ /* default to TLS 1.0 */
+ int major = MBEDTLS_SSL_MAJOR_VERSION_3;
+ int minor = MBEDTLS_SSL_MINOR_VERSION_1;
+
+ if (tls_version_min > TLS_VER_UNSPEC)
+ {
+ tls_version_to_major_minor(tls_version_min, &major, &minor);
+ }
+
+ mbedtls_ssl_conf_min_version(&ks_ssl->ssl_config, major, minor);
+ }
+
+ /* Initialize maximum TLS version */
+ {
+ const int tls_version_max =
+ (session->opt->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT)
+ &SSLF_TLS_VERSION_MAX_MASK;
+
+ if (tls_version_max > TLS_VER_UNSPEC)
+ {
+ int major, minor;
+ tls_version_to_major_minor(tls_version_max, &major, &minor);
+ mbedtls_ssl_conf_max_version(&ks_ssl->ssl_config, major, minor);
+ }
+ }
+
+ /* Initialise SSL context */
+ ALLOC_OBJ_CLEAR(ks_ssl->ctx, mbedtls_ssl_context);
+ mbedtls_ssl_init(ks_ssl->ctx);
+ mbedtls_ssl_setup(ks_ssl->ctx, &ks_ssl->ssl_config);
+
+ /* Initialise BIOs */
+ CLEAR(ks_ssl->bio_ctx);
+ mbedtls_ssl_set_bio(ks_ssl->ctx, &ks_ssl->bio_ctx, ssl_bio_write,
+ ssl_bio_read, NULL);
}
void
key_state_ssl_free(struct key_state_ssl *ks_ssl)
{
- if (ks_ssl) {
- if (ks_ssl->ctx)
- {
- mbedtls_ssl_free(ks_ssl->ctx);
- free(ks_ssl->ctx);
- }
- mbedtls_ssl_config_free(&ks_ssl->ssl_config);
- buf_free_entries(&ks_ssl->bio_ctx.in);
- buf_free_entries(&ks_ssl->bio_ctx.out);
- CLEAR(*ks_ssl);
- }
+ if (ks_ssl)
+ {
+ if (ks_ssl->ctx)
+ {
+ mbedtls_ssl_free(ks_ssl->ctx);
+ free(ks_ssl->ctx);
+ }
+ mbedtls_ssl_config_free(&ks_ssl->ssl_config);
+ buf_free_entries(&ks_ssl->bio_ctx.in);
+ buf_free_entries(&ks_ssl->bio_ctx.out);
+ CLEAR(*ks_ssl);
+ }
}
int
-key_state_write_plaintext (struct key_state_ssl *ks, struct buffer *buf)
+key_state_write_plaintext(struct key_state_ssl *ks, struct buffer *buf)
{
- int retval = 0;
+ int retval = 0;
- ASSERT (buf);
+ ASSERT(buf);
- retval = key_state_write_plaintext_const(ks, BPTR(buf), BLEN(buf));
+ retval = key_state_write_plaintext_const(ks, BPTR(buf), BLEN(buf));
- if (1 == retval)
+ if (1 == retval)
{
- 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;
}
- return retval;
+ return retval;
}
int
-key_state_write_plaintext_const (struct key_state_ssl *ks, const uint8_t *data, int len)
+key_state_write_plaintext_const(struct key_state_ssl *ks, const uint8_t *data, int len)
{
- int retval = 0;
- perf_push (PERF_BIO_WRITE_PLAINTEXT);
+ int retval = 0;
+ perf_push(PERF_BIO_WRITE_PLAINTEXT);
- ASSERT (NULL != ks);
- ASSERT (len >= 0);
+ ASSERT(NULL != ks);
+ ASSERT(len >= 0);
- if (0 == len)
+ if (0 == len)
{
- perf_pop ();
- return 0;
+ perf_pop();
+ return 0;
}
- ASSERT (data);
+ ASSERT(data);
- retval = mbedtls_ssl_write(ks->ctx, data, len);
+ retval = mbedtls_ssl_write(ks->ctx, data, len);
- if (retval < 0)
+ if (retval < 0)
{
- perf_pop ();
- if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
- return 0;
- mbed_log_err (D_TLS_ERRORS, retval,
- "TLS ERROR: write tls_write_plaintext_const error");
- return -1;
+ perf_pop();
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
+ {
+ return 0;
+ }
+ mbed_log_err(D_TLS_ERRORS, retval,
+ "TLS ERROR: write tls_write_plaintext_const error");
+ return -1;
}
- if (retval != len)
+ if (retval != len)
{
- msg (D_TLS_ERRORS,
- "TLS ERROR: write tls_write_plaintext_const incomplete %d/%d",
- retval, len);
- perf_pop ();
- return -1;
+ msg(D_TLS_ERRORS,
+ "TLS ERROR: write tls_write_plaintext_const incomplete %d/%d",
+ retval, len);
+ perf_pop();
+ return -1;
}
- /* successful write */
- dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_plaintext_const %d bytes", retval);
+ /* successful write */
+ dmsg(D_HANDSHAKE_VERBOSE, "write tls_write_plaintext_const %d bytes", retval);
- perf_pop ();
- return 1;
+ perf_pop();
+ return 1;
}
int
-key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf,
- int maxlen)
+key_state_read_ciphertext(struct key_state_ssl *ks, struct buffer *buf,
+ int maxlen)
{
- int retval = 0;
- int len = 0;
+ int retval = 0;
+ int len = 0;
- perf_push (PERF_BIO_READ_CIPHERTEXT);
+ perf_push(PERF_BIO_READ_CIPHERTEXT);
- ASSERT (NULL != ks);
- ASSERT (buf);
- ASSERT (buf->len >= 0);
+ ASSERT(NULL != ks);
+ ASSERT(buf);
+ ASSERT(buf->len >= 0);
- if (buf->len)
+ if (buf->len)
{
- perf_pop ();
- return 0;
+ perf_pop();
+ return 0;
}
- len = buf_forward_capacity (buf);
- if (maxlen < len)
- len = maxlen;
+ len = buf_forward_capacity(buf);
+ if (maxlen < len)
+ {
+ len = maxlen;
+ }
- retval = endless_buf_read(&ks->bio_ctx.out, BPTR(buf), len);
+ retval = endless_buf_read(&ks->bio_ctx.out, BPTR(buf), len);
- /* Error during read, check for retry error */
- if (retval < 0)
+ /* Error during read, check for retry error */
+ if (retval < 0)
{
- perf_pop ();
- if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
- return 0;
- mbed_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_ciphertext error");
- buf->len = 0;
- return -1;
+ perf_pop();
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
+ {
+ return 0;
+ }
+ mbed_log_err(D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_ciphertext error");
+ buf->len = 0;
+ return -1;
}
- /* Nothing read, try again */
- if (0 == retval)
+ /* Nothing read, try again */
+ if (0 == retval)
{
- buf->len = 0;
- perf_pop ();
- return 0;
+ buf->len = 0;
+ perf_pop();
+ return 0;
}
- /* successful read */
- dmsg (D_HANDSHAKE_VERBOSE, "read tls_read_ciphertext %d bytes", retval);
- buf->len = retval;
- perf_pop ();
- return 1;
+ /* successful read */
+ dmsg(D_HANDSHAKE_VERBOSE, "read tls_read_ciphertext %d bytes", retval);
+ buf->len = retval;
+ perf_pop();
+ return 1;
}
int
-key_state_write_ciphertext (struct key_state_ssl *ks, struct buffer *buf)
+key_state_write_ciphertext(struct key_state_ssl *ks, struct buffer *buf)
{
- int retval = 0;
- perf_push (PERF_BIO_WRITE_CIPHERTEXT);
+ int retval = 0;
+ perf_push(PERF_BIO_WRITE_CIPHERTEXT);
- ASSERT (NULL != ks);
- ASSERT (buf);
- ASSERT (buf->len >= 0);
+ ASSERT(NULL != ks);
+ ASSERT(buf);
+ ASSERT(buf->len >= 0);
- if (0 == buf->len)
+ if (0 == buf->len)
{
- perf_pop ();
- return 0;
+ perf_pop();
+ return 0;
}
- retval = endless_buf_write(&ks->bio_ctx.in, BPTR(buf), buf->len);
+ retval = endless_buf_write(&ks->bio_ctx.in, BPTR(buf), buf->len);
- if (retval < 0)
+ if (retval < 0)
{
- perf_pop ();
-
- if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
- return 0;
- mbed_log_err (D_TLS_ERRORS, retval,
- "TLS ERROR: write tls_write_ciphertext error");
- return -1;
+ perf_pop();
+
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
+ {
+ return 0;
+ }
+ mbed_log_err(D_TLS_ERRORS, retval,
+ "TLS ERROR: write tls_write_ciphertext error");
+ return -1;
}
- if (retval != buf->len)
+ if (retval != buf->len)
{
- msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_ciphertext incomplete %d/%d",
- retval, buf->len);
- perf_pop ();
- return -1;
+ msg(D_TLS_ERRORS, "TLS ERROR: write tls_write_ciphertext incomplete %d/%d",
+ retval, buf->len);
+ perf_pop();
+ return -1;
}
- /* successful write */
- dmsg (D_HANDSHAKE_VERBOSE, "write tls_write_ciphertext %d bytes", retval);
+ /* successful write */
+ dmsg(D_HANDSHAKE_VERBOSE, "write tls_write_ciphertext %d bytes", retval);
- 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;
- perf_pop ();
- return 1;
+ perf_pop();
+ return 1;
}
int
-key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,
- int maxlen)
+key_state_read_plaintext(struct key_state_ssl *ks, struct buffer *buf,
+ int maxlen)
{
- int retval = 0;
- int len = 0;
+ int retval = 0;
+ int len = 0;
- perf_push (PERF_BIO_READ_PLAINTEXT);
+ perf_push(PERF_BIO_READ_PLAINTEXT);
- ASSERT (NULL != ks);
- ASSERT (buf);
- ASSERT (buf->len >= 0);
+ ASSERT(NULL != ks);
+ ASSERT(buf);
+ ASSERT(buf->len >= 0);
- if (buf->len)
+ if (buf->len)
{
- perf_pop ();
- return 0;
+ perf_pop();
+ return 0;
}
- len = buf_forward_capacity (buf);
- if (maxlen < len)
- len = maxlen;
+ len = buf_forward_capacity(buf);
+ if (maxlen < len)
+ {
+ len = maxlen;
+ }
- retval = mbedtls_ssl_read(ks->ctx, BPTR(buf), len);
+ retval = mbedtls_ssl_read(ks->ctx, BPTR(buf), len);
- /* Error during read, check for retry error */
- if (retval < 0)
+ /* Error during read, check for retry error */
+ if (retval < 0)
{
- if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
- return 0;
- mbed_log_err (D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_plaintext error");
- buf->len = 0;
- perf_pop ();
- return -1;
+ if (MBEDTLS_ERR_SSL_WANT_WRITE == retval || MBEDTLS_ERR_SSL_WANT_READ == retval)
+ {
+ return 0;
+ }
+ mbed_log_err(D_TLS_ERRORS, retval, "TLS_ERROR: read tls_read_plaintext error");
+ buf->len = 0;
+ perf_pop();
+ return -1;
}
- /* Nothing read, try again */
- if (0 == retval)
+ /* Nothing read, try again */
+ if (0 == retval)
{
- buf->len = 0;
- perf_pop ();
- return 0;
+ buf->len = 0;
+ perf_pop();
+ return 0;
}
- /* successful read */
- dmsg (D_HANDSHAKE_VERBOSE, "read tls_read_plaintext %d bytes", retval);
- buf->len = retval;
+ /* successful read */
+ dmsg(D_HANDSHAKE_VERBOSE, "read tls_read_plaintext %d bytes", retval);
+ buf->len = retval;
- perf_pop ();
- return 1;
+ perf_pop();
+ return 1;
}
/* **************************************
@@ -1135,82 +1245,88 @@ key_state_read_plaintext (struct key_state_ssl *ks, 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 mbedtls_x509_crt *cert;
- char s1[256];
- char s2[256];
-
- s1[0] = s2[0] = 0;
- openvpn_snprintf (s1, sizeof (s1), "%s %s, cipher %s",
- prefix,
- mbedtls_ssl_get_version (ks_ssl->ctx),
- mbedtls_ssl_get_ciphersuite (ks_ssl->ctx));
-
- cert = mbedtls_ssl_get_peer_cert (ks_ssl->ctx);
- if (cert != NULL)
+ const mbedtls_x509_crt *cert;
+ char s1[256];
+ char s2[256];
+
+ s1[0] = s2[0] = 0;
+ openvpn_snprintf(s1, sizeof(s1), "%s %s, cipher %s",
+ prefix,
+ mbedtls_ssl_get_version(ks_ssl->ctx),
+ mbedtls_ssl_get_ciphersuite(ks_ssl->ctx));
+
+ cert = mbedtls_ssl_get_peer_cert(ks_ssl->ctx);
+ if (cert != NULL)
{
- openvpn_snprintf (s2, sizeof (s2), ", %u bit key",
- (unsigned int) mbedtls_pk_get_bitlen (&cert->pk));
+ openvpn_snprintf(s2, sizeof(s2), ", %u bit key",
+ (unsigned int) mbedtls_pk_get_bitlen(&cert->pk));
}
- msg (D_HANDSHAKE, "%s%s", s1, s2);
+ 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;
- const int *ciphers = mbedtls_ssl_list_ciphersuites ();
+ struct tls_root_ctx tls_ctx;
+ const int *ciphers = mbedtls_ssl_list_ciphersuites();
- tls_ctx_server_new(&tls_ctx);
- tls_ctx_restrict_ciphers(&tls_ctx, cipher_list);
+ tls_ctx_server_new(&tls_ctx);
+ tls_ctx_restrict_ciphers(&tls_ctx, cipher_list);
- if (tls_ctx.allowed_ciphers)
- ciphers = tls_ctx.allowed_ciphers;
+ if (tls_ctx.allowed_ciphers)
+ {
+ ciphers = tls_ctx.allowed_ciphers;
+ }
#ifndef ENABLE_SMALL
- printf ("Available TLS Ciphers,\n");
- printf ("listed in order of preference:\n\n");
+ printf("Available TLS Ciphers,\n");
+ printf("listed in order of preference:\n\n");
#endif
- while (*ciphers != 0)
+ while (*ciphers != 0)
{
- printf ("%s\n", mbedtls_ssl_get_ciphersuite_name (*ciphers));
- ciphers++;
+ printf("%s\n", mbedtls_ssl_get_ciphersuite_name(*ciphers));
+ ciphers++;
}
- printf ("\n" SHOW_TLS_CIPHER_LIST_WARNING);
+ printf("\n" SHOW_TLS_CIPHER_LIST_WARNING);
- tls_ctx_free(&tls_ctx);
+ tls_ctx_free(&tls_ctx);
}
void
-show_available_curves (void)
+show_available_curves(void)
{
- const mbedtls_ecp_curve_info *pcurve = mbedtls_ecp_curve_list ();
+ const mbedtls_ecp_curve_info *pcurve = mbedtls_ecp_curve_list();
- if (NULL == pcurve)
- msg (M_FATAL, "Cannot retrieve curve list from mbed TLS");
+ if (NULL == pcurve)
+ {
+ msg(M_FATAL, "Cannot retrieve curve list from mbed TLS");
+ }
- /* Print curve list */
- printf ("Available Elliptic curves, listed in order of preference:\n\n");
- while (MBEDTLS_ECP_DP_NONE != pcurve->grp_id)
+ /* Print curve list */
+ printf("Available Elliptic curves, listed in order of preference:\n\n");
+ while (MBEDTLS_ECP_DP_NONE != pcurve->grp_id)
{
- printf("%s\n", pcurve->name);
- pcurve++;
+ printf("%s\n", pcurve->name);
+ pcurve++;
}
}
void
-get_highest_preference_tls_cipher (char *buf, int size)
+get_highest_preference_tls_cipher(char *buf, int size)
{
- const char *cipher_name;
- const int *ciphers = mbedtls_ssl_list_ciphersuites();
- if (*ciphers == 0)
- msg (M_FATAL, "Cannot retrieve list of supported SSL ciphers.");
+ const char *cipher_name;
+ const int *ciphers = mbedtls_ssl_list_ciphersuites();
+ if (*ciphers == 0)
+ {
+ msg(M_FATAL, "Cannot retrieve list of supported SSL ciphers.");
+ }
- cipher_name = mbedtls_ssl_get_ciphersuite_name(*ciphers);
- strncpynt (buf, cipher_name, size);
+ cipher_name = mbedtls_ssl_get_ciphersuite_name(*ciphers);
+ strncpynt(buf, cipher_name, size);
}
const char *
@@ -1219,7 +1335,7 @@ get_ssl_library_version(void)
static char mbedtls_version[30];
unsigned int pv = mbedtls_version_get_number();
sprintf( mbedtls_version, "mbed TLS %d.%d.%d",
- (pv>>24)&0xff, (pv>>16)&0xff, (pv>>8)&0xff );
+ (pv>>24)&0xff, (pv>>16)&0xff, (pv>>8)&0xff );
return mbedtls_version;
}