diff options
author | Arne Schwabe <arne@rfc2549.org> | 2014-10-29 15:33:32 +0100 |
---|---|---|
committer | Arne Schwabe <arne@rfc2549.org> | 2014-10-29 15:33:32 +0100 |
commit | 7372f1921da478938490adc184e159d098f59025 (patch) | |
tree | ebbb081da27db9a53c6efe376b3d2874affb409b /main/openvpn/src | |
parent | 464f50029ef03e1a81d5878d95f333bca7439291 (diff) |
Update session-id patch, fix accidentally committed experimental branch
Diffstat (limited to 'main/openvpn/src')
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; |