summaryrefslogtreecommitdiff
path: root/main/openvpn/src
diff options
context:
space:
mode:
Diffstat (limited to 'main/openvpn/src')
-rw-r--r--main/openvpn/src/openvpn/crypto.c363
-rw-r--r--main/openvpn/src/openvpn/crypto.h37
-rw-r--r--main/openvpn/src/openvpn/crypto_backend.h84
-rw-r--r--main/openvpn/src/openvpn/crypto_openssl.c162
-rw-r--r--main/openvpn/src/openvpn/crypto_openssl.h35
-rw-r--r--main/openvpn/src/openvpn/crypto_polarssl.c199
-rw-r--r--main/openvpn/src/openvpn/crypto_polarssl.h43
-rw-r--r--main/openvpn/src/openvpn/error.c29
-rw-r--r--main/openvpn/src/openvpn/error.h11
-rw-r--r--main/openvpn/src/openvpn/forward.c20
-rw-r--r--main/openvpn/src/openvpn/httpdigest.c46
-rw-r--r--main/openvpn/src/openvpn/httpdigest.h2
-rw-r--r--main/openvpn/src/openvpn/init.c114
-rw-r--r--main/openvpn/src/openvpn/mroute.h12
-rw-r--r--main/openvpn/src/openvpn/mudp.c16
-rw-r--r--main/openvpn/src/openvpn/multi.c10
-rw-r--r--main/openvpn/src/openvpn/ntlm.c28
-rw-r--r--main/openvpn/src/openvpn/openvpn.h5
-rw-r--r--main/openvpn/src/openvpn/options.c43
-rw-r--r--main/openvpn/src/openvpn/packet_id.c6
-rw-r--r--main/openvpn/src/openvpn/packet_id.h3
-rw-r--r--main/openvpn/src/openvpn/ssl.c163
-rw-r--r--main/openvpn/src/openvpn/ssl.h16
-rw-r--r--main/openvpn/src/openvpn/ssl_backend.h11
-rw-r--r--main/openvpn/src/openvpn/ssl_common.h12
-rw-r--r--main/openvpn/src/openvpn/ssl_openssl.c123
-rw-r--r--main/openvpn/src/openvpn/ssl_polarssl.c247
-rw-r--r--main/openvpn/src/openvpn/ssl_verify_polarssl.c26
28 files changed, 599 insertions, 1267 deletions
diff --git a/main/openvpn/src/openvpn/crypto.c b/main/openvpn/src/openvpn/crypto.c
index 1aaefbb4..69df29de 100644
--- a/main/openvpn/src/openvpn/crypto.c
+++ b/main/openvpn/src/openvpn/crypto.c
@@ -65,61 +65,6 @@
#define CRYPT_ERROR(format) \
do { msg (D_CRYPT_ERRORS, "%s: " format, error_prefix); goto error_exit; } while (false)
-static void
-crypto_options_debug(const unsigned int flags, const char * prefix,
- const struct crypto_options *opt) {
- struct gc_arena gc = gc_new();
-
- const char *encrypt_cipher = "none";
- const char *encrypt_impl_iv = "none";
-
- const char *decrypt_cipher = "none";
- const char *decrypt_impl_iv = "none";
-
- ASSERT(opt);
-
- const cipher_kt_t *cipher;
-
- if (opt->key_ctx_bi.encrypt.cipher) {
- const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt;
-
- cipher = cipher_ctx_get_cipher_kt(ctx->cipher);
- if (cipher) encrypt_cipher = cipher_kt_name(cipher);
-
- encrypt_impl_iv = ctx->implicit_iv_len
- ? format_hex(ctx->implicit_iv, ctx->implicit_iv_len, 0, &gc)
- : "NULL";
- }
-
- if (opt->key_ctx_bi.decrypt.cipher) {
- const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt;
-
- cipher = cipher_ctx_get_cipher_kt(ctx->cipher);
- if (cipher) decrypt_cipher = cipher_kt_name(cipher);
-
- decrypt_impl_iv = ctx->implicit_iv_len
- ? format_hex(ctx->implicit_iv, ctx->implicit_iv_len, 0, &gc)
- : "NULL";
- }
-
- dmsg(flags, "%s: crypto options (%p) {\n"
- " flags = %x\n"
- " encrypt cipher = %s\n"
- " encr implicit iv = %s\n"
- " decrypt cipher = %s\n"
- " encr implicit iv = %s\n"
- "}",
- prefix,
- opt,
- opt->flags,
- encrypt_cipher,
- encrypt_impl_iv,
- decrypt_cipher,
- decrypt_impl_iv);
-
- gc_free(&gc);
-}
-
/**
* As memcmp(), but constant-time.
* Returns 0 when data is equal, non-zero otherwise.
@@ -140,22 +85,22 @@ memcmp_constant_time (const void *a, const void *b, size_t size) {
void
openvpn_encrypt (struct buffer *buf, struct buffer work,
- struct crypto_options *opt, const struct frame* frame)
+ const struct crypto_options *opt,
+ const struct frame* frame)
{
struct gc_arena gc;
- const cipher_kt_t *cipher_kt = NULL;
gc_init (&gc);
- if (buf->len > 0 && opt)
+ if (buf->len > 0 && opt->key_ctx_bi)
{
- const struct key_ctx *ctx = &opt->key_ctx_bi.encrypt;
+ struct key_ctx *ctx = &opt->key_ctx_bi->encrypt;
/* Do Encrypt from buf -> work */
if (ctx->cipher)
{
uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
const int iv_size = cipher_ctx_iv_length (ctx->cipher);
- cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
+ const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
int outlen;
if (cipher_kt_mode_cbc(cipher_kt))
@@ -166,11 +111,11 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
if (opt->flags & CO_USE_IV)
prng_bytes (iv_buf, iv_size);
- /* Put packet ID in plaintext buffer */
- if (packet_id_initialized(&opt->packet_id))
+ /* Put packet ID in plaintext buffer or IV, depending on cipher mode */
+ if (opt->packet_id)
{
struct packet_id_net pin;
- packet_id_alloc_outgoing (&opt->packet_id.send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
+ packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true));
}
}
@@ -179,38 +124,15 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
struct packet_id_net pin;
struct buffer b;
- /* IV and packet-ID required for this mode. */
- ASSERT (opt->flags & CO_USE_IV);
- ASSERT (packet_id_initialized(&opt->packet_id));
+ ASSERT (opt->flags & CO_USE_IV); /* IV and packet-ID required */
+ ASSERT (opt->packet_id); /* for this mode. */
- packet_id_alloc_outgoing (&opt->packet_id.send, &pin, true);
+ packet_id_alloc_outgoing (&opt->packet_id->send, &pin, true);
memset (iv_buf, 0, iv_size);
buf_set_write (&b, iv_buf, iv_size);
ASSERT (packet_id_write (&pin, &b, true, false));
}
- else if (cipher_kt_mode_aead (cipher_kt))
- {
- struct packet_id_net pin;
- struct buffer b;
-
- /* IV, packet-ID and implicit IV required for this mode. */
- ASSERT (opt->flags & CO_USE_IV);
- ASSERT (iv_size >= 12);
- ASSERT (packet_id_initialized(&opt->packet_id));
- ASSERT (ctx->implicit_iv_len);
-
- /* Prepare IV buffer */
- memset(iv_buf, 0, iv_size);
- buf_set_write (&b, iv_buf, iv_size);
-
- /* IV starts with implicit IV (must be unique for each session) */
- ASSERT (buf_write (&b, ctx->implicit_iv, ctx->implicit_iv_len));
-
- /* Append packet counter to make the IV unique for packet */
- packet_id_alloc_outgoing (&opt->packet_id.send, &pin, true);
- ASSERT (packet_id_write (&pin, &b, false, false));
- }
- else /* We only support CBC, CFB, OFB, or AEAD modes right now */
+ else /* We only support CBC, CFB, or OFB modes right now */
{
ASSERT (0);
}
@@ -229,8 +151,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
ASSERT (cipher_ctx_reset(ctx->cipher, iv_buf));
/* Buffer overflow check */
- int block_size = cipher_ctx_block_size(ctx->cipher);
- if (!buf_safe (&work, buf->len + block_size))
+ if (!buf_safe (&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
{
msg (D_CRYPT_ERRORS, "ENCRYPT: buffer size error, bc=%d bo=%d bl=%d wc=%d wo=%d wl=%d cbs=%d",
buf->capacity,
@@ -239,16 +160,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
work.capacity,
work.offset,
work.len,
- block_size);
+ cipher_ctx_block_size (ctx->cipher));
goto err;
}
- /* For AEAD ciphers, we need to update with the AD before ciphertext */
- if (cipher_kt_mode_aead (cipher_kt))
- {
- ASSERT (cipher_ctx_update_ad (ctx->cipher, iv_buf, iv_size));
- }
-
/* Encrypt packet ID, payload */
ASSERT (cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)));
work.len += outlen;
@@ -264,11 +179,9 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
/* prepend the IV to the ciphertext */
if (opt->flags & CO_USE_IV)
{
- uint8_t *output = buf_prepend (&work,
- iv_size - ctx->implicit_iv_len);
+ uint8_t *output = buf_prepend (&work, iv_size);
ASSERT (output);
- memcpy (output, iv_buf + ctx->implicit_iv_len,
- iv_size - ctx->implicit_iv_len);
+ memcpy (output, iv_buf, iv_size);
}
dmsg (D_PACKET_CONTENT, "ENCRYPT TO: %s",
@@ -276,10 +189,10 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
}
else /* No Encryption */
{
- if (packet_id_initialized(&opt->packet_id))
+ if (opt->packet_id)
{
struct packet_id_net pin;
- packet_id_alloc_outgoing (&opt->packet_id.send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
+ packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM));
ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true));
}
work = *buf;
@@ -296,15 +209,6 @@ openvpn_encrypt (struct buffer *buf, struct buffer work,
ASSERT (output);
hmac_ctx_final (ctx->hmac, output);
}
- else if (cipher_kt && cipher_kt_mode_aead(cipher_kt))
- {
- int tag_len = cipher_kt_tag_size (cipher_kt);
- uint8_t* output = NULL;
-
- output = buf_prepend (&work, tag_len);
- ASSERT (output);
- ASSERT (cipher_ctx_get_tag (ctx->cipher, output, tag_len));
- }
*buf = work;
}
@@ -333,7 +237,7 @@ int verify_hmac(struct buffer *buf, struct key_ctx *ctx, int offset)
return 0;
hmac_ctx_update (ctx->hmac, BPTR (buf) + hmac_len + offset,
- BLEN (buf) - hmac_len - offset);
+ BLEN (buf) - hmac_len - offset);
hmac_ctx_final (ctx->hmac, local_hmac);
/* Compare locally computed HMAC with packet HMAC */
@@ -353,20 +257,19 @@ int verify_hmac(struct buffer *buf, struct key_ctx *ctx, int offset)
*/
bool
openvpn_decrypt (struct buffer *buf, struct buffer work,
- struct crypto_options *opt, const struct frame* frame)
+ const struct crypto_options *opt,
+ const struct frame* frame)
{
static const char error_prefix[] = "Authenticate/Decrypt packet error";
struct gc_arena gc;
gc_init (&gc);
- if (buf->len > 0 && opt)
+ if (buf->len > 0 && opt->key_ctx_bi)
{
- const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt;
+ struct key_ctx *ctx = &opt->key_ctx_bi->decrypt;
struct packet_id_net pin;
bool have_pin = false;
- crypto_options_debug(D_CRYPTO_DEBUG, __func__, opt);
-
/* Verify the HMAC */
if (ctx->hmac)
{
@@ -377,44 +280,25 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
}
/* Decrypt packet ID + payload */
+
if (ctx->cipher)
{
const int iv_size = cipher_ctx_iv_length (ctx->cipher);
const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
- int tag_size = 0;
- uint8_t tag_buf[MAX_HMAC_KEY_LENGTH]; /* tag of AEAD ciphertext */
int outlen;
- int retval = 0;
/* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */
ASSERT (buf_init (&work, FRAME_HEADROOM_ADJ (frame, FRAME_HEADROOM_MARKER_DECRYPT)));
- /* for AEAD ciphers, keep the tag value to feed in later */
- CLEAR (tag_buf);
- if (cipher_kt_mode_aead(cipher_kt))
- {
- tag_size = cipher_kt_tag_size(cipher_kt);
- if (buf->len < tag_size)
- CRYPT_ERROR ("missing tag");
- memcpy (tag_buf, BPTR (buf), tag_size);
- ASSERT (buf_advance (buf, tag_size));
- }
-
/* use IV if user requested it */
CLEAR (iv_buf);
if (opt->flags & CO_USE_IV)
{
- ASSERT (ctx->implicit_iv_len <= iv_size);
- if (ctx->implicit_iv_len + buf->len < iv_size)
+ if (buf->len < iv_size)
CRYPT_ERROR ("missing IV info");
-
- /* Get implicit part of IV */
- memcpy (iv_buf, ctx->implicit_iv, ctx->implicit_iv_len);
- /* Read explicit part of IV from packet */
- memcpy (iv_buf + ctx->implicit_iv_len, BPTR (buf),
- iv_size - ctx->implicit_iv_len);
- ASSERT (buf_advance (buf, iv_size - ctx->implicit_iv_len));
+ memcpy (iv_buf, BPTR (buf), iv_size);
+ ASSERT (buf_advance (buf, iv_size));
}
/* show the IV's initial state */
@@ -432,25 +316,13 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
if (!buf_safe (&work, buf->len))
CRYPT_ERROR ("buffer overflow");
- /* feed in tag and the authenticated data for AEAD mode ciphers */
- if (cipher_kt_mode_aead(cipher_kt))
- {
- ASSERT (cipher_ctx_update_ad (ctx->cipher, iv_buf, iv_size));
- }
-
/* Decrypt packet ID, payload */
if (!cipher_ctx_update (ctx->cipher, BPTR (&work), &outlen, BPTR (buf), BLEN (buf)))
CRYPT_ERROR ("cipher update failed");
work.len += outlen;
/* Flush the decryption buffer */
- if (cipher_kt_mode_aead(cipher_kt)) {
- retval = cipher_ctx_final_check_tag (ctx->cipher, BPTR (&work) + outlen, &outlen, tag_buf, tag_size);
- } else {
- retval = cipher_ctx_final (ctx->cipher, BPTR (&work) + outlen, &outlen);
- }
-
- if (!retval)
+ if (!cipher_ctx_final (ctx->cipher, BPTR (&work) + outlen, &outlen))
CRYPT_ERROR ("cipher final failed");
work.len += outlen;
@@ -461,30 +333,26 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
{
if (cipher_kt_mode_cbc(cipher_kt))
{
- if (packet_id_initialized(&opt->packet_id))
+ if (opt->packet_id)
{
if (!packet_id_read (&pin, &work, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)))
CRYPT_ERROR ("error reading CBC packet-id");
have_pin = true;
}
}
- else if (cipher_kt_mode_ofb_cfb(cipher_kt) ||
- cipher_kt_mode_aead(cipher_kt))
+ else if (cipher_kt_mode_ofb_cfb(cipher_kt))
{
struct buffer b;
ASSERT (opt->flags & CO_USE_IV); /* IV and packet-ID required */
- ASSERT (packet_id_initialized(&opt->packet_id)); /* for this mode. */
-
- ASSERT (ctx->implicit_iv_len <= iv_size);
- buf_set_read (&b, iv_buf + ctx->implicit_iv_len,
- iv_size - ctx->implicit_iv_len);
+ ASSERT (opt->packet_id); /* for this mode. */
- if (!packet_id_read (&pin, &b, !ctx->implicit_iv_len))
- CRYPT_ERROR ("error reading CFB/OFB/AEAD packet-id");
+ buf_set_read (&b, iv_buf, iv_size);
+ if (!packet_id_read (&pin, &b, true))
+ CRYPT_ERROR ("error reading CFB/OFB packet-id");
have_pin = true;
}
- else /* We only support CBC, CFB, OFB, or AEAD modes right now */
+ else /* We only support CBC, CFB, or OFB modes right now */
{
ASSERT (0);
}
@@ -493,7 +361,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
else
{
work = *buf;
- if (packet_id_initialized(&opt->packet_id))
+ if (opt->packet_id)
{
if (!packet_id_read (&pin, &work, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)))
CRYPT_ERROR ("error reading packet-id");
@@ -503,13 +371,12 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
if (have_pin)
{
- packet_id_reap_test (&opt->packet_id.rec);
- if (packet_id_test (&opt->packet_id.rec, &pin))
+ packet_id_reap_test (&opt->packet_id->rec);
+ if (packet_id_test (&opt->packet_id->rec, &pin))
{
- packet_id_add (&opt->packet_id.rec, &pin);
- if (opt->pid_persist && (opt->flags & CO_PACKET_ID_LONG_FORM) &&
- !ctx->implicit_iv_len)
- packet_id_persist_save_obj (opt->pid_persist, &opt->packet_id);
+ packet_id_add (&opt->packet_id->rec, &pin);
+ if (opt->pid_persist && (opt->flags & CO_PACKET_ID_LONG_FORM))
+ packet_id_persist_save_obj (opt->pid_persist, opt->packet_id);
}
else
{
@@ -540,9 +407,9 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
bool
crypto_test_hmac (struct buffer *buf, const struct crypto_options *opt)
{
- if (buf->len > 0 && opt)
+ if (buf->len > 0 && opt->key_ctx_bi)
{
- const struct key_ctx *ctx = &opt->key_ctx_bi.decrypt;
+ struct key_ctx *ctx = &opt->key_ctx_bi->decrypt;
/* Verify the HMAC */
if (ctx->hmac)
@@ -566,30 +433,11 @@ crypto_adjust_frame_parameters(struct frame *frame,
bool packet_id,
bool packet_id_long_form)
{
- size_t crypto_overhead = 0;
-
- if (packet_id)
- crypto_overhead += packet_id_size (packet_id_long_form);
-
- if (cipher_defined)
- {
- if (use_iv)
- crypto_overhead += cipher_kt_iv_size (kt->cipher);
-
- if (cipher_kt_mode_aead (kt->cipher))
- crypto_overhead += cipher_kt_tag_size (kt->cipher);
-
- if (cipher_kt_mode_cbc (kt->cipher))
- /* worst case padding expansion */
- crypto_overhead += cipher_kt_block_size (kt->cipher);
- }
-
- crypto_overhead += kt->hmac_length;
-
- frame_add_to_extra_frame (frame, crypto_overhead);
-
- msg(D_MTU_DEBUG, "%s: Adjusting frame parameters for crypto by %zu bytes",
- __func__, crypto_overhead);
+ frame_add_to_extra_frame (frame,
+ (packet_id ? packet_id_size (packet_id_long_form) : 0) +
+ ((cipher_defined && use_iv) ? cipher_kt_iv_size (kt->cipher) : 0) +
+ (cipher_defined ? cipher_kt_block_size (kt->cipher) : 0) + /* worst case padding expansion */
+ kt->hmac_length);
}
/*
@@ -599,10 +447,8 @@ void
init_key_type (struct key_type *kt, const char *ciphername,
bool ciphername_defined, const char *authname,
bool authname_defined, int keysize,
- bool tls_mode, bool warn)
+ bool cfb_ofb_allowed, bool warn)
{
- bool aead_cipher = false;
-
CLEAR (*kt);
if (ciphername && ciphername_defined)
{
@@ -612,14 +458,14 @@ init_key_type (struct key_type *kt, const char *ciphername,
kt->cipher_length = keysize;
/* check legal cipher mode */
- aead_cipher = cipher_kt_mode_aead(kt->cipher);
- if (!(cipher_kt_mode_cbc(kt->cipher)
- || (tls_mode && aead_cipher)
+ {
+ if (!(cipher_kt_mode_cbc(kt->cipher)
#ifdef ENABLE_OFB_CFB_MODE
- || (tls_mode && cipher_kt_mode_ofb_cfb(kt->cipher))
+ || (cfb_ofb_allowed && cipher_kt_mode_ofb_cfb(kt->cipher))
#endif
- ))
- msg (M_FATAL, "Cipher '%s' mode not supported", ciphername);
+ ))
+ msg (M_FATAL, "Cipher '%s' mode not supported", ciphername);
+ }
}
else
{
@@ -628,12 +474,10 @@ init_key_type (struct key_type *kt, const char *ciphername,
}
if (authname && authname_defined)
{
- if (!aead_cipher) { /* Ignore auth for AEAD ciphers */
- kt->digest = md_kt_get (authname);
- kt->hmac_length = md_kt_size (kt->digest);
- }
+ kt->digest = md_kt_get (authname);
+ kt->hmac_length = md_kt_size (kt->digest);
}
- else if (!aead_cipher)
+ else
{
if (warn)
msg (M_WARN, "******* WARNING *******: null MAC specified, no authentication will be used");
@@ -657,7 +501,7 @@ init_key_ctx (struct key_ctx *ctx, struct key *key,
msg (D_HANDSHAKE, "%s: Cipher '%s' initialized with %d bit key",
prefix,
- translate_cipher_name_to_openvpn(cipher_kt_name(kt->cipher)),
+ cipher_kt_name(kt->cipher),
kt->cipher_length *8);
dmsg (D_SHOW_KEYS, "%s: CIPHER KEY: %s", prefix,
@@ -703,12 +547,6 @@ free_key_ctx (struct key_ctx *ctx)
free(ctx->hmac);
ctx->hmac = NULL;
}
- if (ctx->implicit_iv)
- {
- free(ctx->implicit_iv);
- ctx->implicit_iv = 0;
- }
- ctx->implicit_iv_len = 0;
}
void
@@ -718,20 +556,6 @@ free_key_ctx_bi (struct key_ctx_bi *ctx)
free_key_ctx(&ctx->decrypt);
}
-bool
-key_ctx_set_implicit_iv (struct key_ctx *ctx, const uint8_t *iv, size_t len)
-{
- if (ctx->implicit_iv) free (ctx->implicit_iv);
-
- ctx->implicit_iv = malloc (len);
- if (!ctx->implicit_iv) return false;
-
- ctx->implicit_iv_len = len;
- memcpy (ctx->implicit_iv, iv, len);
-
- return true;
-}
-
static bool
key_is_zero (struct key *key, const struct key_type *kt)
@@ -879,7 +703,7 @@ key2_print (const struct key2* k,
}
void
-test_crypto (struct crypto_options *co, struct frame* frame)
+test_crypto (const struct crypto_options *co, struct frame* frame)
{
int i, j;
struct gc_arena gc = gc_new ();
@@ -892,22 +716,6 @@ test_crypto (struct crypto_options *co, struct frame* frame)
/* init work */
ASSERT (buf_init (&work, FRAME_HEADROOM (frame)));
-#ifdef HAVE_AEAD_CIPHER_MODES
- /* init implicit IV */
- {
- const cipher_kt_t *cipher = cipher_ctx_get_cipher_kt(
- co->key_ctx_bi.encrypt.cipher);
-
- if (cipher_kt_mode_aead(cipher))
- {
- key_ctx_set_implicit_iv(&co->key_ctx_bi.encrypt,\
- (const uint8_t *) "01234567", 8);
- key_ctx_set_implicit_iv(&co->key_ctx_bi.decrypt,
- (const uint8_t *) "01234567", 8);
- }
- }
-#endif
-
msg (M_INFO, "Entering " PACKAGE_NAME " crypto self-test mode.");
for (i = 1; i <= TUN_MTU_SIZE (frame); ++i)
{
@@ -960,8 +768,13 @@ get_tls_handshake_key (const struct key_type *key_type,
if (passphrase_file && key_type->hmac_length)
{
struct key2 key2;
+ struct key_type kt = *key_type;
struct key_direction_state kds;
+ /* for control channel we are only authenticating, not encrypting */
+ kt.cipher_length = 0;
+ kt.cipher = NULL;
+
if (flags & GHK_INLINE)
{
/* key was specified inline, key text is in passphrase_file */
@@ -993,10 +806,10 @@ get_tls_handshake_key (const struct key_type *key_type,
/* failed, now try to get hash from a freeform file */
hash_size = read_passphrase_hash (passphrase_file,
- key_type->digest,
+ kt.digest,
key2.keys[0].hmac,
MAX_HMAC_KEY_LENGTH);
- ASSERT (hash_size == key_type->hmac_length);
+ ASSERT (hash_size == kt.hmac_length);
/* suceeded */
key2.n = 1;
@@ -1013,9 +826,9 @@ get_tls_handshake_key (const struct key_type *key_type,
/* initialize hmac key in both directions */
- init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], key_type, OPENVPN_OP_ENCRYPT,
+ init_key_ctx (&ctx->encrypt, &key2.keys[kds.out_key], &kt, OPENVPN_OP_ENCRYPT,
"Outgoing Control Channel Authentication");
- init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], key_type, OPENVPN_OP_DECRYPT,
+ init_key_ctx (&ctx->decrypt, &key2.keys[kds.in_key], &kt, OPENVPN_OP_DECRYPT,
"Incoming Control Channel Authentication");
CLEAR (key2);
@@ -1671,42 +1484,4 @@ md5_digest_equal (const struct md5_digest *d1, const struct md5_digest *d2)
return memcmp(d1->digest, d2->digest, MD5_DIGEST_LENGTH) == 0;
}
-static const cipher_name_pair *
-get_cipher_name_pair(const char *cipher_name) {
- const cipher_name_pair *pair;
- size_t i = 0;
-
- /* Search for a cipher name translation */
- for (; i < cipher_name_translation_table_count; i++)
- {
- pair = &cipher_name_translation_table[i];
- if (0 == strcmp (cipher_name, pair->openvpn_name) ||
- 0 == strcmp (cipher_name, pair->ssllib_name))
- return pair;
- }
-
- /* Nothing found, return null */
- return NULL;
-}
-
-const char *
-translate_cipher_name_from_openvpn (const char *cipher_name) {
- const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
-
- if (NULL == pair)
- return cipher_name;
-
- return pair->ssllib_name;
-}
-
-const char *
-translate_cipher_name_to_openvpn (const char *cipher_name) {
- const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
-
- if (NULL == pair)
- return cipher_name;
-
- return pair->openvpn_name;
-}
-
#endif /* ENABLE_CRYPTO */
diff --git a/main/openvpn/src/openvpn/crypto.h b/main/openvpn/src/openvpn/crypto.h
index b0b1df48..3c4e59d7 100644
--- a/main/openvpn/src/openvpn/crypto.h
+++ b/main/openvpn/src/openvpn/crypto.h
@@ -63,15 +63,13 @@ struct key
/**
- * Container for one set of cipher and/or HMAC contexts.
+ * Container for one set of OpenSSL cipher and/or HMAC contexts.
* @ingroup control_processor
*/
struct key_ctx
{
cipher_ctx_t *cipher; /**< Generic cipher %context. */
- hmac_ctx_t *hmac; /**< Generic HMAC %context. */
- uint8_t *implicit_iv; /**< The implicit part of the IV */
- size_t implicit_iv_len; /**< The length of implicit_iv */
+ hmac_ctx_t *hmac; /**< Generic HMAC %context. */
};
#define KEY_DIRECTION_BIDIRECTIONAL 0 /* same keys for both directions */
@@ -122,10 +120,10 @@ struct key_direction_state
*/
struct key_ctx_bi
{
- struct key_ctx encrypt; /**< Cipher and/or HMAC contexts for sending
- * direction. */
- struct key_ctx decrypt; /**< cipher and/or HMAC contexts for
- * receiving direction. */
+ struct key_ctx encrypt; /**< OpenSSL cipher and/or HMAC contexts
+ * for sending direction. */
+ struct key_ctx decrypt; /**< OpenSSL cipher and/or HMAC contexts
+ * for receiving direction. */
};
/**
@@ -134,11 +132,11 @@ struct key_ctx_bi
*/
struct crypto_options
{
- struct key_ctx_bi key_ctx_bi;
+ struct key_ctx_bi *key_ctx_bi;
/**< OpenSSL cipher and HMAC contexts for
* both sending and receiving
* directions. */
- struct packet_id packet_id; /**< Current packet ID state for both
+ struct packet_id *packet_id; /**< Current packet ID state for both
* sending and receiving directions. */
struct packet_id_persist *pid_persist;
/**< Persistent packet ID state for
@@ -205,17 +203,6 @@ void free_key_ctx (struct key_ctx *ctx);
void free_key_ctx_bi (struct key_ctx_bi *ctx);
-/**
- * Set an implicit IV for a key context.
- *
- * @param ctx The key context to update
- * @param iv The implicit IV to load into ctx
- * @param len The length (in bytes) of iv
- */
-bool key_ctx_set_implicit_iv (struct key_ctx *ctx, const uint8_t *iv,
- size_t len);
-
-
/**************************************************************************/
/** @name Functions for performing security operations on data channel packets
@@ -249,7 +236,8 @@ bool key_ctx_set_implicit_iv (struct key_ctx *ctx, const uint8_t *iv,
* error occurred.
*/
void openvpn_encrypt (struct buffer *buf, struct buffer work,
- struct crypto_options *opt, const struct frame* frame);
+ const struct crypto_options *opt,
+ const struct frame* frame);
/**
@@ -284,7 +272,8 @@ void openvpn_encrypt (struct buffer *buf, struct buffer work,
* an error occurred.
*/
bool openvpn_decrypt (struct buffer *buf, struct buffer work,
- struct crypto_options *opt, const struct frame* frame);
+ const struct crypto_options *opt,
+ const struct frame* frame);
bool crypto_test_hmac (struct buffer *buf, const struct crypto_options *opt);
@@ -336,7 +325,7 @@ void prng_bytes (uint8_t *output, int len);
void prng_uninit ();
-void test_crypto (struct crypto_options *co, struct frame* f);
+void test_crypto (const struct crypto_options *co, struct frame* f);
/* key direction functions */
diff --git a/main/openvpn/src/openvpn/crypto_backend.h b/main/openvpn/src/openvpn/crypto_backend.h
index faf40594..bc067a7d 100644
--- a/main/openvpn/src/openvpn/crypto_backend.h
+++ b/main/openvpn/src/openvpn/crypto_backend.h
@@ -38,18 +38,6 @@
#endif
#include "basic.h"
-/* TLS uses a tag of 128 bytes, let's do the same for OpenVPN */
-#define OPENVPN_AEAD_TAG_LENGTH 16
-
-/** Struct used in cipher name translation table */
-typedef struct {
- const char * openvpn_name;
- const char * ssllib_name;
-} cipher_name_pair;
-
-/** Cipher name translation table */
-extern const cipher_name_pair cipher_name_translation_table[];
-extern const size_t cipher_name_translation_table_count;
/*
* This routine should have additional OpenSSL crypto library initialisations
@@ -233,16 +221,6 @@ int cipher_kt_iv_size (const cipher_kt_t *cipher_kt);
int cipher_kt_block_size (const cipher_kt_t *cipher_kt);
/**
- * Returns the MAC tag size of the cipher, in bytes.
- *
- * @param ctx Static cipher parameters. May not be NULL.
- *
- * @return Tag size, in bytes, or 0 if the cipher is not an
- * authenticated encryption mode.
- */
-int cipher_kt_tag_size (const cipher_kt_t *cipher_kt);
-
-/**
* Returns the mode that the cipher runs in.
*
* @param cipher_kt Static cipher parameters
@@ -272,16 +250,6 @@ bool cipher_kt_mode_cbc(const cipher_kt_t *cipher)
bool cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
__attribute__((nonnull));
-/**
- * Check if the supplied cipher is a supported AEAD mode cipher.
- *
- * @param cipher Static cipher parameters. May not be NULL.
- *
- * @return true iff the cipher is a AEAD mode cipher.
- */
-bool cipher_kt_mode_aead(const cipher_kt_t *cipher)
- __attribute__((nonnull));
-
/**
*
@@ -321,15 +289,6 @@ void cipher_ctx_cleanup (cipher_ctx_t *ctx);
int cipher_ctx_iv_length (const cipher_ctx_t *ctx);
/**
- * Gets the computed message authenticated code (MAC) tag for this cipher.
- *
- * @param ctx The cipher's context
- * @param tag The buffer to write computed tag in.
- * @param tag_size The tag buffer size, in bytes.
- */
-int cipher_ctx_get_tag (cipher_ctx_t *ctx, uint8_t* tag, int tag_len);
-
-/**
* Returns the block size of the cipher, in bytes.
*
* @param ctx The cipher's context
@@ -370,18 +329,6 @@ const cipher_kt_t *cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
int cipher_ctx_reset (cipher_ctx_t *ctx, uint8_t *iv_buf);
/**
- * Updates the given cipher context, setting the additional data (AD) used
- * with authenticated encryption with additional data (AEAD) cipher modes.
- *
- * @param ctx Cipher's context. May not be NULL.
- * @param src Source buffer
- * @param src_len Length of the source buffer, in bytes
- *
- * @return \c 0 on failure, \c 1 on success.
- */
-int cipher_ctx_update_ad (cipher_ctx_t *ctx, uint8_t *src, int src_len);
-
-/**
* Updates the given cipher context, encrypting data in the source buffer, and
* placing any complete blocks in the destination buffer.
*
@@ -413,22 +360,6 @@ int cipher_ctx_update (cipher_ctx_t *ctx, uint8_t *dst, int *dst_len,
*/
int cipher_ctx_final (cipher_ctx_t *ctx, uint8_t *dst, int *dst_len);
-/**
- * Like \c cipher_ctx_final, but check the computed authentication tag against
- * the supplied (expected) tag. This function reports failure when the tags
- * don't match.
- *
- * @param ctx Cipher's context. May not be NULL.
- * @param dst Destination buffer.
- * @param dst_len Length of the destination buffer, in bytes.
- * @param tag The expected authentication tag.
- * @param tag_len The length of tag, in bytes.
- *
- * @return \c 0 on failure, \c 1 on success.
- */
-int cipher_ctx_final_check_tag (cipher_ctx_t *ctx, uint8_t *dst, int *dst_len,
- const uint8_t *tag, size_t tag_len);
-
/*
*
* Generic message digest information functions
@@ -596,19 +527,4 @@ void hmac_ctx_update (hmac_ctx_t *ctx, const uint8_t *src, int src_len);
*/
void hmac_ctx_final (hmac_ctx_t *ctx, uint8_t *dst);
-/**
- * Check if mode is an AEAD cipher mode.
- *
- * @param mode The mode to check.
- *
- * @return true if mode is a supported AEAD mode, false otherwise.
- */
-bool crypto_aead_mode (int mode);
-
-/** XXX doxygen */
-const char * translate_cipher_name_from_openvpn (const char *cipher_name);
-
-/** XXX doxygen */
-const char * translate_cipher_name_to_openvpn (const char *cipher_name);
-
#endif /* CRYPTO_BACKEND_H_ */
diff --git a/main/openvpn/src/openvpn/crypto_openssl.c b/main/openvpn/src/openvpn/crypto_openssl.c
index ef487944..0ac89a19 100644
--- a/main/openvpn/src/openvpn/crypto_openssl.c
+++ b/main/openvpn/src/openvpn/crypto_openssl.c
@@ -45,8 +45,6 @@
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/des.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
/*
* Check for key size creepage.
@@ -102,14 +100,13 @@ setup_engine (const char *engine)
if ((e = ENGINE_by_id (engine)) == NULL
&& (e = try_load_engine (engine)) == NULL)
{
- crypto_msg (M_FATAL, "OpenSSL error: cannot load engine '%s'",
- engine);
+ msg (M_FATAL, "OpenSSL error: cannot load engine '%s'", engine);
}
if (!ENGINE_set_default (e, ENGINE_METHOD_ALL))
{
- crypto_msg (M_FATAL, "OpenSSL error: ENGINE_set_default failed on "
- "engine '%s'", engine);
+ msg (M_FATAL, "OpenSSL error: ENGINE_set_default failed on engine '%s'",
+ engine);
}
msg (M_INFO, "Initializing OpenSSL support for engine '%s'",
@@ -198,26 +195,6 @@ crypto_clear_error (void)
ERR_clear_error ();
}
-void
-crypto_print_openssl_errors(const unsigned int flags) {
- size_t err = 0;
-
- while ((err = ERR_get_error ()))
- {
- /* Be more clear about frequently occurring "no shared cipher" error */
- if (err == ERR_PACK(ERR_LIB_SSL,SSL_F_SSL3_GET_CLIENT_HELLO,
- SSL_R_NO_SHARED_CIPHER))
- {
- msg (D_CRYPT_ERRORS, "TLS error: The server has no TLS ciphersuites "
- "in common with the client. Your --tls-cipher setting might be "
- "too restrictive.");
- }
-
- msg (flags, "OpenSSL: %s", ERR_error_string (err, NULL));
- }
-}
-
-
/*
*
* OpenSSL memory debugging. If dmalloc debugging is enabled, tell
@@ -254,17 +231,17 @@ crypto_init_dmalloc (void)
}
#endif /* DMALLOC */
-const cipher_name_pair cipher_name_translation_table[] = {
- { "AES-128-CCM", "id-aes128-CCM" },
- { "AES-192-CCM", "id-aes192-CCM" },
- { "AES-256-CCM", "id-aes256-CCM" },
- { "AES-128-GCM", "id-aes128-GCM" },
- { "AES-192-GCM", "id-aes192-GCM" },
- { "AES-256-GCM", "id-aes256-GCM" },
-};
-const size_t cipher_name_translation_table_count =
- sizeof (cipher_name_translation_table) / sizeof (*cipher_name_translation_table);
+const char *
+translate_cipher_name_from_openvpn (const char *cipher_name) {
+ // OpenSSL doesn't require any translation
+ return cipher_name;
+}
+const char *
+translate_cipher_name_to_openvpn (const char *cipher_name) {
+ // OpenSSL doesn't require any translation
+ return cipher_name;
+}
void
show_available_ciphers ()
@@ -272,12 +249,12 @@ show_available_ciphers ()
int nid;
#ifndef ENABLE_SMALL
- printf ("The following ciphers and cipher modes are available for use\n"
- "with " PACKAGE_NAME ". Each cipher shown below may be use as a\n"
- "parameter to the --cipher option. The default key size is\n"
- "shown as well as whether or not it can be changed with the\n"
- "--keysize directive. Using a CBC or GCM mode is recommended.\n"
- "In static key mode only CBC mode is allowed.\n\n");
+ printf ("The following ciphers and cipher modes are available\n"
+ "for use with " PACKAGE_NAME ". Each cipher shown below may be\n"
+ "used as a parameter to the --cipher option. The default\n"
+ "key size is shown as well as whether or not it can be\n"
+ "changed with the --keysize directive. Using a CBC mode\n"
+ "is recommended. In static key mode only CBC mode is allowed.\n\n");
#endif
for (nid = 0; nid < 10000; ++nid) /* is there a better way to get the size of the nid list? */
@@ -289,20 +266,17 @@ show_available_ciphers ()
#ifdef ENABLE_OFB_CFB_MODE
|| cipher_kt_mode_ofb_cfb(cipher)
#endif
-#ifdef HAVE_AEAD_CIPHER_MODES
- || cipher_kt_mode_aead(cipher)
-#endif
)
{
const char *var_key_size =
(EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ?
"variable" : "fixed";
- const char *ssl_only = cipher_kt_mode_cbc(cipher) ?
- "" : " (TLS client/server mode)";
+ const char *ssl_only = cipher_kt_mode_ofb_cfb(cipher) ?
+ " (TLS client/server mode)" : "";
- printf ("%s %d bit default key (%s)%s\n",
- translate_cipher_name_to_openvpn(OBJ_nid2sn (nid)),
- EVP_CIPHER_key_length (cipher) * 8, var_key_size, ssl_only);
+ printf ("%s %d bit default key (%s)%s\n", OBJ_nid2sn (nid),
+ EVP_CIPHER_key_length (cipher) * 8, var_key_size,
+ ssl_only);
}
}
}
@@ -412,20 +386,17 @@ key_des_check (uint8_t *key, int key_len, int ndc)
DES_cblock *dc = (DES_cblock*) buf_read_alloc (&b, sizeof (DES_cblock));
if (!dc)
{
- msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key "
- "material");
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: insufficient key material");
goto err;
}
if (DES_is_weak_key(dc))
{
- crypto_msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key "
- "detected");
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: weak key detected");
goto err;
}
if (!DES_check_key_parity (dc))
{
- crypto_msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity "
- "detected");
+ msg (D_CRYPT_ERRORS, "CRYPTO INFO: check_key_DES: bad parity detected");
goto err;
}
}
@@ -474,7 +445,7 @@ cipher_kt_get (const char *ciphername)
cipher = EVP_get_cipherbyname (ciphername);
if (NULL == cipher)
- crypto_msg (M_FATAL, "Cipher algorithm '%s' not found", ciphername);
+ msg (M_SSLERR, "Cipher algorithm '%s' not found", ciphername);
if (EVP_CIPHER_key_length (cipher) > MAX_CIPHER_KEY_LENGTH)
msg (M_FATAL, "Cipher algorithm '%s' uses a default key size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum key size (%d bytes)",
@@ -512,15 +483,6 @@ cipher_kt_block_size (const EVP_CIPHER *cipher_kt)
}
int
-cipher_kt_tag_size (const EVP_CIPHER *cipher_kt)
-{
- if (cipher_kt_mode_aead(cipher_kt))
- return OPENVPN_AEAD_TAG_LENGTH;
- else
- return 0;
-}
-
-int
cipher_kt_mode (const EVP_CIPHER *cipher_kt)
{
ASSERT(NULL != cipher_kt);
@@ -550,17 +512,6 @@ cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
;
}
-bool
-cipher_kt_mode_aead(const cipher_kt_t *cipher)
-{
-#ifdef HAVE_AEAD_CIPHER_MODES
- return (cipher_kt_mode(cipher) == OPENVPN_MODE_GCM ||
- cipher_kt_mode(cipher) == OPENVPN_MODE_CCM);
-#else
- return false;
-#endif
-}
-
/*
*
* Generic cipher context functions
@@ -578,13 +529,13 @@ cipher_ctx_init (EVP_CIPHER_CTX *ctx, uint8_t *key, int key_len,
EVP_CIPHER_CTX_init (ctx);
if (!EVP_CipherInit (ctx, kt, NULL, NULL, enc))
- crypto_msg (M_FATAL, "EVP cipher init #1");
+ msg (M_SSLERR, "EVP cipher init #1");
#ifdef HAVE_EVP_CIPHER_CTX_SET_KEY_LENGTH
if (!EVP_CIPHER_CTX_set_key_length (ctx, key_len))
- crypto_msg (M_FATAL, "EVP set key size");
+ msg (M_SSLERR, "EVP set key size");
#endif
if (!EVP_CipherInit (ctx, NULL, key, NULL, enc))
- crypto_msg (M_FATAL, "EVP cipher init #2");
+ msg (M_SSLERR, "EVP cipher init #2");
/* make sure we used a big enough key */
ASSERT (EVP_CIPHER_CTX_key_length (ctx) <= key_len);
@@ -602,15 +553,6 @@ cipher_ctx_iv_length (const EVP_CIPHER_CTX *ctx)
return EVP_CIPHER_CTX_iv_length (ctx);
}
-int cipher_ctx_get_tag (EVP_CIPHER_CTX *ctx, uint8_t *tag_buf, int tag_size)
-{
-#ifdef HAVE_AEAD_CIPHER_MODES
- return EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_GET_TAG, tag_size, tag_buf);
-#else
- ASSERT (0);
-#endif
-}
-
int
cipher_ctx_block_size(const EVP_CIPHER_CTX *ctx)
{
@@ -637,17 +579,6 @@ cipher_ctx_reset (EVP_CIPHER_CTX *ctx, uint8_t *iv_buf)
}
int
-cipher_ctx_update_ad (EVP_CIPHER_CTX *ctx, uint8_t* src, int src_len)
-{
-#ifdef HAVE_AEAD_CIPHER_MODES
- int len;
- return EVP_CipherUpdate (ctx, NULL, &len, src, src_len);
-#else
- ASSERT (0);
-#endif
-}
-
-int
cipher_ctx_update (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len,
uint8_t *src, int src_len)
{
@@ -660,21 +591,6 @@ cipher_ctx_final (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len)
return EVP_CipherFinal (ctx, dst, dst_len);
}
-int
-cipher_ctx_final_check_tag (EVP_CIPHER_CTX *ctx, uint8_t *dst, int *dst_len,
- const uint8_t *tag, size_t tag_len)
-{
-#ifdef HAVE_AEAD_CIPHER_MODES
- /* Setting a tag does not change the tag, so casting away const... */
- if (!EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_TAG, tag_len,
- (uint8_t *) tag))
- return 0;
-
- return cipher_ctx_final (ctx, dst, dst_len);
-#else
- ASSERT (0);
-#endif
-}
void
cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH],
@@ -701,11 +617,9 @@ md_kt_get (const char *digest)
ASSERT (digest);
md = EVP_get_digestbyname (digest);
if (!md)
- crypto_msg (M_FATAL, "Message hash algorithm '%s' not found", digest);
+ msg (M_SSLERR, "Message hash algorithm '%s' not found", digest);
if (EVP_MD_size (md) > MAX_HMAC_KEY_LENGTH)
- crypto_msg (M_FATAL, "Message hash algorithm '%s' uses a default hash size "
- "(%d bytes) which is larger than " PACKAGE_NAME "'s current maximum "
- "hash size (%d bytes)",
+ msg (M_FATAL, "Message hash algorithm '%s' uses a default hash size (%d bytes) which is larger than " PACKAGE_NAME "'s current maximum hash size (%d bytes)",
digest,
EVP_MD_size (md),
MAX_HMAC_KEY_LENGTH);
@@ -833,14 +747,4 @@ hmac_ctx_final (HMAC_CTX *ctx, uint8_t *dst)
HMAC_Final (ctx, dst, &in_hmac_len);
}
-bool
-crypto_aead_mode (int mode)
-{
-#ifdef HAVE_AEAD_CIPHER_MODES
- return mode == OPENVPN_MODE_CCM || mode == OPENVPN_MODE_GCM;
-#else
- return false;
-#endif
-}
-
#endif /* ENABLE_CRYPTO && ENABLE_CRYPTO_OPENSSL */
diff --git a/main/openvpn/src/openvpn/crypto_openssl.h b/main/openvpn/src/openvpn/crypto_openssl.h
index b99fd67f..f883c2a5 100644
--- a/main/openvpn/src/openvpn/crypto_openssl.h
+++ b/main/openvpn/src/openvpn/crypto_openssl.h
@@ -61,16 +61,6 @@ typedef HMAC_CTX hmac_ctx_t;
/** Cipher is in CFB mode */
#define OPENVPN_MODE_CFB EVP_CIPH_CFB_MODE
-#ifdef HAVE_AEAD_CIPHER_MODES
-
-/** Cipher is in CCM mode */
-#define OPENVPN_MODE_CCM EVP_CIPH_CCM_MODE
-
-/** Cipher is in GCM mode */
-#define OPENVPN_MODE_GCM EVP_CIPH_GCM_MODE
-
-#endif /* HAVE_AEAD_CIPHER_MODES */
-
/** Cipher should encrypt */
#define OPENVPN_OP_ENCRYPT 1
@@ -80,29 +70,4 @@ typedef HMAC_CTX hmac_ctx_t;
#define DES_KEY_LENGTH 8
#define MD4_DIGEST_LENGTH 16
-/**
- * Retrieve any occurred OpenSSL errors and print those errors.
- *
- * Note that this function uses the not thread-safe OpenSSL error API.
- *
- * @param flags Flags to indicate error type and priority.
- */
-void crypto_print_openssl_errors(const unsigned int flags);
-
-/**
- * Retrieve any OpenSSL errors, then print the supplied error message.
- *
- * This is just a convenience wrapper for often occurring situations.
- *
- * @param flags Flags to indicate error type and priority.
- * @param format Format string to print.
- * @param format args (optional) arguments for the format string.
- */
-# define crypto_msg(flags, ...) \
-do { \
- crypto_print_openssl_errors(nonfatal(flags)); \
- msg((flags), __VA_ARGS__); \
-} while (false)
-
-
#endif /* CRYPTO_OPENSSL_H_ */
diff --git a/main/openvpn/src/openvpn/crypto_polarssl.c b/main/openvpn/src/openvpn/crypto_polarssl.c
index c7a41baf..1a986dbd 100644
--- a/main/openvpn/src/openvpn/crypto_polarssl.c
+++ b/main/openvpn/src/openvpn/crypto_polarssl.c
@@ -46,7 +46,6 @@
#include "misc.h"
#include <polarssl/des.h>
-#include <polarssl/error.h>
#include <polarssl/md5.h>
#include <polarssl/cipher.h>
#include <polarssl/havege.h>
@@ -87,32 +86,6 @@ crypto_clear_error (void)
{
}
-bool polar_log_err(unsigned int flags, int errval, const char *prefix)
-{
- if (0 != errval)
- {
- char errstr[256];
- polarssl_strerror(errval, errstr, sizeof(errstr));
-
- if (NULL == prefix) prefix = "PolarSSL error";
- msg (flags, "%s: %s", prefix, errstr);
- }
-
- return 0 == errval;
-}
-
-bool polar_log_func_line(unsigned int flags, int errval, const char *func,
- int line)
-{
- char prefix[256];
-
- if (!openvpn_snprintf(prefix, sizeof(prefix), "%s:%d", func, line))
- return polar_log_err(flags, errval, func);
-
- return polar_log_err(flags, errval, prefix);
-}
-
-
#ifdef DMALLOC
void
crypto_init_dmalloc (void)
@@ -121,15 +94,52 @@ crypto_init_dmalloc (void)
}
#endif /* DMALLOC */
-const cipher_name_pair cipher_name_translation_table[] = {
+typedef struct { const char * openvpn_name; const char * polarssl_name; } cipher_name_pair;
+cipher_name_pair cipher_name_translation_table[] = {
{ "BF-CBC", "BLOWFISH-CBC" },
{ "BF-CFB", "BLOWFISH-CFB64" },
{ "CAMELLIA-128-CFB", "CAMELLIA-128-CFB128" },
{ "CAMELLIA-192-CFB", "CAMELLIA-192-CFB128" },
{ "CAMELLIA-256-CFB", "CAMELLIA-256-CFB128" }
};
-const size_t cipher_name_translation_table_count =
- sizeof (cipher_name_translation_table) / sizeof (*cipher_name_translation_table);
+
+const cipher_name_pair *
+get_cipher_name_pair(const char *cipher_name) {
+ cipher_name_pair *pair;
+ size_t i = 0;
+
+ /* Search for a cipher name translation */
+ for (; i < sizeof (cipher_name_translation_table) / sizeof (*cipher_name_translation_table); i++)
+ {
+ pair = &cipher_name_translation_table[i];
+ if (0 == strcmp (cipher_name, pair->openvpn_name) ||
+ 0 == strcmp (cipher_name, pair->polarssl_name))
+ return pair;
+ }
+
+ /* Nothing found, return null */
+ return NULL;
+}
+
+const char *
+translate_cipher_name_from_openvpn (const char *cipher_name) {
+ const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
+
+ if (NULL == pair)
+ return cipher_name;
+
+ return pair->polarssl_name;
+}
+
+const char *
+translate_cipher_name_to_openvpn (const char *cipher_name) {
+ const cipher_name_pair *pair = get_cipher_name_pair(cipher_name);
+
+ if (NULL == pair)
+ return cipher_name;
+
+ return pair->openvpn_name;
+}
void
show_available_ciphers ()
@@ -137,28 +147,21 @@ show_available_ciphers ()
const int *ciphers = cipher_list();
#ifndef ENABLE_SMALL
- printf ("The following ciphers and cipher modes are available for use\n"
- "with " PACKAGE_NAME ". Each cipher shown below may be used as a\n"
- "parameter to the --cipher option. Using a CBC or GCM mode is\n"
- "recommended. In static key mode only CBC mode is allowed.\n\n");
+ printf ("The following ciphers and cipher modes are available\n"
+ "for use with " PACKAGE_NAME ". Each cipher shown below may be\n"
+ "used as a parameter to the --cipher option. The default\n"
+ "key size is shown as well as whether or not it can be\n"
+ "changed with the --keysize directive. Using a CBC mode\n"
+ "is recommended.\n\n");
#endif
while (*ciphers != 0)
{
- const cipher_kt_t *info = cipher_info_from_type(*ciphers);
-
- if (info && (cipher_kt_mode_cbc(info)
-#ifdef HAVE_AEAD_CIPHER_MODES
- || cipher_kt_mode_aead(info)
-#endif
- ))
- {
- const char *ssl_only = cipher_kt_mode_cbc(info) ?
- "" : " (TLS client/server mode)";
+ const cipher_info_t *info = cipher_info_from_type(*ciphers);
- printf ("%s %d bit default key%s\n",
- cipher_kt_name(info), cipher_kt_key_size(info) * 8, ssl_only);
- }
+ if (info && info->mode == POLARSSL_MODE_CBC)
+ printf ("%s %d bit default key\n",
+ cipher_kt_name(info), cipher_kt_key_size(info) * 8);
ciphers++;
}
@@ -231,8 +234,7 @@ ctr_drbg_context * rand_ctx_get()
/* Initialise PolarSSL RNG, and built-in entropy sources */
entropy_init(&ec);
- if (!polar_ok(ctr_drbg_init(&cd_ctx, entropy_func, &ec,
- BPTR(&pers_string), BLEN(&pers_string))))
+ if (0 != ctr_drbg_init(&cd_ctx, entropy_func, &ec, BPTR(&pers_string), BLEN(&pers_string)))
msg (M_FATAL, "Failed to initialize random generator");
gc_free(&gc);
@@ -408,16 +410,6 @@ cipher_kt_block_size (const cipher_info_t *cipher_kt)
}
int
-cipher_kt_tag_size (const cipher_info_t *cipher_kt)
-{
-#ifdef HAVE_AEAD_CIPHER_MODES
- if (cipher_kt && cipher_kt_mode_aead(cipher_kt))
- return OPENVPN_AEAD_TAG_LENGTH;
-#endif
- return 0;
-}
-
-int
cipher_kt_mode (const cipher_info_t *cipher_kt)
{
ASSERT(NULL != cipher_kt);
@@ -437,12 +429,6 @@ cipher_kt_mode_ofb_cfb(const cipher_kt_t *cipher)
cipher_kt_mode(cipher) == OPENVPN_MODE_CFB);
}
-bool
-cipher_kt_mode_aead(const cipher_kt_t *cipher)
-{
- return cipher_kt_mode(cipher) == OPENVPN_MODE_GCM;
-}
-
/*
*
@@ -459,10 +445,10 @@ cipher_ctx_init (cipher_context_t *ctx, uint8_t *key, int key_len,
CLEAR (*ctx);
- if (!polar_ok(cipher_init_ctx(ctx, kt)))
+ if (0 != cipher_init_ctx(ctx, kt))
msg (M_FATAL, "PolarSSL cipher context init #1");
- if (!polar_ok(cipher_setkey(ctx, key, key_len*8, enc)))
+ if (0 != cipher_setkey(ctx, key, key_len*8, enc))
msg (M_FATAL, "PolarSSL cipher set key");
/* make sure we used a big enough key */
@@ -471,7 +457,7 @@ cipher_ctx_init (cipher_context_t *ctx, uint8_t *key, int key_len,
void cipher_ctx_cleanup (cipher_context_t *ctx)
{
- ASSERT (polar_ok(cipher_free_ctx(ctx)));
+ cipher_free_ctx(ctx);
}
int cipher_ctx_iv_length (const cipher_context_t *ctx)
@@ -479,21 +465,6 @@ int cipher_ctx_iv_length (const cipher_context_t *ctx)
return cipher_get_iv_size(ctx);
}
-int cipher_ctx_get_tag (cipher_ctx_t *ctx, uint8_t* tag, int tag_len)
-{
-#ifdef HAVE_AEAD_CIPHER_MODES
- if (tag_len > SIZE_MAX)
- return 0;
-
- if (!polar_ok(cipher_write_tag(ctx, (unsigned char *) tag, tag_len)))
- return 0;
-
- return 1;
-#else
- ASSERT(0);
-#endif /* HAVE_AEAD_CIPHER_MODES */
-}
-
int cipher_ctx_block_size(const cipher_context_t *ctx)
{
return cipher_get_block_size(ctx);
@@ -516,74 +487,36 @@ cipher_ctx_get_cipher_kt (const cipher_ctx_t *ctx)
int cipher_ctx_reset (cipher_context_t *ctx, uint8_t *iv_buf)
{
- if (!polar_ok(cipher_reset(ctx)))
- return 0;
-
- if (!polar_ok(cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size)))
- return 0;
-
- return 1;
-}
-
-int cipher_ctx_update_ad (cipher_ctx_t *ctx, uint8_t *src, int src_len)
-{
- if (src_len > SIZE_MAX)
- return 0;
+ int retval = cipher_reset(ctx);
- if (!polar_ok(cipher_update_ad(ctx, src, src_len)))
- return 0;
+ if (0 == retval)
+ retval = cipher_set_iv(ctx, iv_buf, ctx->cipher_info->iv_size);
- return 1;
+ return 0 == retval;
}
int cipher_ctx_update (cipher_context_t *ctx, uint8_t *dst, int *dst_len,
uint8_t *src, int src_len)
{
+ int retval = 0;
size_t s_dst_len = *dst_len;
- if (!polar_ok(cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len)))
- return 0;
+ retval = cipher_update(ctx, src, (size_t)src_len, dst, &s_dst_len);
*dst_len = s_dst_len;
- return 1;
+ return 0 == retval;
}
int cipher_ctx_final (cipher_context_t *ctx, uint8_t *dst, int *dst_len)
{
+ int retval = 0;
size_t s_dst_len = *dst_len;
- if (!polar_ok(cipher_finish(ctx, dst, &s_dst_len)))
- return 0;
-
+ retval = cipher_finish(ctx, dst, &s_dst_len);
*dst_len = s_dst_len;
- return 1;
-}
-
-int cipher_ctx_final_check_tag (cipher_context_t *ctx, uint8_t *dst, int *dst_len,
- const uint8_t *tag, size_t tag_len)
-{
-#ifdef HAVE_AEAD_CIPHER_MODES
- if (POLARSSL_DECRYPT != ctx->operation)
- return 0;
-
- if (tag_len > SIZE_MAX)
- return 0;
-
- if (!cipher_ctx_final(ctx, dst, dst_len))
- {
- msg(D_CRYPT_ERRORS, "%s: cipher_ctx_final() failed", __func__);
- return 0;
- }
-
- if (!polar_ok(cipher_check_tag(ctx, (const unsigned char *) tag, tag_len)))
- return 0;
-
- return 1;
-#else
- ASSERT(0);
-#endif /* HAVE_AEAD_CIPHER_MODES */
+ return 0 == retval;
}
void
@@ -593,8 +526,8 @@ cipher_des_encrypt_ecb (const unsigned char key[DES_KEY_LENGTH],
{
des_context ctx;
- ASSERT (polar_ok(des_setkey_enc(&ctx, key)));
- ASSERT (polar_ok(des_crypt_ecb(&ctx, src, dst)));
+ des_setkey_enc(&ctx, key);
+ des_crypt_ecb(&ctx, src, dst);
}
diff --git a/main/openvpn/src/openvpn/crypto_polarssl.h b/main/openvpn/src/openvpn/crypto_polarssl.h
index 75aa8643..b6da4363 100644
--- a/main/openvpn/src/openvpn/crypto_polarssl.h
+++ b/main/openvpn/src/openvpn/crypto_polarssl.h
@@ -61,9 +61,6 @@ typedef md_context_t hmac_ctx_t;
/** Cipher is in CFB mode */
#define OPENVPN_MODE_CFB POLARSSL_MODE_CFB
-/** Cipher is in GCM mode */
-#define OPENVPN_MODE_GCM POLARSSL_MODE_GCM
-
/** Cipher should encrypt */
#define OPENVPN_OP_ENCRYPT POLARSSL_ENCRYPT
@@ -94,44 +91,4 @@ ctr_drbg_context * rand_ctx_get();
void rand_ctx_enable_prediction_resistance();
#endif
-/**
- * Log the supplied PolarSSL error, then print the supplied error message.
- *
- * @param flags Flags to indicate error type and priority.
- * @param errval PolarSSL error code to convert to error message.
- * @param prefix Prefix to PolarSSL error message.
- *
- * @returns true if no errors are detected, false otherwise.
- */
-bool polar_log_err(unsigned int flags, int errval, const char *prefix);
-
-/**
- * Log the supplied PolarSSL error, then print the supplied error message.
- *
- * @param flags Flags to indicate error type and priority.
- * @param errval PolarSSL error code to convert to error message.
- * @param func Function name where error was reported.
- * @param line Line number where error was reported.
- *
- * @returns true if no errors are detected, false otherwise.
- */
-bool polar_log_func_line(unsigned int flags, int errval, const char *func,
- int line);
-
-/**
- * Check errval and log on error.
- *
- * Convenience wrapper to put around polarssl library calls, e.g.
- * if (!polar_ok(polarssl_func())) return 0;
- * or
- * ASSERT (polar_ok(polarssl_func()));
- *
- * @param errval PolarSSL error code to convert to error message.
- *
- * @returns true if no errors are detected, false otherwise.
- */
-#define polar_ok(errval) \
- polar_log_func_line(D_CRYPT_ERRORS, errval, __func__, __LINE__)
-
-
#endif /* CRYPTO_POLARSSL_H_ */
diff --git a/main/openvpn/src/openvpn/error.c b/main/openvpn/src/openvpn/error.c
index 72ebfab6..af865f32 100644
--- a/main/openvpn/src/openvpn/error.c
+++ b/main/openvpn/src/openvpn/error.c
@@ -43,6 +43,13 @@
#include "ps.h"
#include "mstats.h"
+#ifdef ENABLE_CRYPTO
+#ifdef ENABLE_CRYPTO_OPENSSL
+#include <openssl/err.h>
+#endif
+#endif
+
+#include "memdbg.h"
#if SYSLOG_CAPABILITY
#ifndef LOG_OPENVPN
@@ -262,6 +269,28 @@ void x_msg_va (const unsigned int flags, const char *format, va_list arglist)
SWAP;
}
+#ifdef ENABLE_CRYPTO
+#ifdef ENABLE_CRYPTO_OPENSSL
+ if (flags & M_SSL)
+ {
+ int nerrs = 0;
+ size_t err;
+ while ((err = ERR_get_error ()))
+ {
+ openvpn_snprintf (m2, ERR_BUF_SIZE, "%s: %s",
+ m1, ERR_error_string (err, NULL));
+ SWAP;
+ ++nerrs;
+ }
+ if (!nerrs)
+ {
+ openvpn_snprintf (m2, ERR_BUF_SIZE, "%s (OpenSSL)", m1);
+ SWAP;
+ }
+ }
+#endif
+#endif
+
if (flags & M_OPTERR)
{
openvpn_snprintf (m2, ERR_BUF_SIZE, "Options error: %s", m1);
diff --git a/main/openvpn/src/openvpn/error.h b/main/openvpn/src/openvpn/error.h
index d5204f3f..1e1f2acf 100644
--- a/main/openvpn/src/openvpn/error.h
+++ b/main/openvpn/src/openvpn/error.h
@@ -93,6 +93,10 @@ extern int x_msg_line_num;
#define M_ERRNO (1<<8) /* show errno description */
+#ifdef ENABLE_CRYPTO_OPENSSL
+# define M_SSL (1<<10) /* show SSL error */
+#endif
+
#define M_NOMUTE (1<<11) /* don't do mute processing */
#define M_NOPREFIX (1<<12) /* don't show date/time prefix */
#define M_USAGE_SMALL (1<<13) /* fatal options error, call usage_small */
@@ -103,6 +107,7 @@ extern int x_msg_line_num;
/* flag combinations which are frequently used */
#define M_ERR (M_FATAL | M_ERRNO)
+#define M_SSLERR (M_FATAL | M_SSL)
#define M_USAGE (M_USAGE_SMALL | M_NOPREFIX | M_OPTERR)
#define M_CLIENT (M_MSG_VIRT_OUT | M_NOMUTE | M_NOIPREFIX)
@@ -349,12 +354,6 @@ ignore_sys_error (const int err)
return false;
}
-/** Convert fatal errors to nonfatal, don't touch other errors */
-static inline const unsigned int
-nonfatal(const unsigned int err) {
- return err & M_FATAL ? (err ^ M_FATAL) | M_NONFATAL : err;
-}
-
#include "errlevel.h"
#endif
diff --git a/main/openvpn/src/openvpn/forward.c b/main/openvpn/src/openvpn/forward.c
index 73bed9b8..0bbdedb0 100644
--- a/main/openvpn/src/openvpn/forward.c
+++ b/main/openvpn/src/openvpn/forward.c
@@ -433,7 +433,6 @@ encrypt_sign (struct context *c, bool comp_frag)
{
struct context_buffers *b = c->c2.buffers;
const uint8_t *orig_buf = c->c2.buf.data;
- struct crypto_options *co = NULL;
#if P2MP_SERVER
/*
@@ -465,19 +464,15 @@ encrypt_sign (struct context *c, bool comp_frag)
*/
if (c->c2.tls_multi)
{
- tls_pre_encrypt (c->c2.tls_multi, &c->c2.buf, &co);
+ tls_pre_encrypt (c->c2.tls_multi, &c->c2.buf, &c->c2.crypto_options);
}
- else
#endif
- {
- co = &c->c2.crypto_options;
- }
/*
* Encrypt the packet and write an optional
* HMAC signature.
*/
- openvpn_encrypt (&c->c2.buf, b->encrypt_buf, co, &c->c2.frame);
+ openvpn_encrypt (&c->c2.buf, b->encrypt_buf, &c->c2.crypto_options, &c->c2.frame);
#endif
/*
* Get the address we will be sending the packet to.
@@ -793,7 +788,6 @@ process_incoming_link (struct context *c)
*/
if (c->c2.buf.len > 0)
{
- struct crypto_options *co = NULL;
if (!link_socket_verify_incoming_addr (&c->c2.buf, lsi, &c->c2.from))
link_socket_bad_incoming_addr (&c->c2.buf, lsi, &c->c2.from);
@@ -811,7 +805,7 @@ process_incoming_link (struct context *c)
* will load crypto_options with the correct encryption key
* and return false.
*/
- if (tls_pre_decrypt (c->c2.tls_multi, &c->c2.from, &c->c2.buf, &co))
+ if (tls_pre_decrypt (c->c2.tls_multi, &c->c2.from, &c->c2.buf, &c->c2.crypto_options))
{
interval_action (&c->c2.tmp_int);
@@ -820,10 +814,6 @@ process_incoming_link (struct context *c)
event_timeout_reset (&c->c2.ping_rec_interval);
}
}
- else
- {
- co = &c->c2.crypto_options;
- }
#if P2MP_SERVER
/*
* Drop non-TLS packet if client-connect script/plugin has not
@@ -832,12 +822,10 @@ process_incoming_link (struct context *c)
if (c->c2.context_auth != CAS_SUCCEEDED)
c->c2.buf.len = 0;
#endif
-#else
- co = &c->c2.crypto_options;
#endif /* ENABLE_SSL */
/* authenticate and decrypt the incoming packet */
- decrypt_status = openvpn_decrypt (&c->c2.buf, c->c2.buffers->decrypt_buf, co, &c->c2.frame);
+ decrypt_status = openvpn_decrypt (&c->c2.buf, c->c2.buffers->decrypt_buf, &c->c2.crypto_options, &c->c2.frame);
if (!decrypt_status && link_socket_connection_oriented (c->c2.link_socket))
{
diff --git a/main/openvpn/src/openvpn/httpdigest.c b/main/openvpn/src/openvpn/httpdigest.c
index 2590d1b1..78b8344d 100644
--- a/main/openvpn/src/openvpn/httpdigest.c
+++ b/main/openvpn/src/openvpn/httpdigest.c
@@ -74,23 +74,22 @@ DigestCalcHA1(
HASH HA1;
md_ctx_t md5_ctx;
const md_kt_t *md5_kt = md_kt_get("MD5");
- const uint8_t colon = ':';
md_ctx_init(&md5_ctx, md5_kt);
- md_ctx_update(&md5_ctx, (uint8_t *) pszUserName, strlen(pszUserName));
- md_ctx_update(&md5_ctx, &colon, 1);
- md_ctx_update(&md5_ctx, (uint8_t *) pszRealm, strlen(pszRealm));
- md_ctx_update(&md5_ctx, &colon, 1);
- md_ctx_update(&md5_ctx, (uint8_t *) pszPassword, strlen(pszPassword));
+ md_ctx_update(&md5_ctx, pszUserName, strlen(pszUserName));
+ md_ctx_update(&md5_ctx, ":", 1);
+ md_ctx_update(&md5_ctx, pszRealm, strlen(pszRealm));
+ md_ctx_update(&md5_ctx, ":", 1);
+ md_ctx_update(&md5_ctx, pszPassword, strlen(pszPassword));
md_ctx_final(&md5_ctx, HA1);
if (pszAlg && strcasecmp(pszAlg, "md5-sess") == 0)
{
md_ctx_init(&md5_ctx, md5_kt);
md_ctx_update(&md5_ctx, HA1, HASHLEN);
- md_ctx_update(&md5_ctx, &colon, 1);
- md_ctx_update(&md5_ctx, (uint8_t *) pszNonce, strlen(pszNonce));
- md_ctx_update(&md5_ctx, &colon, 1);
- md_ctx_update(&md5_ctx, (uint8_t *) pszCNonce, strlen(pszCNonce));
+ md_ctx_update(&md5_ctx, ":", 1);
+ md_ctx_update(&md5_ctx, pszNonce, strlen(pszNonce));
+ md_ctx_update(&md5_ctx, ":", 1);
+ md_ctx_update(&md5_ctx, pszCNonce, strlen(pszCNonce));
md_ctx_final(&md5_ctx, HA1);
};
md_ctx_cleanup(&md5_ctx);
@@ -117,16 +116,15 @@ DigestCalcResponse(
md_ctx_t md5_ctx;
const md_kt_t *md5_kt = md_kt_get("MD5");
- const uint8_t colon = ':';
/* calculate H(A2) */
md_ctx_init(&md5_ctx, md5_kt);
- md_ctx_update(&md5_ctx, (uint8_t *) pszMethod, strlen(pszMethod));
- md_ctx_update(&md5_ctx, &colon, 1);
- md_ctx_update(&md5_ctx, (uint8_t *) pszDigestUri, strlen(pszDigestUri));
+ md_ctx_update(&md5_ctx, pszMethod, strlen(pszMethod));
+ md_ctx_update(&md5_ctx, ":", 1);
+ md_ctx_update(&md5_ctx, pszDigestUri, strlen(pszDigestUri));
if (strcasecmp(pszQop, "auth-int") == 0)
{
- md_ctx_update(&md5_ctx, &colon, 1);
+ md_ctx_update(&md5_ctx, ":", 1);
md_ctx_update(&md5_ctx, HEntity, HASHHEXLEN);
};
md_ctx_final(&md5_ctx, HA2);
@@ -135,17 +133,17 @@ DigestCalcResponse(
/* calculate response */
md_ctx_init(&md5_ctx, md5_kt);
md_ctx_update(&md5_ctx, HA1, HASHHEXLEN);
- md_ctx_update(&md5_ctx, &colon, 1);
- md_ctx_update(&md5_ctx, (uint8_t *) pszNonce, strlen(pszNonce));
- md_ctx_update(&md5_ctx, &colon, 1);
+ md_ctx_update(&md5_ctx, ":", 1);
+ md_ctx_update(&md5_ctx, pszNonce, strlen(pszNonce));
+ md_ctx_update(&md5_ctx, ":", 1);
if (*pszQop)
{
- md_ctx_update(&md5_ctx, (uint8_t *) pszNonceCount, strlen(pszNonceCount));
- md_ctx_update(&md5_ctx, &colon, 1);
- md_ctx_update(&md5_ctx, (uint8_t *) pszCNonce, strlen(pszCNonce));
- md_ctx_update(&md5_ctx, &colon, 1);
- md_ctx_update(&md5_ctx, (uint8_t *) pszQop, strlen(pszQop));
- md_ctx_update(&md5_ctx, &colon, 1);
+ md_ctx_update(&md5_ctx, pszNonceCount, strlen(pszNonceCount));
+ md_ctx_update(&md5_ctx, ":", 1);
+ md_ctx_update(&md5_ctx, pszCNonce, strlen(pszCNonce));
+ md_ctx_update(&md5_ctx, ":", 1);
+ md_ctx_update(&md5_ctx, pszQop, strlen(pszQop));
+ md_ctx_update(&md5_ctx, ":", 1);
};
md_ctx_update(&md5_ctx, HA2Hex, HASHHEXLEN);
md_ctx_final(&md5_ctx, RespHash);
diff --git a/main/openvpn/src/openvpn/httpdigest.h b/main/openvpn/src/openvpn/httpdigest.h
index 24bd85d8..84238413 100644
--- a/main/openvpn/src/openvpn/httpdigest.h
+++ b/main/openvpn/src/openvpn/httpdigest.h
@@ -25,7 +25,7 @@
#if PROXY_DIGEST_AUTH
#define HASHLEN 16
-typedef uint8_t HASH[HASHLEN];
+typedef unsigned char HASH[HASHLEN];
#define HASHHEXLEN 32
typedef unsigned char HASHHEX[HASHHEXLEN+1];
#undef IN
diff --git a/main/openvpn/src/openvpn/init.c b/main/openvpn/src/openvpn/init.c
index af517ee9..7cec8d9b 100644
--- a/main/openvpn/src/openvpn/init.c
+++ b/main/openvpn/src/openvpn/init.c
@@ -1893,38 +1893,39 @@ do_startup_pause (struct context *c)
* Finalize MTU parameters based on command line or config file options.
*/
static void
-frame_finalize_options (struct frame *frame, const struct options *o,
- bool cipher_enabled)
+frame_finalize_options (struct context *c, const struct options *o)
{
- ASSERT(o);
+ if (!o)
+ o = &c->options;
/*
* Set adjustment factor for buffer alignment when no
* cipher is used.
*/
- if (!cipher_enabled)
+ if (!CIPHER_ENABLED (c))
{
- frame_align_to_extra_frame (frame);
- frame_or_align_flags (frame,
+ frame_align_to_extra_frame (&c->c2.frame);
+ frame_or_align_flags (&c->c2.frame,
FRAME_HEADROOM_MARKER_FRAGMENT
|FRAME_HEADROOM_MARKER_READ_LINK
|FRAME_HEADROOM_MARKER_READ_STREAM);
}
- frame_finalize (frame,
+ frame_finalize (&c->c2.frame,
o->ce.link_mtu_defined,
o->ce.link_mtu,
o->ce.tun_mtu_defined,
o->ce.tun_mtu);
}
-#ifdef ENABLE_CRYPTO
/*
* Free a key schedule, including OpenSSL components.
*/
static void
key_schedule_free (struct key_schedule *ks, bool free_ssl_ctx)
{
+#ifdef ENABLE_CRYPTO
+ free_key_ctx_bi (&ks->static_key);
#ifdef ENABLE_SSL
if (tls_ctx_initialised(&ks->ssl_ctx) && free_ssl_ctx)
{
@@ -1932,9 +1933,12 @@ key_schedule_free (struct key_schedule *ks, bool free_ssl_ctx)
free_key_ctx_bi (&ks->tls_auth_key);
}
#endif /* ENABLE_SSL */
+#endif /* ENABLE_CRYPTO */
CLEAR (*ks);
}
+#ifdef ENABLE_CRYPTO
+
static void
init_crypto_pre (struct context *c, const unsigned int flags)
{
@@ -1948,6 +1952,14 @@ init_crypto_pre (struct context *c, const unsigned int flags)
packet_id_persist_load (&c->c1.pid_persist, c->options.packet_id_file);
}
+ /* Initialize crypto options */
+
+ if (c->options.use_iv)
+ c->c2.crypto_options.flags |= CO_USE_IV;
+
+ if (c->options.mute_replay_warnings)
+ c->c2.crypto_options.flags |= CO_MUTE_REPLAY_WARNINGS;
+
#ifdef ENABLE_PREDICTION_RESISTANCE
if (c->options.use_prediction_resistance)
rand_ctx_enable_prediction_resistance();
@@ -1966,28 +1978,22 @@ do_init_crypto_static (struct context *c, const unsigned int flags)
init_crypto_pre (c, flags);
- /* Initialize flags */
- if (c->options.use_iv)
- c->c2.crypto_options.flags |= CO_USE_IV;
-
- if (c->options.mute_replay_warnings)
- c->c2.crypto_options.flags |= CO_MUTE_REPLAY_WARNINGS;
-
/* Initialize packet ID tracking */
if (options->replay)
{
- packet_id_init (&c->c2.crypto_options.packet_id,
+ packet_id_init (&c->c2.packet_id,
link_socket_proto_connection_oriented (options->ce.proto),
options->replay_window,
options->replay_time,
"STATIC", 0);
+ c->c2.crypto_options.packet_id = &c->c2.packet_id;
c->c2.crypto_options.pid_persist = &c->c1.pid_persist;
c->c2.crypto_options.flags |= CO_PACKET_ID_LONG_FORM;
packet_id_persist_load_obj (&c->c1.pid_persist,
- &c->c2.crypto_options.packet_id);
+ c->c2.crypto_options.packet_id);
}
- if (!key_ctx_bi_defined (&c->c2.crypto_options.key_ctx_bi))
+ if (!key_ctx_bi_defined (&c->c1.ks.static_key))
{
struct key2 key2;
struct key_direction_state kds;
@@ -2019,12 +2025,10 @@ do_init_crypto_static (struct context *c, const unsigned int flags)
key_direction_state_init (&kds, options->key_direction);
must_have_n_keys (options->shared_secret_file, "secret", &key2,
kds.need_keys);
- init_key_ctx (&c->c2.crypto_options.key_ctx_bi.encrypt,
- &key2.keys[kds.out_key], &c->c1.ks.key_type,
- OPENVPN_OP_ENCRYPT, "Static Encrypt");
- init_key_ctx (&c->c2.crypto_options.key_ctx_bi.decrypt,
- &key2.keys[kds.in_key], &c->c1.ks.key_type,
- OPENVPN_OP_DECRYPT, "Static Decrypt");
+ init_key_ctx (&c->c1.ks.static_key.encrypt, &key2.keys[kds.out_key],
+ &c->c1.ks.key_type, OPENVPN_OP_ENCRYPT, "Static Encrypt");
+ init_key_ctx (&c->c1.ks.static_key.decrypt, &key2.keys[kds.in_key],
+ &c->c1.ks.key_type, OPENVPN_OP_DECRYPT, "Static Decrypt");
/* Erase the temporary copy of key */
CLEAR (key2);
@@ -2034,6 +2038,9 @@ do_init_crypto_static (struct context *c, const unsigned int flags)
msg (M_INFO, "Re-using pre-shared static key");
}
+ /* Get key schedule */
+ c->c2.crypto_options.key_ctx_bi = &c->c1.ks.static_key;
+
/* Compute MTU parameters */
crypto_adjust_frame_parameters (&c->c2.frame,
&c->c1.ks.key_type,
@@ -2105,22 +2112,11 @@ do_init_crypto_tls_c1 (struct context *c)
flags |= GHK_INLINE;
file = options->tls_auth_file_inline;
}
-
- /* Initialize key_type for tls-auth with auth only */
- CLEAR (c->c1.ks.tls_auth_key_type);
- if (options->authname && options->authname_defined)
- {
- c->c1.ks.tls_auth_key_type.digest = md_kt_get (options->authname);
- c->c1.ks.tls_auth_key_type.hmac_length =
- md_kt_size (c->c1.ks.tls_auth_key_type.digest);
- }
- else
- {
- msg (M_FATAL, "ERROR: tls-auth specified, but no valid auth");
- }
-
- get_tls_handshake_key (&c->c1.ks.tls_auth_key_type,
- &c->c1.ks.tls_auth_key, file, options->key_direction, flags);
+ get_tls_handshake_key (&c->c1.ks.key_type,
+ &c->c1.ks.tls_auth_key,
+ file,
+ options->key_direction,
+ flags);
}
#if 0 /* was: #if ENABLE_INLINE_FILES -- Note that enabling this code will break restarts */
@@ -2175,12 +2171,6 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
/* Set all command-line TLS-related options */
CLEAR (to);
- if (options->use_iv)
- to.crypto_flags |= CO_USE_IV;
-
- if (options->mute_replay_warnings)
- to.crypto_flags |= CO_MUTE_REPLAY_WARNINGS;
-
to.crypto_flags_and = ~(CO_PACKET_ID_LONG_FORM);
if (packet_id_long_form)
to.crypto_flags_or = CO_PACKET_ID_LONG_FORM;
@@ -2270,11 +2260,11 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
/* TLS handshake authentication (--tls-auth) */
if (options->tls_auth_file)
{
- to.tls_auth.key_ctx_bi = c->c1.ks.tls_auth_key;
+ to.tls_auth_key = c->c1.ks.tls_auth_key;
to.tls_auth.pid_persist = &c->c1.pid_persist;
to.tls_auth.flags |= CO_PACKET_ID_LONG_FORM;
crypto_adjust_frame_parameters (&to.frame,
- &c->c1.ks.tls_auth_key_type,
+ &c->c1.ks.key_type,
false, false, true, true);
}
@@ -2417,7 +2407,7 @@ do_init_frame (struct context *c)
* Fill in the blanks in the frame parameters structure,
* make sure values are rational, etc.
*/
- frame_finalize_options (&c->c2.frame, &c->options, CIPHER_ENABLED (c));
+ frame_finalize_options (c, NULL);
#ifdef USE_COMP
/*
@@ -2853,13 +2843,8 @@ do_close_tls (struct context *c)
static void
do_close_free_key_schedule (struct context *c, bool free_ssl_ctx)
{
-#ifdef ENABLE_CRYPTO
if (!(c->sig->signal_received == SIGUSR1 && c->options.persist_key))
- {
- key_schedule_free (&c->c1.ks, free_ssl_ctx);
- free_key_ctx_bi (&c->c2.crypto_options.key_ctx_bi);
- }
-#endif /* ENABLE_CRYPTO */
+ key_schedule_free (&c->c1.ks, free_ssl_ctx);
}
/*
@@ -2908,7 +2893,7 @@ static void
do_close_packet_id (struct context *c)
{
#ifdef ENABLE_CRYPTO
- packet_id_free (&c->c2.crypto_options.packet_id);
+ packet_id_free (&c->c2.packet_id);
packet_id_persist_save (&c->c1.pid_persist);
if (!(c->sig->signal_received == SIGUSR1))
packet_id_persist_close (&c->c1.pid_persist);
@@ -3795,6 +3780,7 @@ close_context (struct context *c, int sig, unsigned int flags)
}
#ifdef ENABLE_CRYPTO
+
/*
* Do a loopback test
* on the crypto subsystem.
@@ -3811,21 +3797,23 @@ test_crypto_thread (void *arg)
next_connection_entry(c);
do_init_crypto_static (c, 0);
- frame_finalize_options (&c->c2.frame, options, CIPHER_ENABLED (c));
+ frame_finalize_options (c, options);
test_crypto (&c->c2.crypto_options, &c->c2.frame);
key_schedule_free (&c->c1.ks, true);
- free_key_ctx_bi (&c->c2.crypto_options.key_ctx_bi);
- packet_id_free (&c->c2.crypto_options.packet_id);
+ packet_id_free (&c->c2.packet_id);
context_gc_free (c);
return NULL;
}
+#endif
+
bool
do_test_crypto (const struct options *o)
{
+#ifdef ENABLE_CRYPTO
if (o->test_crypto)
{
struct context c;
@@ -3840,12 +3828,6 @@ do_test_crypto (const struct options *o)
test_crypto_thread ((void *) &c);
return true;
}
+#endif
return false;
}
-#else
-bool
-do_test_crypto (const struct options *o)
-{
- return false;
-}
-#endif /* ENABLE_CRYPTO */
diff --git a/main/openvpn/src/openvpn/mroute.h b/main/openvpn/src/openvpn/mroute.h
index 60653f96..608f70be 100644
--- a/main/openvpn/src/openvpn/mroute.h
+++ b/main/openvpn/src/openvpn/mroute.h
@@ -186,23 +186,19 @@ mroute_addr_hash_len (const struct mroute_addr *a)
static inline void
mroute_extract_in_addr_t (struct mroute_addr *dest, const in_addr_t src)
{
- uint32_t tmp_addr = htonl (src);
dest->type = MR_ADDR_IPV4;
dest->netbits = 0;
dest->len = 4;
- memcpy(dest->addr, &tmp_addr, sizeof(uint32_t));
+ *(in_addr_t*)dest->addr = htonl (src);
}
static inline in_addr_t
in_addr_t_from_mroute_addr (const struct mroute_addr *addr)
{
- if ((addr->type & MR_ADDR_MASK) == MR_ADDR_IPV4 && addr->netbits == 0 && addr->len == 4) {
- uint32_t tmp = 0;
- memcpy(&tmp, addr->addr, sizeof(uint32_t));
- return ntohl(tmp);
- } else {
+ if ((addr->type & MR_ADDR_MASK) == MR_ADDR_IPV4 && addr->netbits == 0 && addr->len == 4)
+ return ntohl(*(in_addr_t*)addr->addr);
+ else
return 0;
- }
}
static inline void
diff --git a/main/openvpn/src/openvpn/mudp.c b/main/openvpn/src/openvpn/mudp.c
index 8941d896..51227a90 100644
--- a/main/openvpn/src/openvpn/mudp.c
+++ b/main/openvpn/src/openvpn/mudp.c
@@ -105,10 +105,10 @@ multi_get_create_instance_udp (struct multi_context *m)
struct hash_element *he;
const uint32_t hv = hash_value (hash, &real);
struct hash_bucket *bucket = hash_bucket (hash, hv);
- uint8_t* ptr = BPTR(&m->top.c2.buf);
+ uint8_t* ptr = BPTR(&m->top.c2.buf);
uint8_t op = ptr[0] >> P_OPCODE_SHIFT;
uint32_t peer_id;
- bool session_forged = false;
+ bool hmac_mismatch = false;
if (op == P_DATA_V2)
{
@@ -119,15 +119,15 @@ multi_get_create_instance_udp (struct multi_context *m)
if (!link_socket_actual_match(&mi->context.c2.from, &m->top.c2.from))
{
- msg(D_MULTI_MEDIUM, "floating detected from %s to %s",
- print_link_socket_actual (&mi->context.c2.from, &gc), print_link_socket_actual (&m->top.c2.from, &gc));
+ msg(D_MULTI_MEDIUM, "float from %s to %s",
+ print_link_socket_actual (&mi->context.c2.from, &gc), print_link_socket_actual (&m->top.c2.from, &gc));
/* peer-id is not trusted, so check hmac */
- session_forged = !(crypto_test_hmac(&m->top.c2.buf, &mi->context.c2.crypto_options));
- if (session_forged)
+ hmac_mismatch = !(crypto_test_hmac(&m->top.c2.buf, &mi->context.c2.crypto_options));
+ if (hmac_mismatch)
{
mi = NULL;
- msg (D_MULTI_MEDIUM, "hmac verification failed, session forge detected!");
+ msg (D_MULTI_MEDIUM, "HMAC mismatch for peer-id %d", peer_id);
}
else
{
@@ -144,7 +144,7 @@ multi_get_create_instance_udp (struct multi_context *m)
mi = (struct multi_instance *) he->value;
}
}
- if (!mi && !session_forged)
+ if (!mi && !hmac_mismatch)
{
if (!m->top.c2.tls_auth_standalone
|| tls_pre_decrypt_lite (m->top.c2.tls_auth_standalone, &m->top.c2.from, &m->top.c2.buf))
diff --git a/main/openvpn/src/openvpn/multi.c b/main/openvpn/src/openvpn/multi.c
index c585630b..bd5948c8 100644
--- a/main/openvpn/src/openvpn/multi.c
+++ b/main/openvpn/src/openvpn/multi.c
@@ -303,7 +303,6 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa
cid_compare_function);
#endif
-
/*
* This is our scheduler, for time-based wakeup
* events.
@@ -374,12 +373,7 @@ multi_init (struct multi_context *m, struct context *t, bool tcp_mode, int threa
*/
m->max_clients = t->options.max_clients;
- int i;
- m->instances = malloc(sizeof(struct multi_instance*) * m->max_clients);
- for (i = 0; i < m->max_clients; ++ i)
- {
- m->instances[i] = NULL;
- }
+ m->instances = calloc(m->max_clients, sizeof(struct multi_instance*));
/*
* Initialize multi-socket TCP I/O wait object
@@ -664,6 +658,8 @@ multi_create_instance (struct multi_context *m, const struct mroute_addr *real)
perf_push (PERF_MULTI_CREATE_INSTANCE);
+ msg (D_MULTI_MEDIUM, "MULTI: multi_create_instance called");
+
ALLOC_OBJ_CLEAR (mi, struct multi_instance);
mi->gc = gc_new ();
diff --git a/main/openvpn/src/openvpn/ntlm.c b/main/openvpn/src/openvpn/ntlm.c
index 1833cecf..3390bddd 100644
--- a/main/openvpn/src/openvpn/ntlm.c
+++ b/main/openvpn/src/openvpn/ntlm.c
@@ -73,26 +73,26 @@ create_des_keys(const unsigned char *hash, unsigned char *key)
}
static void
-gen_md4_hash (const uint8_t* data, int data_len, uint8_t *result)
+gen_md4_hash (const char* data, int data_len, char *result)
{
/* result is 16 byte md4 hash */
const md_kt_t *md4_kt = md_kt_get("MD4");
- uint8_t md[MD4_DIGEST_LENGTH];
+ char md[MD4_DIGEST_LENGTH];
md_full(md4_kt, data, data_len, md);
memcpy (result, md, MD4_DIGEST_LENGTH);
}
static void
-gen_hmac_md5 (const uint8_t *data, int data_len, const uint8_t *key, int key_len, uint8_t *result)
+gen_hmac_md5 (const char* data, int data_len, const char* key, int key_len,char *result)
{
const md_kt_t *md5_kt = md_kt_get("MD5");
hmac_ctx_t hmac_ctx;
CLEAR(hmac_ctx);
hmac_ctx_init(&hmac_ctx, key, key_len, md5_kt);
- hmac_ctx_update(&hmac_ctx, data, data_len);
- hmac_ctx_final(&hmac_ctx, result);
+ hmac_ctx_update(&hmac_ctx, (const unsigned char *)data, data_len);
+ hmac_ctx_final(&hmac_ctx, (unsigned char *)result);
hmac_ctx_cleanup(&hmac_ctx);
}
@@ -140,7 +140,7 @@ unsigned char *my_strupr(unsigned char *str)
}
static int
-unicodize (uint8_t *dst, const char *src)
+unicodize (char *dst, const char *src)
{
/* not really unicode... */
int i = 0;
@@ -192,20 +192,20 @@ ntlm_phase_3 (const struct http_proxy_info *p, const char *phase_2, struct gc_ar
*
*/
- uint8_t pwbuf[sizeof (p->up.password) * 2]; /* for unicode password */
+ char pwbuf[sizeof (p->up.password) * 2]; /* for unicode password */
char buf2[128]; /* decoded reply from proxy */
unsigned char phase3[464];
- uint8_t md4_hash[MD4_DIGEST_LENGTH+5];
- unsigned char challenge[8], ntlm_response[24];
+ char md4_hash[MD4_DIGEST_LENGTH+5];
+ char challenge[8], ntlm_response[24];
int i, ret_val;
- uint8_t ntlmv2_response[144];
- uint8_t userdomain_u[256]; /* for uppercase unicode username and domain */
+ char ntlmv2_response[144];
+ char userdomain_u[256]; /* for uppercase unicode username and domain */
char userdomain[128]; /* the same as previous but ascii */
- uint8_t ntlmv2_hash[MD5_DIGEST_LENGTH];
- uint8_t ntlmv2_hmacmd5[16];
- uint8_t *ntlmv2_blob = ntlmv2_response + 16; /* inside ntlmv2_response, length: 128 */
+ char ntlmv2_hash[MD5_DIGEST_LENGTH];
+ char ntlmv2_hmacmd5[16];
+ char *ntlmv2_blob = ntlmv2_response + 16; /* inside ntlmv2_response, length: 128 */
int ntlmv2_blob_size=0;
int phase3_bufpos = 0x40; /* offset to next security buffer data to be added */
size_t len;
diff --git a/main/openvpn/src/openvpn/openvpn.h b/main/openvpn/src/openvpn/openvpn.h
index 57676868..eab8cd5b 100644
--- a/main/openvpn/src/openvpn/openvpn.h
+++ b/main/openvpn/src/openvpn/openvpn.h
@@ -59,12 +59,14 @@ struct key_schedule
/* which cipher, HMAC digest, and key sizes are we using? */
struct key_type key_type;
+ /* pre-shared static key, read from a file */
+ struct key_ctx_bi static_key;
+
#ifdef ENABLE_SSL
/* our global SSL context */
struct tls_root_ctx ssl_ctx;
/* optional authentication HMAC key for TLS control channel */
- struct key_type tls_auth_key_type;
struct key_ctx_bi tls_auth_key;
#endif /* ENABLE_SSL */
@@ -364,6 +366,7 @@ struct context_2
* process data channel packet. */
/* used to keep track of data channel packet sequence numbers */
+ struct packet_id packet_id;
struct event_timeout packet_id_persist_interval;
#endif /* ENABLE_CRYPTO */
diff --git a/main/openvpn/src/openvpn/options.c b/main/openvpn/src/openvpn/options.c
index bdab8fea..1ca4ad57 100644
--- a/main/openvpn/src/openvpn/options.c
+++ b/main/openvpn/src/openvpn/options.c
@@ -570,7 +570,6 @@ static const char usage_message[] =
"--tls-version-min <version> ['or-highest'] : sets the minimum TLS version we\n"
" will accept from the peer. If version is unrecognized and 'or-highest'\n"
" is specified, require max TLS version supported by SSL implementation.\n"
- "--tls-version-max <version> : sets the maximum TLS version we will use.\n"
#ifndef ENABLE_CRYPTO_POLARSSL
"--pkcs12 file : PKCS#12 file containing local private key, local certificate\n"
" and optionally the root CA certificate.\n"
@@ -2146,6 +2145,10 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
(options->shared_secret_file != NULL) > 1)
msg (M_USAGE, "specify only one of --tls-server, --tls-client, or --secret");
+ if (options->tls_server)
+ {
+ notnull (options->dh_file, "DH file (--dh)");
+ }
if (options->tls_server || options->tls_client)
{
#ifdef ENABLE_PKCS11
@@ -2497,16 +2500,6 @@ options_postprocess_mutate (struct options *o)
for (i = 0; i < o->connection_list->len; ++i)
options_postprocess_mutate_ce (o, o->connection_list->array[i]);
-#ifdef ENABLE_SSL
- if (o->tls_server)
- {
- /* Check that DH file is specified, or explicitly disabled */
- notnull (o->dh_file, "DH file (--dh)");
- if (streq (o->dh_file, "none"))
- o->dh_file = NULL;
- }
-#endif
-
#if ENABLE_MANAGEMENT
if (o->http_proxy_override)
options_postprocess_http_proxy_override(o);
@@ -2998,8 +2991,7 @@ options_string (const struct options *o,
o->authname, o->authname_defined,
o->keysize, true, false);
- buf_printf (&out, ",cipher %s",
- translate_cipher_name_to_openvpn(cipher_kt_name (kt.cipher)));
+ buf_printf (&out, ",cipher %s", cipher_kt_name (kt.cipher));
buf_printf (&out, ",auth %s", md_kt_name (kt.digest));
buf_printf (&out, ",keysize %d", kt.cipher_length * 8);
if (o->shared_secret_file)
@@ -3921,9 +3913,9 @@ apply_push_options (struct options *options,
++line_num;
if (parse_line (line, p, SIZE (p), file, line_num, msglevel, &options->gc))
{
- add_option (options, p, file, line_num, 0, msglevel, permission_mask, option_types_found, es);
- }
+ add_option (options, p, file, line_num, 0, msglevel, permission_mask, option_types_found, es);
}
+ }
return true;
}
@@ -6576,29 +6568,14 @@ add_option (struct options *options,
{
int ver;
VERIFY_PERMISSION (OPT_P_GENERAL);
- ver = tls_version_parse(p[1], p[2]);
+ ver = tls_version_min_parse(p[1], p[2]);
if (ver == TLS_VER_BAD)
{
msg (msglevel, "unknown tls-version-min parameter: %s", p[1]);
goto err;
}
- options->ssl_flags &=
- ~(SSLF_TLS_VERSION_MIN_MASK << SSLF_TLS_VERSION_MIN_SHIFT);
- options->ssl_flags |= (ver << SSLF_TLS_VERSION_MIN_SHIFT);
- }
- else if (streq (p[0], "tls-version-max") && p[1])
- {
- int ver;
- VERIFY_PERMISSION (OPT_P_GENERAL);
- ver = tls_version_parse(p[1], NULL);
- if (ver == TLS_VER_BAD)
- {
- msg (msglevel, "unknown tls-version-max parameter: %s", p[1]);
- goto err;
- }
- options->ssl_flags &=
- ~(SSLF_TLS_VERSION_MAX_MASK << SSLF_TLS_VERSION_MAX_SHIFT);
- options->ssl_flags |= (ver << SSLF_TLS_VERSION_MAX_SHIFT);
+ options->ssl_flags &= ~(SSLF_TLS_VERSION_MASK << SSLF_TLS_VERSION_SHIFT);
+ options->ssl_flags |= (ver << SSLF_TLS_VERSION_SHIFT);
}
#ifndef ENABLE_CRYPTO_POLARSSL
else if (streq (p[0], "pkcs12") && p[1])
diff --git a/main/openvpn/src/openvpn/packet_id.c b/main/openvpn/src/openvpn/packet_id.c
index 122830b7..baa49664 100644
--- a/main/openvpn/src/openvpn/packet_id.c
+++ b/main/openvpn/src/openvpn/packet_id.c
@@ -99,12 +99,6 @@ packet_id_init (struct packet_id *p, bool tcp_mode, int seq_backtrack, int time_
p->rec.initialized = true;
}
-bool
-packet_id_initialized (const struct packet_id *pid)
-{
- return pid->rec.initialized;
-}
-
void
packet_id_free (struct packet_id *p)
{
diff --git a/main/openvpn/src/openvpn/packet_id.h b/main/openvpn/src/openvpn/packet_id.h
index 2c786648..3ddaab6a 100644
--- a/main/openvpn/src/openvpn/packet_id.h
+++ b/main/openvpn/src/openvpn/packet_id.h
@@ -213,9 +213,6 @@ struct packet_id
void packet_id_init (struct packet_id *p, bool tcp_mode, int seq_backtrack, int time_backtrack, const char *name, int unit);
void packet_id_free (struct packet_id *p);
-/** Is this struct packet_id initialized? */
-bool packet_id_initialized (const struct packet_id *pid);
-
/* should we accept an incoming packet id ? */
bool packet_id_test (struct packet_id_rec *p,
const struct packet_id_net *pin);
diff --git a/main/openvpn/src/openvpn/ssl.c b/main/openvpn/src/openvpn/ssl.c
index 103a5114..94b7b6d9 100644
--- a/main/openvpn/src/openvpn/ssl.c
+++ b/main/openvpn/src/openvpn/ssl.c
@@ -454,7 +454,7 @@ ssl_put_auth_challenge (const char *cr_str)
* return tls_version_max().
*/
int
-tls_version_parse(const char *vstr, const char *extra)
+tls_version_min_parse(const char *vstr, const char *extra)
{
const int max_version = tls_version_max();
if (!strcmp(vstr, "1.0") && TLS_VER_1_0 <= max_version)
@@ -483,10 +483,7 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
if (options->tls_server)
{
tls_ctx_server_new(new_ctx);
-
- if (options->dh_file)
- tls_ctx_load_dh_params(new_ctx, options->dh_file,
- options->dh_file_inline);
+ tls_ctx_load_dh_params(new_ctx, options->dh_file, options->dh_file_inline);
}
else /* if client */
{
@@ -764,17 +761,11 @@ key_state_init (struct tls_session *session, struct key_state *ks)
reliable_set_timeout (ks->send_reliable, session->opt->packet_timeout);
/* init packet ID tracker */
- if (session->opt->replay)
- {
- packet_id_init (&ks->crypto_options.packet_id, session->opt->tcp_mode,
- session->opt->replay_window, session->opt->replay_time, "SSL",
- ks->key_id);
- }
-
- ks->crypto_options.pid_persist = NULL;
- ks->crypto_options.flags = session->opt->crypto_flags;
- ks->crypto_options.flags &= session->opt->crypto_flags_and;
- ks->crypto_options.flags |= session->opt->crypto_flags_or;
+ packet_id_init (&ks->packet_id,
+ session->opt->tcp_mode,
+ session->opt->replay_window,
+ session->opt->replay_time,
+ "SSL", ks->key_id);
#ifdef MANAGEMENT_DEF_AUTH
ks->mda_key_id = session->opt->mda_context->mda_key_id_counter++;
@@ -802,7 +793,7 @@ key_state_free (struct key_state *ks, bool clear)
key_state_ssl_free(&ks->ks_ssl);
- free_key_ctx_bi (&ks->crypto_options.key_ctx_bi);
+ free_key_ctx_bi (&ks->key);
free_buf (&ks->plaintext_read_buf);
free_buf (&ks->plaintext_write_buf);
free_buf (&ks->ack_write_buf);
@@ -826,7 +817,7 @@ key_state_free (struct key_state *ks, bool clear)
if (ks->key_src)
free (ks->key_src);
- packet_id_free (&ks->crypto_options.packet_id);
+ packet_id_free (&ks->packet_id);
#ifdef PLUGIN_DEF_AUTH
key_state_rm_auth_control_file (ks);
@@ -841,6 +832,13 @@ key_state_free (struct key_state *ks, bool clear)
/** @} addtogroup control_processor */
+/*
+ * Must be called if we move a tls_session in memory.
+ */
+static inline void tls_session_set_self_referential_pointers (struct tls_session* session) {
+ session->tls_auth.packet_id = &session->tls_auth_pid;
+}
+
/**
* Returns whether or not the server should check for username/password
*
@@ -913,15 +911,18 @@ tls_session_init (struct tls_multi *multi, struct tls_session *session)
/* Initialize control channel authentication parameters */
session->tls_auth = session->opt->tls_auth;
+ /* Set session internal pointers (also called if session object is moved in memory) */
+ tls_session_set_self_referential_pointers (session);
+
/* initialize packet ID replay window for --tls-auth */
- packet_id_init (&session->tls_auth.packet_id,
+ packet_id_init (session->tls_auth.packet_id,
session->opt->tcp_mode,
session->opt->replay_window,
session->opt->replay_time,
"TLS_AUTH", session->key_id);
/* load most recent packet-id to replay protect on --tls-auth */
- packet_id_persist_load_obj (session->tls_auth.pid_persist, &session->tls_auth.packet_id);
+ packet_id_persist_load_obj (session->tls_auth.pid_persist, session->tls_auth.packet_id);
key_state_init (session, &session->key[KS_PRIMARY]);
@@ -948,8 +949,8 @@ tls_session_free (struct tls_session *session, bool clear)
{
int i;
- if (packet_id_initialized(&session->tls_auth.packet_id))
- packet_id_free (&session->tls_auth.packet_id);
+ if (session->tls_auth.packet_id)
+ packet_id_free (session->tls_auth.packet_id);
for (i = 0; i < KS_SIZE; ++i)
key_state_free (&session->key[i], false);
@@ -980,6 +981,7 @@ move_session (struct tls_multi* multi, int dest, int src, bool reinit_src)
ASSERT (dest >= 0 && dest < TM_SIZE);
tls_session_free (&multi->session[dest], false);
multi->session[dest] = multi->session[src];
+ tls_session_set_self_referential_pointers (&multi->session[dest]);
if (reinit_src)
tls_session_init (multi, &multi->session[src]);
@@ -1044,6 +1046,9 @@ tls_multi_init (struct tls_options *tls_options)
/* get command line derived options */
ret->opt = *tls_options;
+ /* set up pointer to HMAC object for TLS packet authentication */
+ ret->opt.tls_auth.key_ctx_bi = &ret->opt.tls_auth_key;
+
/* set up list of keys to be scanned by data channel encrypt and decrypt routines */
ASSERT (SIZE (ret->key_scan) == 3);
ret->key_scan[0] = &ret->session[TM_ACTIVE].key[KS_PRIMARY];
@@ -1082,7 +1087,8 @@ tls_auth_standalone_init (struct tls_options *tls_options,
ALLOC_OBJ_CLEAR_GC (tas, struct tls_auth_standalone, gc);
/* set up pointer to HMAC object for TLS packet authentication */
- tas->tls_auth_options.key_ctx_bi = tls_options->tls_auth.key_ctx_bi;
+ tas->tls_auth_key = tls_options->tls_auth_key;
+ tas->tls_auth_options.key_ctx_bi = &tas->tls_auth_key;
tas->tls_auth_options.flags |= CO_PACKET_ID_LONG_FORM;
/* get initial frame parms, still need to finalize */
@@ -1165,11 +1171,11 @@ tls_multi_free (struct tls_multi *multi, bool clear)
static bool
swap_hmac (struct buffer *buf, const struct crypto_options *co, bool incoming)
{
- const struct key_ctx *ctx;
+ struct key_ctx *ctx;
ASSERT (co);
- ctx = (incoming ? &co->key_ctx_bi.decrypt : &co->key_ctx_bi.encrypt);
+ ctx = (incoming ? &co->key_ctx_bi->decrypt : &co->key_ctx_bi->encrypt);
ASSERT (ctx->hmac);
{
@@ -1233,7 +1239,7 @@ write_control_auth (struct tls_session *session,
ASSERT (session_id_write_prepend (&session->session_id, buf));
ASSERT (header = buf_prepend (buf, 1));
*header = ks->key_id | (opcode << P_OPCODE_SHIFT);
- if (session->tls_auth.key_ctx_bi.encrypt.hmac)
+ if (session->tls_auth.key_ctx_bi->encrypt.hmac)
{
/* no encryption, only write hmac */
openvpn_encrypt (buf, null, &session->tls_auth, NULL);
@@ -1247,12 +1253,12 @@ write_control_auth (struct tls_session *session,
*/
static bool
read_control_auth (struct buffer *buf,
- struct crypto_options *co,
+ const struct crypto_options *co,
const struct link_socket_actual *from)
{
struct gc_arena gc = gc_new ();
- if (co->key_ctx_bi.decrypt.hmac)
+ if (co->key_ctx_bi->decrypt.hmac)
{
struct buffer null = clear_buf ();
@@ -1583,41 +1589,6 @@ generate_key_expansion (struct key_ctx_bi *key,
return ret;
}
-/**
- * Initialize the implicit IV for a key_ctx_bi based on TLS session ids and
- * cipher used.
- *
- * @param keys Encrypt/decrypt key context
- * @param cipher_kt Cipher key type info
- * @param session_id_local The local session id for this session
- * @param session_id_remote The remote seession id for this session
- *
- * @return true on success, false on failure.
- */
-static bool
-ssl_init_implicit_iv(struct key_ctx_bi *keys, const cipher_kt_t *cipher_kt,
- const struct session_id *session_id_local,
- const struct session_id *session_id_remote)
-{
- ASSERT (NULL != keys);
- ASSERT (NULL != cipher_kt);
- ASSERT (NULL != session_id_local);
- ASSERT (NULL != session_id_remote);
-
- if (cipher_kt_mode_aead(cipher_kt))
- {
- if (!key_ctx_set_implicit_iv(&keys->encrypt, session_id_local->id,
- SID_SIZE))
- return false;
-
- if (!key_ctx_set_implicit_iv(&keys->decrypt, session_id_remote->id,
- SID_SIZE))
- return false;
- }
-
- return true;
-}
-
static bool
random_bytes_to_buf (struct buffer *buf,
uint8_t *out,
@@ -1807,9 +1778,8 @@ key_method_1_write (struct buffer *buf, struct tls_session *session)
return false;
}
- init_key_ctx (&ks->crypto_options.key_ctx_bi.encrypt, &key,
- &session->opt->key_type, OPENVPN_OP_ENCRYPT,
- "Data Channel Encrypt");
+ init_key_ctx (&ks->key.encrypt, &key, &session->opt->key_type,
+ OPENVPN_OP_ENCRYPT, "Data Channel Encrypt");
CLEAR (key);
/* send local options string */
@@ -1965,7 +1935,7 @@ key_method_2_write (struct buffer *buf, struct tls_session *session)
{
if (ks->authenticated)
{
- if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi,
+ if (!generate_key_expansion (&ks->key,
&session->opt->key_type,
ks->key_src,
&ks->session_id_remote,
@@ -1975,14 +1945,6 @@ key_method_2_write (struct buffer *buf, struct tls_session *session)
msg (D_TLS_ERRORS, "TLS Error: server generate_key_expansion failed");
goto error;
}
-
- if (!ssl_init_implicit_iv(&ks->crypto_options.key_ctx_bi,
- session->opt->key_type.cipher, &session->session_id,
- &ks->session_id_remote))
- {
- msg (D_TLS_ERRORS, "TLS Error: initializing implicit IV failed");
- goto error;
- }
}
CLEAR (*ks->key_src);
@@ -2044,9 +2006,8 @@ key_method_1_read (struct buffer *buf, struct tls_session *session)
buf_clear (buf);
- init_key_ctx (&ks->crypto_options.key_ctx_bi.decrypt, &key,
- &session->opt->key_type, OPENVPN_OP_DECRYPT,
- "Data Channel Decrypt");
+ init_key_ctx (&ks->key.decrypt, &key, &session->opt->key_type,
+ OPENVPN_OP_DECRYPT, "Data Channel Decrypt");
CLEAR (key);
ks->authenticated = true;
return true;
@@ -2186,7 +2147,7 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
*/
if (!session->opt->server)
{
- if (!generate_key_expansion (&ks->crypto_options.key_ctx_bi,
+ if (!generate_key_expansion (&ks->key,
&session->opt->key_type,
ks->key_src,
&session->session_id,
@@ -2196,14 +2157,6 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
msg (D_TLS_ERRORS, "TLS Error: client generate_key_expansion failed");
goto error;
}
-
- if (!ssl_init_implicit_iv(&ks->crypto_options.key_ctx_bi,
- session->opt->key_type.cipher, &session->session_id,
- &ks->session_id_remote))
- {
- msg (D_TLS_ERRORS, "TLS Error: initializing implicit IV failed");
- goto error;
- }
CLEAR (*ks->key_src);
}
@@ -2266,7 +2219,7 @@ tls_process (struct tls_multi *multi,
&& ks->n_bytes >= session->opt->renegotiate_bytes)
|| (session->opt->renegotiate_packets
&& ks->n_packets >= session->opt->renegotiate_packets)
- || (packet_id_close_to_wrapping (&ks->crypto_options.packet_id.send))))
+ || (packet_id_close_to_wrapping (&ks->packet_id.send))))
{
msg (D_TLS_DEBUG_LOW,
"TLS: soft reset sec=%d bytes=" counter_format "/%d pkts=" counter_format "/%d",
@@ -2820,7 +2773,7 @@ bool
tls_pre_decrypt (struct tls_multi *multi,
const struct link_socket_actual *from,
struct buffer *buf,
- struct crypto_options **opt)
+ struct crypto_options *opt)
{
struct gc_arena gc = gc_new ();
bool ret = false;
@@ -2867,12 +2820,13 @@ tls_pre_decrypt (struct tls_multi *multi,
&& link_socket_actual_match (from, &ks->remote_addr))
{
/* return appropriate data channel decrypt key in opt */
- *opt = &ks->crypto_options;
+ opt->key_ctx_bi = &ks->key;
+ opt->packet_id = multi->opt.replay ? &ks->packet_id : NULL;
+ opt->pid_persist = NULL;
+ opt->flags &= multi->opt.crypto_flags_and;
+ opt->flags |= multi->opt.crypto_flags_or;
- ASSERT (buf_advance (buf, 1));
- if (op == P_DATA_V2) {
- buf_advance (buf, 3);
- }
+ ASSERT (buf_advance (buf, (op == P_DATA_V2) ? 4 : 1));
++ks->n_packets;
ks->n_bytes += buf->len;
@@ -3249,7 +3203,10 @@ tls_pre_decrypt (struct tls_multi *multi,
done:
buf->len = 0;
- *opt = NULL;
+ opt->key_ctx_bi = NULL;
+ opt->packet_id = NULL;
+ opt->pid_persist = NULL;
+ opt->flags &= multi->opt.crypto_flags_and;
gc_free (&gc);
return ret;
@@ -3367,7 +3324,6 @@ tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
return ret;
error:
-
tls_clear_error();
gc_free (&gc);
return ret;
@@ -3376,7 +3332,7 @@ tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
/* Choose the key with which to encrypt a data packet */
void
tls_pre_encrypt (struct tls_multi *multi,
- struct buffer *buf, struct crypto_options **opt)
+ struct buffer *buf, struct crypto_options *opt)
{
multi->save_ks = NULL;
if (buf->len > 0)
@@ -3405,7 +3361,11 @@ tls_pre_encrypt (struct tls_multi *multi,
if (ks_select)
{
- *opt = &ks_select->crypto_options;
+ opt->key_ctx_bi = &ks_select->key;
+ opt->packet_id = multi->opt.replay ? &ks_select->packet_id : NULL;
+ opt->pid_persist = NULL;
+ opt->flags &= multi->opt.crypto_flags_and;
+ opt->flags |= multi->opt.crypto_flags_or;
multi->save_ks = ks_select;
dmsg (D_TLS_KEYSELECT, "TLS: tls_pre_encrypt: key_id=%d", ks_select->key_id);
return;
@@ -3420,7 +3380,10 @@ tls_pre_encrypt (struct tls_multi *multi,
}
buf->len = 0;
- *opt = NULL;
+ opt->key_ctx_bi = NULL;
+ opt->packet_id = NULL;
+ opt->pid_persist = NULL;
+ opt->flags &= multi->opt.crypto_flags_and;
}
/* Prepend the appropriate opcode to encrypted buffer prior to TCP/UDP send */
@@ -3530,7 +3493,7 @@ const struct link_socket_actual *from)
for (i = 0; i < KEY_SCAN_SIZE; ++i)
{
struct key_state *ks = multi->key_scan[i];
- if (DECRYPT_KEY_ENABLED (multi, ks) && ks->authenticated && link_socket_actual_defined(&ks->remote_addr))
+ if (DECRYPT_KEY_ENABLED (multi, ks) && ks->authenticated && link_socket_actual_defined(&ks->remote_addr))
{
if (link_socket_actual_match (from, &ks->remote_addr))
continue;
diff --git a/main/openvpn/src/openvpn/ssl.h b/main/openvpn/src/openvpn/ssl.h
index cc80043e..a338745e 100644
--- a/main/openvpn/src/openvpn/ssl.h
+++ b/main/openvpn/src/openvpn/ssl.h
@@ -136,6 +136,7 @@
*/
struct tls_auth_standalone
{
+ struct key_ctx_bi tls_auth_key;
struct crypto_options tls_auth_options;
struct frame frame;
};
@@ -292,8 +293,9 @@ int tls_multi_process (struct tls_multi *multi,
* of this packet.
* @param from - The source address of the packet.
* @param buf - A buffer structure containing the incoming packet.
- * @param opt - Returns a crypto options structure with the appropriate security
- * parameters to handle the packet if it is a data channel packet.
+ * @param opt - A crypto options structure that will be loaded with the
+ * appropriate security parameters to handle the packet if it is a
+ * data channel packet.
*
* @return
* @li True if the packet is a control channel packet that has been
@@ -304,7 +306,7 @@ int tls_multi_process (struct tls_multi *multi,
bool tls_pre_decrypt (struct tls_multi *multi,
const struct link_socket_actual *from,
struct buffer *buf,
- struct crypto_options **opt);
+ struct crypto_options *opt);
/**************************************************************************/
@@ -353,15 +355,15 @@ bool tls_pre_decrypt_lite (const struct tls_auth_standalone *tas,
* @ingroup data_crypto
*
* If no appropriate security parameters can be found, or if some other
- * error occurs, then the buffer is set to empty, and the parameters to a NULL
- * pointer.
+ * error occurs, then the buffer is set to empty.
*
* @param multi - The TLS state for this packet's destination VPN tunnel.
* @param buf - The buffer containing the outgoing packet.
- * @param opt - Returns a crypto options structure with the security parameters.
+ * @param opt - The crypto options structure into which the appropriate
+ * security parameters should be loaded.
*/
void tls_pre_encrypt (struct tls_multi *multi,
- struct buffer *buf, struct crypto_options **opt);
+ struct buffer *buf, struct crypto_options *opt);
/**
diff --git a/main/openvpn/src/openvpn/ssl_backend.h b/main/openvpn/src/openvpn/ssl_backend.h
index b0777bf5..bfd15496 100644
--- a/main/openvpn/src/openvpn/ssl_backend.h
+++ b/main/openvpn/src/openvpn/ssl_backend.h
@@ -109,12 +109,11 @@ void tls_clear_error();
* @return One of the TLS_VER_x constants or TLS_VER_BAD
* if a parse error should be flagged.
*/
-#define TLS_VER_BAD -1
-#define TLS_VER_UNSPEC 0 /* default */
-#define TLS_VER_1_0 1
-#define TLS_VER_1_1 2
-#define TLS_VER_1_2 3
-int tls_version_parse(const char *vstr, const char *extra);
+#define TLS_VER_BAD -1
+#define TLS_VER_1_0 0 /* default */
+#define TLS_VER_1_1 1
+#define TLS_VER_1_2 2
+int tls_version_min_parse(const char *vstr, const char *extra);
/**
* Return the maximum TLS version (as a TLS_VER_x constant)
diff --git a/main/openvpn/src/openvpn/ssl_common.h b/main/openvpn/src/openvpn/ssl_common.h
index 748febcf..cb0ba628 100644
--- a/main/openvpn/src/openvpn/ssl_common.h
+++ b/main/openvpn/src/openvpn/ssl_common.h
@@ -160,8 +160,9 @@ struct key_state
int initial_opcode; /* our initial P_ opcode */
struct session_id session_id_remote; /* peer's random session ID */
struct link_socket_actual remote_addr; /* peer's IP addr */
+ struct packet_id packet_id; /* for data channel, to prevent replay attacks */
- struct crypto_options crypto_options;/* data channel crypto options */
+ struct key_ctx_bi key; /* data channel keys for encrypt/decrypt/hmac */
struct key_source2 *key_src; /* source entropy for key expansion */
@@ -258,7 +259,6 @@ struct tls_options
bool pass_config_info;
/* struct crypto_option flags */
- unsigned int crypto_flags;
unsigned int crypto_flags_and;
unsigned int crypto_flags_or;
@@ -268,6 +268,7 @@ struct tls_options
/* packet authentication for TLS handshake */
struct crypto_options tls_auth;
+ struct key_ctx_bi tls_auth_key;
/* frame parameters for TLS control channel */
struct frame frame;
@@ -295,10 +296,8 @@ struct tls_options
# define SSLF_AUTH_USER_PASS_OPTIONAL (1<<2)
# define SSLF_OPT_VERIFY (1<<4)
# define SSLF_CRL_VERIFY_DIR (1<<5)
-# define SSLF_TLS_VERSION_MIN_SHIFT 6
-# define SSLF_TLS_VERSION_MIN_MASK 0xF /* (uses bit positions 6 to 9) */
-# define SSLF_TLS_VERSION_MAX_SHIFT 10
-# define SSLF_TLS_VERSION_MAX_MASK 0xF /* (uses bit positions 10 to 13) */
+# define SSLF_TLS_VERSION_SHIFT 6
+# define SSLF_TLS_VERSION_MASK 0xF /* (uses bit positions 6 to 9) */
unsigned int ssl_flags;
#ifdef MANAGEMENT_DEF_AUTH
@@ -358,6 +357,7 @@ struct tls_session
/* authenticate control packets */
struct crypto_options tls_auth;
+ struct packet_id tls_auth_pid;
int initial_opcode; /* our initial P_ opcode */
struct session_id session_id; /* our random session ID */
diff --git a/main/openvpn/src/openvpn/ssl_openssl.c b/main/openvpn/src/openvpn/ssl_openssl.c
index c1a01002..adf3ae6f 100644
--- a/main/openvpn/src/openvpn/ssl_openssl.c
+++ b/main/openvpn/src/openvpn/ssl_openssl.c
@@ -104,7 +104,7 @@ tls_ctx_server_new(struct tls_root_ctx *ctx)
ctx->ctx = SSL_CTX_new (SSLv23_server_method ());
if (ctx->ctx == NULL)
- crypto_msg (M_FATAL, "SSL_CTX_new SSLv23_server_method");
+ msg (M_SSLERR, "SSL_CTX_new SSLv23_server_method");
}
void
@@ -115,7 +115,7 @@ tls_ctx_client_new(struct tls_root_ctx *ctx)
ctx->ctx = SSL_CTX_new (SSLv23_client_method ());
if (ctx->ctx == NULL)
- crypto_msg (M_FATAL, "SSL_CTX_new SSLv23_client_method");
+ msg (M_SSLERR, "SSL_CTX_new SSLv23_client_method");
}
void
@@ -152,7 +152,7 @@ info_callback (INFO_CALLBACK_SSL_CONST SSL * s, int where, int ret)
}
else if (where & SSL_CB_ALERT)
{
- dmsg(D_HANDSHAKE_VERBOSE, "SSL alert (%s): %s: %s",
+ 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));
@@ -184,23 +184,15 @@ tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags)
/* 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)
+ const int tls_version_min = (ssl_flags >> SSLF_TLS_VERSION_SHIFT) & SSLF_TLS_VERSION_MASK;
+ if (tls_version_min > 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)
+ if (tls_version_min > 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)
+ if (tls_version_min > TLS_VER_1_2)
sslopt |= SSL_OP_NO_TLSv1_2;
#endif
SSL_CTX_set_options (ctx->ctx, sslopt);
@@ -235,7 +227,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
{
/* Use sane default (disable export, and unsupported cipher modes) */
if(!SSL_CTX_set_cipher_list(ctx->ctx, "DEFAULT:!EXP:!PSK:!SRP"))
- crypto_msg (M_FATAL, "Failed to set default TLS cipher list.");
+ msg(M_SSLERR, "Failed to set default TLS cipher list.");
return;
}
@@ -288,8 +280,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
// Make sure new cipher name fits in cipher string
if (((sizeof(openssl_ciphers)-1) - openssl_ciphers_len) < current_cipher_len) {
- crypto_msg (M_FATAL, "Failed to set restricted TLS cipher list, too "
- "long (>%d).", (int)sizeof(openssl_ciphers)-1);
+ msg(M_SSLERR, "Failed to set restricted TLS cipher list, too long (>%d).", (int)sizeof(openssl_ciphers)-1);
}
// Concatenate cipher name to OpenSSL cipher string
@@ -306,8 +297,7 @@ tls_ctx_restrict_ciphers(struct tls_root_ctx *ctx, const char *ciphers)
// 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);
+ msg(M_SSLERR, "Failed to set restricted TLS cipher list: %s", openssl_ciphers);
}
void
@@ -323,22 +313,22 @@ tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file,
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");
+ msg (M_SSLERR, "Cannot open memory BIO for inline DH parameters");
}
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);
+ msg (M_SSLERR, "Cannot open %s for DH parameters", dh_file);
}
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);
+ msg (M_SSLERR, "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 (M_SSLERR, "SSL_CTX_set_tmp_dh");
msg (D_TLS_DEBUG_LOW, "Diffie-Hellman initialized with %d bit key",
8 * DH_size (dh));
@@ -407,7 +397,7 @@ tls_ctx_load_ecdh_params (struct tls_root_ctx *ctx, const char *curve_name
}
if (!SSL_CTX_set_tmp_ecdh(ctx->ctx, ecdh))
- crypto_msg (M_FATAL, "SSL_CTX_set_tmp_ecdh: cannot add curve");
+ msg (M_SSLERR, "SSL_CTX_set_tmp_ecdh: cannot add curve");
msg (D_TLS_DEBUG_LOW, "ECDH curve %s added", sname);
@@ -443,7 +433,7 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
BIO_push(b64, bio);
p12 = d2i_PKCS12_bio(b64, NULL);
if (!p12)
- crypto_msg (M_FATAL, "Error reading inline PKCS#12 file");
+ msg(M_SSLERR, "Error reading inline PKCS#12 file");
BIO_free(b64);
BIO_free(bio);
}
@@ -451,11 +441,11 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
{
/* Load the PKCS #12 file */
if (!(fp = platform_fopen(pkcs12_file, "rb")))
- crypto_msg (M_FATAL, "Error opening file %s", pkcs12_file);
+ msg(M_SSLERR, "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);
+ msg(M_SSLERR, "Error reading PKCS#12 file %s", pkcs12_file);
}
/* Parse the PKCS #12 file */
@@ -478,16 +468,16 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
/* Load Certificate */
if (!SSL_CTX_use_certificate (ctx->ctx, cert))
- crypto_msg (M_FATAL, "Cannot use certificate");
+ msg (M_SSLERR, "Cannot use certificate");
/* Load Private Key */
if (!SSL_CTX_use_PrivateKey (ctx->ctx, pkey))
- crypto_msg (M_FATAL, "Cannot use private key");
+ msg (M_SSLERR, "Cannot use private key");
warn_if_group_others_accessible (pkcs12_file);
/* Check Private Key */
if (!SSL_CTX_check_private_key (ctx->ctx))
- crypto_msg (M_FATAL, "Private key does not match the certificate");
+ msg (M_SSLERR, "Private key does not match the certificate");
/* Set Certificate Verification chain */
if (load_ca_file)
@@ -501,11 +491,9 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
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)");
+ msg (M_SSLERR, "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)");
+ msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)");
}
}
} else {
@@ -519,8 +507,7 @@ tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file,
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)");
+ msg (M_SSLERR, "Cannot add extra certificate to chain (SSL_CTX_add_extra_chain_cert)");
}
}
}
@@ -535,8 +522,8 @@ tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)
/* Load Certificate and Private Key */
if (!SSL_CTX_use_CryptoAPI_certificate (ctx->ctx, cryptoapi_cert))
- crypto_msg (M_SSLERR, "Cannot load certificate \"%s\" from Microsoft "
- "Certificate Store", cryptoapi_cert);
+ msg (M_SSLERR, "Cannot load certificate \"%s\" from Microsoft Certificate Store",
+ cryptoapi_cert);
}
#endif /* WIN32 */
@@ -550,9 +537,9 @@ tls_ctx_add_extra_certs (struct tls_root_ctx *ctx, BIO *bio)
if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */
break;
if (!cert)
- crypto_msg (M_FATAL, "Error reading extra certificate");
+ msg (M_SSLERR, "Error reading extra certificate");
if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1)
- crypto_msg (M_FATAL, "Error adding extra certificate");
+ msg (M_SSLERR, "Error adding extra certificate");
}
}
@@ -600,9 +587,9 @@ end:
if (!ret)
{
if (inline_file)
- crypto_msg (M_FATAL, "Cannot load inline certificate file");
+ msg (M_SSLERR, "Cannot load inline certificate file");
else
- crypto_msg (M_FATAL, "Cannot load certificate file %s", cert_file);
+ msg (M_SSLERR, "Cannot load certificate file %s", cert_file);
}
if (in != NULL)
@@ -660,14 +647,14 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file,
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);
+ msg (M_WARN|M_SSL, "Cannot load private key file %s", priv_key_file);
goto end;
}
warn_if_group_others_accessible (priv_key_file);
/* Check Private Key */
if (!SSL_CTX_check_private_key (ssl_ctx))
- crypto_msg (M_FATAL, "Private key does not match the certificate");
+ msg (M_SSLERR, "Private key does not match the certificate");
ret = 0;
end:
@@ -818,7 +805,7 @@ tls_ctx_use_external_private_key (struct tls_root_ctx *ctx,
if (rsa_meth)
free(rsa_meth);
}
- crypto_msg (M_FATAL, "Cannot enable SSL external private key capability");
+ msg (M_SSLERR, "Cannot enable SSL external private key capability");
return 0;
}
@@ -848,8 +835,7 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
store = SSL_CTX_get_cert_store(ctx->ctx);
if (!store)
- crypto_msg (M_FATAL, "Cannot get certificate store "
- "(SSL_CTX_get_cert_store)");
+ msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)");
/* Try to add certificates and CRLs from ca_file */
if (ca_file)
@@ -872,7 +858,7 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
if (tls_server && !info->x509)
{
- crypto_msg (M_FATAL, "X509 name was missing in TLS mode");
+ msg (M_SSLERR, "X509 name was missing in TLS mode");
}
if (info->x509)
@@ -908,8 +894,7 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
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);
+ msg (M_WARN, "Cannot load CA certificate file %s (entry %d did not validate)", np(ca_file), added);
}
prev = cnum;
}
@@ -922,14 +907,12 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
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));
+ msg (M_SSLERR, "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);
+ msg (M_SSLERR, "Cannot load CA certificate file %s (only %d of %d entries were valid X509 names)", np(ca_file), cnum, added);
}
if (in)
@@ -943,7 +926,7 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file,
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);
+ msg(M_SSLERR, "Cannot add lookup at --capath %s", ca_path);
X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
}
}
@@ -960,7 +943,7 @@ tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file
in = BIO_new_file (extra_certs_file, "r");
if (in == NULL)
- crypto_msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file);
+ msg (M_SSLERR, "Cannot load extra-certs file: %s", extra_certs_file);
else
tls_ctx_add_extra_certs (ctx, in);
@@ -1052,7 +1035,7 @@ getbio (BIO_METHOD * type, const char *desc)
BIO *ret;
ret = BIO_new (type);
if (!ret)
- crypto_msg (M_FATAL, "Error creating %s BIO", desc);
+ msg (M_SSLERR, "Error creating %s BIO", desc);
return ret;
}
@@ -1086,15 +1069,16 @@ bio_write (BIO *bio, const uint8_t *data, int size, const char *desc)
}
else
{
- crypto_msg (D_TLS_ERRORS, "TLS ERROR: BIO write %s error", desc);
+ msg (D_TLS_ERRORS | M_SSL, "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);
+ msg (D_TLS_ERRORS | M_SSL,
+ "TLS ERROR: BIO write %s incomplete %d/%d", desc, i, size);
ret = -1;
ERR_clear_error ();
}
@@ -1160,7 +1144,8 @@ bio_read (BIO *bio, struct buffer *buf, int maxlen, const char *desc)
}
else
{
- crypto_msg (D_TLS_ERRORS, "TLS_ERROR: BIO read %s error", desc);
+ msg (D_TLS_ERRORS | M_SSL, "TLS_ERROR: BIO read %s error",
+ desc);
buf->len = 0;
ret = -1;
ERR_clear_error ();
@@ -1190,7 +1175,7 @@ key_state_ssl_init(struct key_state_ssl *ks_ssl, const struct tls_root_ctx *ssl_
ks_ssl->ssl = SSL_new (ssl_ctx->ctx);
if (!ks_ssl->ssl)
- crypto_msg (M_FATAL, "SSL_new failed");
+ msg (M_SSLERR, "SSL_new failed");
/* put session * in ssl object so we can access it
from verify callback*/
@@ -1365,11 +1350,11 @@ show_available_tls_ciphers (const char *cipher_list)
tls_ctx.ctx = SSL_CTX_new (SSLv23_method ());
if (!tls_ctx.ctx)
- crypto_msg (M_FATAL, "Cannot create SSL_CTX object");
+ msg (M_SSLERR, "Cannot create SSL_CTX object");
ssl = SSL_new (tls_ctx.ctx);
if (!ssl)
- crypto_msg (M_FATAL, "Cannot create SSL object");
+ msg (M_SSLERR, "Cannot create SSL object");
tls_ctx_restrict_ciphers(&tls_ctx, cipher_list);
@@ -1410,7 +1395,7 @@ show_available_curves()
curves = OPENSSL_malloc((int)(sizeof(EC_builtin_curve) * crv_len));
if (curves == NULL)
- crypto_msg (M_FATAL, "Cannot create EC_builtin_curve object");
+ msg (M_SSLERR, "Cannot create EC_builtin_curve object");
else
{
if (EC_get_builtin_curves(curves, crv_len))
@@ -1427,7 +1412,7 @@ show_available_curves()
}
else
{
- crypto_msg (M_FATAL, "Cannot get list of builtin curves");
+ msg (M_SSLERR, "Cannot get list of builtin curves");
}
OPENSSL_free(curves);
}
@@ -1446,10 +1431,10 @@ get_highest_preference_tls_cipher (char *buf, int size)
ctx = SSL_CTX_new (SSLv23_method ());
if (!ctx)
- crypto_msg (M_FATAL, "Cannot create SSL_CTX object");
+ msg (M_SSLERR, "Cannot create SSL_CTX object");
ssl = SSL_new (ctx);
if (!ssl)
- crypto_msg (M_FATAL, "Cannot create SSL object");
+ msg (M_SSLERR, "Cannot create SSL object");
cipher_name = SSL_get_cipher_list (ssl, 0);
strncpynt (buf, cipher_name, size);
diff --git a/main/openvpn/src/openvpn/ssl_polarssl.c b/main/openvpn/src/openvpn/ssl_polarssl.c
index 385024e1..387e6369 100644
--- a/main/openvpn/src/openvpn/ssl_polarssl.c
+++ b/main/openvpn/src/openvpn/ssl_polarssl.c
@@ -218,13 +218,13 @@ tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file,
{
if (!strcmp (dh_file, INLINE_FILE_TAG) && dh_inline)
{
- if (!polar_ok(dhm_parse_dhm(ctx->dhm_ctx,
- (const unsigned char *) dh_inline, strlen(dh_inline))))
+ if (0 != dhm_parse_dhm(ctx->dhm_ctx, (const unsigned char *) dh_inline,
+ strlen(dh_inline)))
msg (M_FATAL, "Cannot read inline DH parameters");
}
else
{
- if (!polar_ok(dhm_parse_dhmfile(ctx->dhm_ctx, dh_file)))
+ if (0 != dhm_parse_dhmfile(ctx->dhm_ctx, dh_file))
msg (M_FATAL, "Cannot read DH parameters from file %s", dh_file);
}
@@ -268,15 +268,18 @@ tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file,
if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_inline)
{
- if (!polar_ok(x509_crt_parse(ctx->crt_chain,
- (const unsigned char *) cert_inline, strlen(cert_inline))))
+ if (0 != x509_crt_parse(ctx->crt_chain,
+ (const unsigned char *) cert_inline, strlen(cert_inline)))
msg (M_FATAL, "Cannot load inline certificate file");
}
else
{
- if (!polar_ok(x509_crt_parse_file(ctx->crt_chain, cert_file)))
+ int retval = x509_crt_parse_file(ctx->crt_chain, cert_file);
+ if (0 != retval)
{
- msg (M_FATAL, "Cannot load certificate file %s", cert_file);
+ char errstr[128];
+ polarssl_strerror(retval, errstr, sizeof(errstr));
+ msg (M_FATAL, "Cannot load certificate file %s (%s)", cert_file, errstr);
}
}
}
@@ -314,7 +317,7 @@ tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file,
status = pk_parse_keyfile(ctx->priv_key, priv_key_file, passbuf);
}
}
- if (!polar_ok(status))
+ if (0 != status)
{
#ifdef ENABLE_MANAGEMENT
if (management && (POLARSSL_ERR_PK_PASSWORD_MISMATCH == status))
@@ -409,7 +412,7 @@ static inline int external_pkcs1_sign( void *ctx_voidptr,
if( md_info == NULL )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
- if (!polar_ok(oid_get_oid_by_md( md_alg, &oid, &oid_size )))
+ if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
hashlen = md_get_size( md_info );
@@ -494,43 +497,49 @@ static inline size_t external_key_len(void *vctx)
#endif
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
+ const char *ca_file_inline,
+ const char *ca_path, bool tls_server
)
{
if (ca_path)
msg(M_FATAL, "ERROR: PolarSSL 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_file_inline)
{
- if (!polar_ok(x509_crt_parse(ctx->ca_chain,
- (const unsigned char *) ca_inline, strlen(ca_inline))))
+ if (0 != x509_crt_parse(ctx->ca_chain, (unsigned char *) ca_file_inline,
+ strlen(ca_file_inline)))
msg (M_FATAL, "Cannot load inline CA certificates");
}
else
{
/* Load CA file for verifying peer supplied certificate */
- if (!polar_ok(x509_crt_parse_file(ctx->ca_chain, ca_file)))
- msg (M_FATAL, "Cannot load CA certificate file %s", ca_file);
+ int retval = x509_crt_parse_file(ctx->ca_chain, ca_file);
+ if (0 != retval)
+ {
+ char errstr[128];
+ polarssl_strerror(retval, errstr, sizeof(errstr));
+ msg (M_FATAL, "Cannot load CA certificate file %s (%s)", ca_file, errstr);
+ }
}
}
void
tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file,
- const char *extra_certs_inline
+ const char *extra_certs_file_inline
)
{
ASSERT(NULL != ctx);
- if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_inline)
+ if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline)
{
- if (!polar_ok(x509_crt_parse(ctx->crt_chain,
- (const unsigned char *) extra_certs_inline,
- strlen(extra_certs_inline))))
+ if (0 != x509_crt_parse(ctx->crt_chain,
+ (unsigned char *) extra_certs_file_inline,
+ strlen(extra_certs_file_inline)))
msg (M_FATAL, "Cannot load inline extra-certs file");
}
else
{
- if (!polar_ok(x509_crt_parse_file(ctx->crt_chain, extra_certs_file)))
+ if (0 != x509_crt_parse_file(ctx->crt_chain, extra_certs_file))
msg (M_FATAL, "Cannot load extra-certs file: %s", extra_certs_file);
}
}
@@ -636,8 +645,10 @@ static int endless_buf_write( void *ctx, const unsigned char *in, size_t len )
static void my_debug( void *ctx, int level, const char *str )
{
- int my_loglevel = (level < 2) ? D_TLS_DEBUG_MED : D_TLS_DEBUG;
- msg (my_loglevel, "PolarSSL alert: %s", str);
+ if (level == 1)
+ {
+ dmsg (D_HANDSHAKE_VERBOSE, "PolarSSL alert: %s", str);
+ }
}
/*
@@ -674,40 +685,6 @@ tls_version_max(void)
#endif
}
-/**
- * Convert an OpenVPN tls-version variable to PolarSSl 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 polarssl format.
- * Must be a valid pointer.
- * @param minor Returns the TLS minor version in polarssl 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 = SSL_MAJOR_VERSION_3;
- *minor = SSL_MINOR_VERSION_1;
- break;
- case TLS_VER_1_1:
- *major = SSL_MAJOR_VERSION_3;
- *minor = SSL_MINOR_VERSION_2;
- break;
- case TLS_VER_1_2:
- *major = SSL_MAJOR_VERSION_3;
- *minor = SSL_MINOR_VERSION_3;
- break;
- default:
- msg(M_FATAL, "%s: invalid TLS version %d", __func__, tls_ver);
- break;
- }
-}
-
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)
{
@@ -716,91 +693,88 @@ void key_state_ssl_init(struct key_state_ssl *ks_ssl,
CLEAR(*ks_ssl);
ALLOC_OBJ_CLEAR(ks_ssl->ctx, ssl_context);
+ if (0 == ssl_init(ks_ssl->ctx))
+ {
+ /* Initialise SSL context */
+ ssl_set_dbg (ks_ssl->ctx, my_debug, NULL);
+ ssl_set_endpoint (ks_ssl->ctx, ssl_ctx->endpoint);
- ASSERT (polar_ok(ssl_init(ks_ssl->ctx)));
-
- /* Initialise SSL context */
- ssl_set_dbg (ks_ssl->ctx, my_debug, NULL);
- ssl_set_endpoint (ks_ssl->ctx, ssl_ctx->endpoint);
-
- ssl_set_rng (ks_ssl->ctx, ctr_drbg_random, rand_ctx_get());
+ ssl_set_rng (ks_ssl->ctx, ctr_drbg_random, rand_ctx_get());
- if (ssl_ctx->allowed_ciphers)
- ssl_set_ciphersuites (ks_ssl->ctx, ssl_ctx->allowed_ciphers);
+ if (ssl_ctx->allowed_ciphers)
+ ssl_set_ciphersuites (ks_ssl->ctx, ssl_ctx->allowed_ciphers);
- /* Initialise authentication information */
- if (is_server)
- ASSERT (polar_ok(ssl_set_dh_param_ctx(ks_ssl->ctx, ssl_ctx->dhm_ctx)));
+ /* Initialise authentication information */
+ if (is_server)
+ ssl_set_dh_param_ctx (ks_ssl->ctx, ssl_ctx->dhm_ctx );
#if defined(ENABLE_PKCS11)
- if (ssl_ctx->priv_key_pkcs11 != NULL)
- ASSERT (polar_ok(ssl_set_own_cert_alt(ks_ssl->ctx, ssl_ctx->crt_chain,
- ssl_ctx->priv_key_pkcs11, ssl_pkcs11_decrypt, ssl_pkcs11_sign,
- ssl_pkcs11_key_len)));
- else
+ if (ssl_ctx->priv_key_pkcs11 != NULL)
+ ssl_set_own_cert_alt( ks_ssl->ctx, ssl_ctx->crt_chain,
+ ssl_ctx->priv_key_pkcs11, ssl_pkcs11_decrypt, ssl_pkcs11_sign,
+ ssl_pkcs11_key_len );
+ else
#endif
#if defined(MANAGMENT_EXTERNAL_KEY)
- if (ssl_ctx->external_key != NULL)
- ASSERT (polar_ok(ssl_set_own_cert_alt(ks_ssl->ctx, ssl_ctx->crt_chain,
- ssl_ctx->external_key, NULL, external_pkcs1_sign,
- external_key_len)));
- else
+ if (ssl_ctx->external_key != NULL)
+ ssl_set_own_cert_alt( ks_ssl->ctx, ssl_ctx->crt_chain,
+ ssl_ctx->external_key, NULL, external_pkcs1_sign,
+ external_key_len );
+ else
#endif
- ASSERT (polar_ok(ssl_set_own_cert( ks_ssl->ctx, ssl_ctx->crt_chain,
- ssl_ctx->priv_key )));
+ ssl_set_own_cert( ks_ssl->ctx, 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_NOT_REQUIRED)
- {
- msg (M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION "
- "--client-cert-not-required may accept clients which do not present "
- "a certificate");
- }
- else
+ if (session->opt->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)
+ {
+ msg (M_WARN, "WARNING: POTENTIALLY DANGEROUS OPTION "
+ "--client-cert-not-required may accept clients which do not present "
+ "a certificate");
+ }
+ else
#endif
- {
- ssl_set_authmode (ks_ssl->ctx, SSL_VERIFY_REQUIRED);
- ssl_set_verify (ks_ssl->ctx, verify_callback, session);
- }
-
- /* TODO: PolarSSL does not currently support sending the CA chain to the client */
- ssl_set_ca_chain (ks_ssl->ctx, ssl_ctx->ca_chain, NULL, NULL );
-
- /* 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 = SSL_MAJOR_VERSION_3;
- int minor = SSL_MINOR_VERSION_1;
-
- if (tls_version_min > TLS_VER_UNSPEC)
- tls_version_to_major_minor(tls_version_min, &major, &minor);
-
- ssl_set_min_version(ks_ssl->ctx, major, minor);
- }
+ {
+ ssl_set_authmode (ks_ssl->ctx, SSL_VERIFY_REQUIRED);
+ ssl_set_verify (ks_ssl->ctx, verify_callback, session);
+ }
- /* Initialize maximum TLS version */
- {
- const int tls_version_max =
- (session->opt->ssl_flags >> SSLF_TLS_VERSION_MAX_SHIFT) &
- SSLF_TLS_VERSION_MAX_MASK;
+ /* TODO: PolarSSL does not currently support sending the CA chain to the client */
+ ssl_set_ca_chain (ks_ssl->ctx, ssl_ctx->ca_chain, NULL, NULL );
- if (tls_version_max > TLS_VER_UNSPEC)
+ /* Initialize minimum TLS version */
{
- int major, minor;
- tls_version_to_major_minor(tls_version_max, &major, &minor);
- ssl_set_max_version(ks_ssl->ctx, major, minor);
+ const int tls_version_min = (session->opt->ssl_flags >> SSLF_TLS_VERSION_SHIFT) & SSLF_TLS_VERSION_MASK;
+ int polar_major;
+ int polar_minor;
+ switch (tls_version_min)
+ {
+ case TLS_VER_1_0:
+ default:
+ polar_major = SSL_MAJOR_VERSION_3;
+ polar_minor = SSL_MINOR_VERSION_1;
+ break;
+#if defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_2)
+ case TLS_VER_1_1:
+ polar_major = SSL_MAJOR_VERSION_3;
+ polar_minor = SSL_MINOR_VERSION_2;
+ break;
+#endif
+#if defined(SSL_MAJOR_VERSION_3) && defined(SSL_MINOR_VERSION_3)
+ case TLS_VER_1_2:
+ polar_major = SSL_MAJOR_VERSION_3;
+ polar_minor = SSL_MINOR_VERSION_3;
+ break;
+#endif
+ }
+ ssl_set_min_version(ks_ssl->ctx, polar_major, polar_minor);
}
- }
- /* Initialise BIOs */
- ALLOC_OBJ_CLEAR (ks_ssl->ct_in, endless_buffer);
- ALLOC_OBJ_CLEAR (ks_ssl->ct_out, endless_buffer);
- ssl_set_bio (ks_ssl->ctx, endless_buf_read, ks_ssl->ct_in,
- endless_buf_write, ks_ssl->ct_out);
+ /* Initialise BIOs */
+ ALLOC_OBJ_CLEAR (ks_ssl->ct_in, endless_buffer);
+ ALLOC_OBJ_CLEAR (ks_ssl->ct_out, endless_buffer);
+ ssl_set_bio (ks_ssl->ctx, endless_buf_read, ks_ssl->ct_in,
+ endless_buf_write, ks_ssl->ct_out);
+ }
}
void
@@ -847,8 +821,7 @@ key_state_write_plaintext (struct key_state_ssl *ks, struct buffer *buf)
perf_pop ();
if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
return 0;
- polar_log_err(D_TLS_ERRORS, retval,
- "TLS ERROR: write tls_write_plaintext error");
+ msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_plaintext error");
return -1;
}
@@ -895,8 +868,7 @@ key_state_write_plaintext_const (struct key_state_ssl *ks, const uint8_t *data,
perf_pop ();
if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
return 0;
- polar_log_err (D_TLS_ERRORS, retval,
- "TLS ERROR: write tls_write_plaintext_const error");
+ msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_plaintext_const error");
return -1;
}
@@ -922,6 +894,7 @@ key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf,
{
int retval = 0;
int len = 0;
+ char error_message[1024];
perf_push (PERF_BIO_READ_CIPHERTEXT);
@@ -947,8 +920,8 @@ key_state_read_ciphertext (struct key_state_ssl *ks, struct buffer *buf,
perf_pop ();
if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
return 0;
- polar_log_err (D_TLS_ERRORS, retval,
- "TLS_ERROR: read tls_read_ciphertext error");
+ error_strerror(retval, error_message, sizeof(error_message));
+ msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_ciphertext error: %d %s", retval, error_message);
buf->len = 0;
return -1;
}
@@ -991,8 +964,7 @@ key_state_write_ciphertext (struct key_state_ssl *ks, struct buffer *buf)
if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
return 0;
- polar_log_err (D_TLS_ERRORS, retval,
- "TLS ERROR: write tls_write_ciphertext error");
+ msg (D_TLS_ERRORS, "TLS ERROR: write tls_write_ciphertext error");
return -1;
}
@@ -1021,6 +993,7 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,
{
int retval = 0;
int len = 0;
+ char error_message[1024];
perf_push (PERF_BIO_READ_PLAINTEXT);
@@ -1045,8 +1018,8 @@ key_state_read_plaintext (struct key_state_ssl *ks, struct buffer *buf,
{
if (POLARSSL_ERR_NET_WANT_WRITE == retval || POLARSSL_ERR_NET_WANT_READ == retval)
return 0;
- polar_log_err (D_TLS_ERRORS, retval,
- "TLS_ERROR: read tls_read_plaintext error");
+ error_strerror(retval, error_message, sizeof(error_message));
+ msg (D_TLS_ERRORS, "TLS_ERROR: read tls_read_plaintext error: %d %s", retval, error_message);
buf->len = 0;
perf_pop ();
return -1;
diff --git a/main/openvpn/src/openvpn/ssl_verify_polarssl.c b/main/openvpn/src/openvpn/ssl_verify_polarssl.c
index ed0297b3..2b7c214f 100644
--- a/main/openvpn/src/openvpn/ssl_verify_polarssl.c
+++ b/main/openvpn/src/openvpn/ssl_verify_polarssl.c
@@ -131,12 +131,17 @@ backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc)
char *buf = NULL;
size_t buflen = 0;
mpi serial_mpi = { 0 };
+ int retval = 0;
/* Transform asn1 integer serial into PolarSSL MPI */
mpi_init(&serial_mpi);
- if (!polar_ok(mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len)))
+ retval = mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len);
+ if (retval < 0)
{
- msg(M_WARN, "Failed to retrieve serial from certificate.");
+ char errbuf[128];
+ polarssl_strerror(retval, errbuf, sizeof(errbuf));
+
+ msg(M_WARN, "Failed to retrieve serial from certificate: %s.", errbuf);
return NULL;
}
@@ -145,9 +150,13 @@ backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc)
buf = gc_malloc(buflen, true, gc);
/* Write MPI serial as decimal string into buffer */
- if (!polar_ok(mpi_write_string(&serial_mpi, 10, buf, &buflen)))
+ retval = mpi_write_string(&serial_mpi, 10, buf, &buflen);
+ if (retval < 0)
{
- msg(M_WARN, "Failed to write serial to string.");
+ char errbuf[128];
+ polarssl_strerror(retval, errbuf, sizeof(errbuf));
+
+ msg(M_WARN, "Failed to write serial to string: %s.", errbuf);
return NULL;
}
@@ -362,9 +371,12 @@ x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject)
result_t retval = FAILURE;
x509_crl crl = {0};
- if (!polar_ok(x509_crl_parse_file(&crl, crl_file)))
+ int polar_retval = x509_crl_parse_file(&crl, crl_file);
+ if (polar_retval != 0)
{
- msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file);
+ char errstr[128];
+ polarssl_strerror(polar_retval, errstr, sizeof(errstr));
+ msg (M_WARN, "CRL: cannot read CRL from file %s (%s)", crl_file, errstr);
goto end;
}
@@ -377,7 +389,7 @@ x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject)
goto end;
}
- if (!polar_ok(x509_crt_revoked(cert, &crl)))
+ if (0 != x509_crt_revoked(cert, &crl))
{
msg (D_HANDSHAKE, "CRL CHECK FAILED: %s is REVOKED", subject);
goto end;