aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/plugins/eap_tls/tls/tls_protection.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/eap_tls/tls/tls_protection.c')
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_protection.c311
1 files changed, 0 insertions, 311 deletions
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_protection.c b/src/libcharon/plugins/eap_tls/tls/tls_protection.c
deleted file mode 100644
index 75fae0a71..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_protection.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- */
-
-#include "tls_protection.h"
-
-#include <daemon.h>
-
-typedef struct private_tls_protection_t private_tls_protection_t;
-
-/**
- * Private data of an tls_protection_t object.
- */
-struct private_tls_protection_t {
-
- /**
- * Public tls_protection_t interface.
- */
- tls_protection_t public;
-
- /**
- * TLS context
- */
- tls_t *tls;
-
- /**
- * Upper layer, TLS record compression
- */
- tls_compression_t *compression;
-
- /**
- * RNG if we generate IVs ourself
- */
- rng_t *rng;
-
- /**
- * Sequence number of incoming records
- */
- u_int32_t seq_in;
-
- /**
- * Sequence number for outgoing records
- */
- u_int32_t seq_out;
-
- /**
- * Signer instance for inbound traffic
- */
- signer_t *signer_in;
-
- /**
- * Signer instance for outbound traffic
- */
- signer_t *signer_out;
-
- /**
- * Crypter instance for inbound traffic
- */
- crypter_t *crypter_in;
-
- /**
- * Crypter instance for outbound traffic
- */
- crypter_t *crypter_out;
-
- /**
- * Current IV for input decryption
- */
- chunk_t iv_in;
-
- /**
- * Current IV for output decryption
- */
- chunk_t iv_out;
-};
-
-/**
- * Create the header to append to the record data to create the MAC
- */
-static chunk_t sigheader(u_int32_t seq, u_int8_t type,
- u_int16_t version, u_int16_t length)
-{
- /* we only support 32 bit sequence numbers, but TLS uses 64 bit */
- u_int32_t seq_high = 0;
-
- seq = htonl(seq);
- version = htons(version);
- length = htons(length);
-
- return chunk_cat("ccccc", chunk_from_thing(seq_high),
- chunk_from_thing(seq), chunk_from_thing(type),
- chunk_from_thing(version), chunk_from_thing(length));
-}
-
-METHOD(tls_protection_t, process, status_t,
- private_tls_protection_t *this, tls_content_type_t type, chunk_t data)
-{
- if (this->crypter_in)
- {
- chunk_t iv, next_iv = chunk_empty;
- u_int8_t bs, padding_length;
-
- bs = this->crypter_in->get_block_size(this->crypter_in);
- if (data.len < bs || data.len % bs)
- {
- DBG1(DBG_IKE, "encrypted TLS record not multiple of block size");
- return FAILED;
- }
- if (this->iv_in.len)
- { /* < TLSv1.1 uses IV from key derivation/last block */
- iv = this->iv_in;
- next_iv = chunk_clone(chunk_create(data.ptr + data.len - bs, bs));
- }
- else
- { /* TLSv1.1 uses random IVs, prepended to record */
- iv = chunk_create(data.ptr, bs);
- data = chunk_skip(data, bs);
- if (data.len < bs)
- {
- DBG1(DBG_IKE, "TLS record too short to decrypt");
- return FAILED;
- }
- }
- this->crypter_in->decrypt(this->crypter_in, data, iv, NULL);
-
- if (next_iv.len)
- { /* next record IV is last ciphertext block of this record */
- memcpy(this->iv_in.ptr, next_iv.ptr, next_iv.len);
- free(next_iv.ptr);
- }
-
- padding_length = data.ptr[data.len - 1];
- if (padding_length >= data.len)
- {
- DBG1(DBG_IKE, "invalid TLS record padding");
- return FAILED;
- }
- data.len -= padding_length + 1;
- }
- if (this->signer_in)
- {
- chunk_t mac, macdata, header;
- u_int8_t bs;
-
- bs = this->signer_in->get_block_size(this->signer_in);
- if (data.len <= bs)
- {
- DBG1(DBG_IKE, "TLS record too short to verify MAC");
- return FAILED;
- }
- mac = chunk_skip(data, data.len - bs);
- data.len -= bs;
-
- header = sigheader(this->seq_in, type,
- this->tls->get_version(this->tls), data.len);
- macdata = chunk_cat("mc", header, data);
- if (!this->signer_in->verify_signature(this->signer_in, macdata, mac))
- {
- DBG1(DBG_IKE, "TLS record MAC verification failed");
- free(macdata.ptr);
- return FAILED;
- }
- free(macdata.ptr);
- }
-
- if (type == TLS_CHANGE_CIPHER_SPEC)
- {
- this->seq_in = 0;
- }
- else
- {
- this->seq_in++;
- }
- return this->compression->process(this->compression, type, data);
-}
-
-METHOD(tls_protection_t, build, status_t,
- private_tls_protection_t *this, tls_content_type_t *type, chunk_t *data)
-{
- status_t status;
-
- status = this->compression->build(this->compression, type, data);
- if (*type == TLS_CHANGE_CIPHER_SPEC)
- {
- this->seq_out = 0;
- return status;
- }
-
- if (status == NEED_MORE)
- {
- if (this->signer_out)
- {
- chunk_t mac, header;
-
- header = sigheader(this->seq_out, *type,
- this->tls->get_version(this->tls), data->len);
- this->signer_out->get_signature(this->signer_out, header, NULL);
- free(header.ptr);
- this->signer_out->allocate_signature(this->signer_out, *data, &mac);
- if (this->crypter_out)
- {
- chunk_t padding, iv;
- u_int8_t bs, padding_length;
-
- bs = this->crypter_out->get_block_size(this->crypter_out);
- padding_length = bs - ((data->len + mac.len + 1) % bs);
-
- padding = chunk_alloca(padding_length);
- memset(padding.ptr, padding_length, padding.len);
-
- if (this->iv_out.len)
- { /* < TLSv1.1 uses IV from key derivation/last block */
- iv = this->iv_out;
- }
- else
- { /* TLSv1.1 uses random IVs, prepended to record */
- if (!this->rng)
- {
- DBG1(DBG_IKE, "no RNG supported to generate TLS IV");
- free(data->ptr);
- return FAILED;
- }
- this->rng->allocate_bytes(this->rng, bs, &iv);
- }
-
- *data = chunk_cat("mmcc", *data, mac, padding,
- chunk_from_thing(padding_length));
- /* encrypt inline */
- this->crypter_out->encrypt(this->crypter_out, *data, iv, NULL);
-
- if (this->iv_out.len)
- { /* next record IV is last ciphertext block of this record */
- memcpy(this->iv_out.ptr, data->ptr - this->iv_out.len,
- this->iv_out.len);
- }
- else
- { /* prepend IV */
- *data = chunk_cat("mm", iv, *data);
- }
- }
- else
- { /* NULL encryption */
- *data = chunk_cat("mm", *data, mac);
- }
- }
- }
- this->seq_out++;
- return status;
-}
-
-METHOD(tls_protection_t, set_cipher, void,
- private_tls_protection_t *this, bool inbound, signer_t *signer,
- crypter_t *crypter, chunk_t iv)
-{
- if (inbound)
- {
- this->signer_in = signer;
- this->crypter_in = crypter;
- this->iv_in = iv;
- }
- else
- {
- this->signer_out = signer;
- this->crypter_out = crypter;
- this->iv_out = iv;
- if (!iv.len)
- { /* generate IVs if none given */
- this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- }
- }
-}
-
-METHOD(tls_protection_t, destroy, void,
- private_tls_protection_t *this)
-{
- DESTROY_IF(this->rng);
- free(this);
-}
-
-/**
- * See header
- */
-tls_protection_t *tls_protection_create(tls_t *tls,
- tls_compression_t *compression)
-{
- private_tls_protection_t *this;
-
- INIT(this,
- .public = {
- .process = _process,
- .build = _build,
- .set_cipher = _set_cipher,
- .destroy = _destroy,
- },
- .tls = tls,
- .compression = compression,
- );
-
- return &this->public;
-}