aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/plugins/eap_tls/tls
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-08-03 15:17:40 +0200
committerMartin Willi <martin@revosec.ch>2010-08-03 15:39:26 +0200
commit0f82a47063f05d8eeae64866ff4787edc8db6328 (patch)
tree80d2e1fc7d530dc205314b7abafeb25fec48cc73 /src/libcharon/plugins/eap_tls/tls
parent0b71bc7af047f1a20bbad8a38d33b01452c35613 (diff)
downloadstrongswan-0f82a47063f05d8eeae64866ff4787edc8db6328.tar.bz2
strongswan-0f82a47063f05d8eeae64866ff4787edc8db6328.tar.xz
Moved TLS stack to its own library
Diffstat (limited to 'src/libcharon/plugins/eap_tls/tls')
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls.c215
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls.h168
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_compression.c73
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_compression.h77
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_crypto.c691
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_crypto.h188
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_fragmentation.c256
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_fragmentation.h77
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_handshake.h82
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_peer.c625
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_peer.h48
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_prf.c190
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_prf.h72
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_protection.c311
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_protection.h90
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_reader.c200
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_reader.h131
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_server.c607
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_server.h48
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_writer.c237
-rw-r--r--src/libcharon/plugins/eap_tls/tls/tls_writer.h136
21 files changed, 0 insertions, 4522 deletions
diff --git a/src/libcharon/plugins/eap_tls/tls/tls.c b/src/libcharon/plugins/eap_tls/tls/tls.c
deleted file mode 100644
index ab03037fa..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls.c
+++ /dev/null
@@ -1,215 +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.h"
-
-#include "tls_protection.h"
-#include "tls_compression.h"
-#include "tls_fragmentation.h"
-#include "tls_crypto.h"
-#include "tls_server.h"
-#include "tls_peer.h"
-
-#include <daemon.h>
-
-ENUM_BEGIN(tls_version_names, SSL_2_0, SSL_2_0,
- "SSLv2");
-ENUM_NEXT(tls_version_names, SSL_3_0, TLS_1_2, SSL_2_0,
- "SSLv3",
- "TLS 1.0",
- "TLS 1.1",
- "TLS 1.2");
-ENUM_END(tls_version_names, TLS_1_2);
-
-ENUM(tls_content_type_names, TLS_CHANGE_CIPHER_SPEC, TLS_APPLICATION_DATA,
- "ChangeCipherSpec",
- "Alert",
- "Handshake",
- "ApplicationData",
-);
-
-ENUM_BEGIN(tls_handshake_type_names, TLS_HELLO_REQUEST, TLS_SERVER_HELLO,
- "HelloRequest",
- "ClientHello",
- "ServerHello");
-ENUM_NEXT(tls_handshake_type_names, TLS_CERTIFICATE, TLS_CLIENT_KEY_EXCHANGE, TLS_SERVER_HELLO,
- "Certificate",
- "ServerKeyExchange",
- "CertificateRequest",
- "ServerHelloDone",
- "CertificateVerify",
- "ClientKeyExchange");
-ENUM_NEXT(tls_handshake_type_names, TLS_FINISHED, TLS_FINISHED, TLS_CLIENT_KEY_EXCHANGE,
- "Finished");
-ENUM_END(tls_handshake_type_names, TLS_FINISHED);
-
-
-typedef struct private_tls_t private_tls_t;
-
-/**
- * Private data of an tls_protection_t object.
- */
-struct private_tls_t {
-
- /**
- * Public tls_t interface.
- */
- tls_t public;
-
- /**
- * Role this TLS stack acts as.
- */
- bool is_server;
-
- /**
- * Server identity
- */
- identification_t *server;
-
- /**
- * Peer identity
- */
- identification_t *peer;
-
- /**
- * Negotiated TLS version
- */
- tls_version_t version;
-
- /**
- * TLS record protection layer
- */
- tls_protection_t *protection;
-
- /**
- * TLS record compression layer
- */
- tls_compression_t *compression;
-
- /**
- * TLS record fragmentation layer
- */
- tls_fragmentation_t *fragmentation;
-
- /**
- * TLS crypto helper context
- */
- tls_crypto_t *crypto;
-
- /**
- * TLS handshake protocol handler
- */
- tls_handshake_t *handshake;
-};
-
-METHOD(tls_t, process, status_t,
- private_tls_t *this, tls_content_type_t type, chunk_t data)
-{
- return this->protection->process(this->protection, type, data);
-}
-
-METHOD(tls_t, build, status_t,
- private_tls_t *this, tls_content_type_t *type, chunk_t *data)
-{
- return this->protection->build(this->protection, type, data);
-}
-
-METHOD(tls_t, is_server, bool,
- private_tls_t *this)
-{
- return this->is_server;
-}
-
-METHOD(tls_t, get_version, tls_version_t,
- private_tls_t *this)
-{
- return this->version;
-}
-
-METHOD(tls_t, set_version, void,
- private_tls_t *this, tls_version_t version)
-{
- this->version = version;
-}
-
-METHOD(tls_t, is_complete, bool,
- private_tls_t *this)
-{
- return this->crypto->get_eap_msk(this->crypto).len != 0;
-}
-
-METHOD(tls_t, get_eap_msk, chunk_t,
- private_tls_t *this)
-{
- return this->crypto->get_eap_msk(this->crypto);
-}
-
-METHOD(tls_t, destroy, void,
- private_tls_t *this)
-{
- this->protection->destroy(this->protection);
- this->compression->destroy(this->compression);
- this->fragmentation->destroy(this->fragmentation);
- this->crypto->destroy(this->crypto);
- this->handshake->destroy(this->handshake);
- this->peer->destroy(this->peer);
- this->server->destroy(this->server);
-
- free(this);
-}
-
-/**
- * See header
- */
-tls_t *tls_create(bool is_server, identification_t *server,
- identification_t *peer)
-{
- private_tls_t *this;
-
- INIT(this,
- .public = {
- .process = _process,
- .build = _build,
- .is_server = _is_server,
- .get_version = _get_version,
- .set_version = _set_version,
- .is_complete = _is_complete,
- .get_eap_msk = _get_eap_msk,
- .destroy = _destroy,
- },
- .is_server = is_server,
- .version = TLS_1_2,
- .server = server->clone(server),
- .peer = peer->clone(peer),
- );
-
- this->crypto = tls_crypto_create(&this->public);
- if (is_server)
- {
- this->handshake = &tls_server_create(&this->public, this->crypto,
- this->server, this->peer)->handshake;
- }
- else
- {
- this->handshake = &tls_peer_create(&this->public, this->crypto,
- this->peer, this->server)->handshake;
- }
- this->fragmentation = tls_fragmentation_create(this->handshake);
- this->compression = tls_compression_create(this->fragmentation);
- this->protection = tls_protection_create(&this->public, this->compression);
- this->crypto->set_protection(this->crypto, this->protection);
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_tls/tls/tls.h b/src/libcharon/plugins/eap_tls/tls/tls.h
deleted file mode 100644
index 283f591e7..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls.h
+++ /dev/null
@@ -1,168 +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.
- */
-
-/**
- * @defgroup tlsgroup tls
- * @{ @ingroup eap_tls
- *
- * @defgroup tls tls
- * @{ @ingroup tls
- */
-
-#ifndef TLS_H_
-#define TLS_H_
-
-typedef enum tls_version_t tls_version_t;
-typedef enum tls_content_type_t tls_content_type_t;
-typedef enum tls_handshake_type_t tls_handshake_type_t;
-typedef struct tls_t tls_t;
-
-#include <library.h>
-
-/**
- * TLS/SSL version numbers
- */
-enum tls_version_t {
- SSL_2_0 = 0x0200,
- SSL_3_0 = 0x0300,
- TLS_1_0 = 0x0301,
- TLS_1_1 = 0x0302,
- TLS_1_2 = 0x0303,
-};
-
-/**
- * Enum names for tls_version_t
- */
-extern enum_name_t *tls_version_names;
-
-/**
- * TLS higher level content type
- */
-enum tls_content_type_t {
- TLS_CHANGE_CIPHER_SPEC = 20,
- TLS_ALERT = 21,
- TLS_HANDSHAKE = 22,
- TLS_APPLICATION_DATA = 23,
-};
-
-/**
- * Enum names for tls_content_type_t
- */
-extern enum_name_t *tls_content_type_names;
-
-/**
- * TLS handshake subtype
- */
-enum tls_handshake_type_t {
- TLS_HELLO_REQUEST = 0,
- TLS_CLIENT_HELLO = 1,
- TLS_SERVER_HELLO = 2,
- TLS_CERTIFICATE = 11,
- TLS_SERVER_KEY_EXCHANGE = 12,
- TLS_CERTIFICATE_REQUEST = 13,
- TLS_SERVER_HELLO_DONE = 14,
- TLS_CERTIFICATE_VERIFY = 15,
- TLS_CLIENT_KEY_EXCHANGE = 16,
- TLS_FINISHED = 20,
-};
-
-/**
- * Enum names for tls_handshake_type_t
- */
-extern enum_name_t *tls_handshake_type_names;
-
-/**
- * A bottom-up driven TLS stack, suitable for EAP implementations.
- */
-struct tls_t {
-
- /**
- * Process a TLS record, pass it to upper layers.
- *
- * @param type type of the TLS record to process
- * @param data associated TLS record data
- * @return
- * - SUCCESS if TLS negotiation complete
- * - FAILED if TLS handshake failed
- * - NEED_MORE if more invocations to process/build needed
- */
- status_t (*process)(tls_t *this, tls_content_type_t type, chunk_t data);
-
- /**
- * Query upper layer for TLS record, build protected record.
- *
- * @param type type of the built TLS record
- * @param data allocated data of the built TLS record
- * @return
- * - SUCCESS if TLS negotiation complete
- * - FAILED if TLS handshake failed
- * - NEED_MORE if upper layers have more records to send
- * - INVALID_STATE if more input records required
- */
- status_t (*build)(tls_t *this, tls_content_type_t *type, chunk_t *data);
-
- /**
- * Check if TLS stack is acting as a server.
- *
- * @return TRUE if server, FALSE if peer
- */
- bool (*is_server)(tls_t *this);
-
- /**
- * Get the negotiated TLS/SSL version.
- *
- * @return negotiated TLS version
- */
- tls_version_t (*get_version)(tls_t *this);
-
- /**
- * Set the negotiated TLS/SSL version.
- *
- * @param version negotiated TLS version
- */
- void (*set_version)(tls_t *this, tls_version_t version);
-
- /**
- * Check if TLS negotiation completed successfully.
- *
- * @return TRUE if TLS negotation and authentication complete
- */
- bool (*is_complete)(tls_t *this);
-
- /**
- * Get the MSK for EAP-TLS.
- *
- * @return MSK, internal data
- */
- chunk_t (*get_eap_msk)(tls_t *this);
-
- /**
- * Destroy a tls_t.
- */
- void (*destroy)(tls_t *this);
-};
-
-/**
- * Create a tls instance.
- *
- * @param is_server TRUE to act as server, FALSE for client
- * @param server server identity
- * @param peer peer identity
- * @return TLS stack
- */
-tls_t *tls_create(bool is_server, identification_t *server,
- identification_t *peer);
-
-#endif /** TLS_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_compression.c b/src/libcharon/plugins/eap_tls/tls/tls_compression.c
deleted file mode 100644
index 453558084..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_compression.c
+++ /dev/null
@@ -1,73 +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_compression.h"
-
-#include <daemon.h>
-
-typedef struct private_tls_compression_t private_tls_compression_t;
-
-/**
- * Private data of an tls_compression_t object.
- */
-struct private_tls_compression_t {
-
- /**
- * Public tls_compression_t interface.
- */
- tls_compression_t public;
-
- /**
- * Upper layer, TLS record fragmentation
- */
- tls_fragmentation_t *fragmentation;
-};
-
-METHOD(tls_compression_t, process, status_t,
- private_tls_compression_t *this, tls_content_type_t type, chunk_t data)
-{
- return this->fragmentation->process(this->fragmentation, type, data);
-}
-
-METHOD(tls_compression_t, build, status_t,
- private_tls_compression_t *this, tls_content_type_t *type, chunk_t *data)
-{
- return this->fragmentation->build(this->fragmentation, type, data);
-}
-
-METHOD(tls_compression_t, destroy, void,
- private_tls_compression_t *this)
-{
- free(this);
-}
-
-/**
- * See header
- */
-tls_compression_t *tls_compression_create(tls_fragmentation_t *fragmentation)
-{
- private_tls_compression_t *this;
-
- INIT(this,
- .public = {
- .process = _process,
- .build = _build,
- .destroy = _destroy,
- },
- .fragmentation = fragmentation,
- );
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_compression.h b/src/libcharon/plugins/eap_tls/tls/tls_compression.h
deleted file mode 100644
index a61543004..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_compression.h
+++ /dev/null
@@ -1,77 +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.
- */
-
-/**
- * @defgroup tls_compression tls_compression
- * @{ @ingroup tls
- */
-
-#ifndef TLS_COMPRESSION_H_
-#define TLS_COMPRESSION_H_
-
-typedef struct tls_compression_t tls_compression_t;
-
-#include <library.h>
-
-#include "tls.h"
-#include "tls_fragmentation.h"
-
-/**
- * TLS record protocol compression layer.
- */
-struct tls_compression_t {
-
- /**
- * Process a compressed TLS record, pass it to upper layers.
- *
- * @param type type of the TLS record to process
- * @param data associated TLS record data
- * @return
- * - SUCCESS if TLS negotiation complete
- * - FAILED if TLS handshake failed
- * - NEED_MORE if more invocations to process/build needed
- */
- status_t (*process)(tls_compression_t *this,
- tls_content_type_t type, chunk_t data);
-
- /**
- * Query upper layer for TLS record, build compressed record.
- *
- * @param type type of the built TLS record
- * @param data allocated data of the built TLS record
- * @return
- * - SUCCESS if TLS negotiation complete
- * - FAILED if TLS handshake failed
- * - NEED_MORE if upper layers have more records to send
- * - INVALID_STATE if more input records required
- */
- status_t (*build)(tls_compression_t *this,
- tls_content_type_t *type, chunk_t *data);
-
- /**
- * Destroy a tls_compression_t.
- */
- void (*destroy)(tls_compression_t *this);
-};
-
-/**
- * Create a tls_compression instance.
- *
- * @param fragmentation fragmentation layer of TLS stack
- * @return TLS compression layer.
- */
-tls_compression_t *tls_compression_create(tls_fragmentation_t *fragmentation);
-
-#endif /** TLS_COMPRESSION_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_crypto.c b/src/libcharon/plugins/eap_tls/tls/tls_crypto.c
deleted file mode 100644
index f8894629f..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_crypto.c
+++ /dev/null
@@ -1,691 +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_crypto.h"
-
-#include <daemon.h>
-
-typedef struct private_tls_crypto_t private_tls_crypto_t;
-
-/**
- * Private data of an tls_crypto_t object.
- */
-struct private_tls_crypto_t {
-
- /**
- * Public tls_crypto_t interface.
- */
- tls_crypto_t public;
-
- /**
- * Protection layer
- */
- tls_protection_t *protection;
-
- /**
- * List of supported/acceptable cipher suites
- */
- tls_cipher_suite_t *suites;
-
- /**
- * Number of supported suites
- */
- int suite_count;
-
- /**
- * Selected cipher suite
- */
- tls_cipher_suite_t suite;
-
- /**
- * TLS context
- */
- tls_t *tls;
-
- /**
- * All handshake data concatentated
- */
- chunk_t handshake;
-
- /**
- * Connection state TLS PRF
- */
- tls_prf_t *prf;
-
- /**
- * 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;
-
- /**
- * IV for input decryption, if < TLSv1.2
- */
- chunk_t iv_in;
-
- /**
- * IV for output decryption, if < TLSv1.2
- */
- chunk_t iv_out;
-
- /**
- * EAP-TLS MSK
- */
- chunk_t msk;
-};
-
-typedef struct {
- tls_cipher_suite_t suite;
- hash_algorithm_t hash;
- pseudo_random_function_t prf;
- integrity_algorithm_t mac;
- encryption_algorithm_t encr;
- size_t encr_size;
-} suite_algs_t;
-
-/**
- * Mapping suites to a set of algorithms
- */
-static suite_algs_t suite_algs[] = {
- { TLS_RSA_WITH_NULL_MD5,
- HASH_MD5,
- PRF_HMAC_MD5,
- AUTH_HMAC_MD5_128,
- ENCR_NULL, 0
- },
- { TLS_RSA_WITH_NULL_SHA,
- HASH_SHA1,
- PRF_HMAC_SHA1,
- AUTH_HMAC_SHA1_160,
- ENCR_NULL, 0
- },
- { TLS_RSA_WITH_NULL_SHA256,
- HASH_SHA256,
- PRF_HMAC_SHA2_256,
- AUTH_HMAC_SHA2_256_256,
- ENCR_NULL, 0
- },
- { TLS_RSA_WITH_AES_128_CBC_SHA,
- HASH_SHA1,
- PRF_HMAC_SHA1,
- AUTH_HMAC_SHA1_160,
- ENCR_AES_CBC, 16
- },
- { TLS_RSA_WITH_AES_256_CBC_SHA,
- HASH_SHA1,
- PRF_HMAC_SHA1,
- AUTH_HMAC_SHA1_160,
- ENCR_AES_CBC, 32
- },
- { TLS_RSA_WITH_3DES_EDE_CBC_SHA,
- HASH_SHA1,
- PRF_HMAC_SHA1,
- AUTH_HMAC_SHA1_160,
- ENCR_3DES, 0
- },
- { TLS_RSA_WITH_AES_128_CBC_SHA256,
- HASH_SHA256,
- PRF_HMAC_SHA2_256,
- AUTH_HMAC_SHA2_256_256,
- ENCR_AES_CBC, 16
- },
-};
-
-/**
- * Look up algoritms by a suite
- */
-static suite_algs_t *find_suite(tls_cipher_suite_t suite)
-{
- int i;
-
- for (i = 0; i < countof(suite_algs); i++)
- {
- if (suite_algs[i].suite == suite)
- {
- return &suite_algs[i];
- }
- }
- return NULL;
-}
-
-/**
- * Initialize the cipher suite list
- */
-static void build_cipher_suite_list(private_tls_crypto_t *this)
-{
- encryption_algorithm_t encr;
- integrity_algorithm_t mac;
- enumerator_t *encrs, *macs;
- tls_cipher_suite_t supported[64], unique[64];
- int count = 0, i, j;
-
- /* we assume that we support RSA, but no DHE yet */
- macs = lib->crypto->create_signer_enumerator(lib->crypto);
- while (macs->enumerate(macs, &mac))
- {
- switch (mac)
- {
- case AUTH_HMAC_SHA1_160:
- supported[count++] = TLS_RSA_WITH_NULL_SHA;
- break;
- case AUTH_HMAC_SHA2_256_256:
- supported[count++] = TLS_RSA_WITH_NULL_SHA256;
- break;
- case AUTH_HMAC_MD5_128:
- supported[count++] = TLS_RSA_WITH_NULL_MD5;
- break;
- default:
- break;
- }
- encrs = lib->crypto->create_crypter_enumerator(lib->crypto);
- while (encrs->enumerate(encrs, &encr))
- {
- switch (encr)
- {
- case ENCR_AES_CBC:
- switch (mac)
- {
- case AUTH_HMAC_SHA1_160:
- supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
- supported[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
- break;
- case AUTH_HMAC_SHA2_256_256:
- supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
- supported[count++] = TLS_RSA_WITH_AES_128_CBC_SHA256;
- break;
- default:
- break;
- }
- break;
- case ENCR_3DES:
- switch (mac)
- {
- case AUTH_HMAC_SHA1_160:
- supported[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
- break;
- default:
- break;
- }
- break;
- default:
- break;
- }
- }
- encrs->destroy(encrs);
- }
- macs->destroy(macs);
-
- /* remove duplicates */
- this->suite_count = 0;
- for (i = 0; i < count; i++)
- {
- bool match = FALSE;
-
- for (j = 0; j < this->suite_count; j++)
- {
- if (supported[i] == unique[j])
- {
- match = TRUE;
- break;
- }
- }
- if (!match)
- {
- unique[this->suite_count++] = supported[i];
- }
- }
- free(this->suites);
- this->suites = malloc(sizeof(tls_cipher_suite_t) * this->suite_count);
- memcpy(this->suites, unique, sizeof(tls_cipher_suite_t) * this->suite_count);
-}
-
-METHOD(tls_crypto_t, get_cipher_suites, int,
- private_tls_crypto_t *this, tls_cipher_suite_t **suites)
-{
- *suites = this->suites;
- return this->suite_count;
-}
-
-/**
- * Create crypto primitives
- */
-static bool create_ciphers(private_tls_crypto_t *this, tls_cipher_suite_t suite)
-{
- suite_algs_t *algs;
-
- algs = find_suite(suite);
- if (!algs)
- {
- DBG1(DBG_IKE, "selected TLS suite not supported");
- return FALSE;
- }
-
- DESTROY_IF(this->prf);
- if (this->tls->get_version(this->tls) < TLS_1_2)
- {
- this->prf = tls_prf_create_10();
- }
- else
- {
- this->prf = tls_prf_create_12(algs->prf);
- }
- if (!this->prf)
- {
- DBG1(DBG_IKE, "selected TLS PRF not supported");
- return FALSE;
- }
-
- DESTROY_IF(this->signer_in);
- DESTROY_IF(this->signer_out);
- this->signer_in = lib->crypto->create_signer(lib->crypto, algs->mac);
- this->signer_out = lib->crypto->create_signer(lib->crypto, algs->mac);
- if (!this->signer_in || !this->signer_out)
- {
- DBG1(DBG_IKE, "selected TLS MAC %N not supported",
- integrity_algorithm_names, algs->mac);
- return FALSE;
- }
-
- DESTROY_IF(this->crypter_in);
- DESTROY_IF(this->crypter_out);
- if (algs->encr == ENCR_NULL)
- {
- this->crypter_in = this->crypter_out = NULL;
- }
- else
- {
- this->crypter_in = lib->crypto->create_crypter(lib->crypto,
- algs->encr, algs->encr_size);
- this->crypter_out = lib->crypto->create_crypter(lib->crypto,
- algs->encr, algs->encr_size);
- if (!this->crypter_in || !this->crypter_out)
- {
- DBG1(DBG_IKE, "selected TLS crypter %N not supported",
- encryption_algorithm_names, algs->encr);
- return FALSE;
- }
- }
- return TRUE;
-}
-
-METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t,
- private_tls_crypto_t *this, tls_cipher_suite_t *suites, int count)
-{
- int i, j;
-
- for (i = 0; i < this->suite_count; i++)
- {
- for (j = 0; j < count; j++)
- {
- if (this->suites[i] == suites[j])
- {
- if (create_ciphers(this, this->suites[i]))
- {
- this->suite = this->suites[i];
- return this->suite;
- }
- }
- }
- }
- return 0;
-}
-
-METHOD(tls_crypto_t, set_protection, void,
- private_tls_crypto_t *this, tls_protection_t *protection)
-{
- this->protection = protection;
-}
-
-METHOD(tls_crypto_t, append_handshake, void,
- private_tls_crypto_t *this, tls_handshake_type_t type, chunk_t data)
-{
- u_int32_t header;
-
- /* reconstruct handshake header */
- header = htonl(data.len | (type << 24));
- this->handshake = chunk_cat("mcc", this->handshake,
- chunk_from_thing(header), data);
-}
-
-/**
- * Create a hash of the stored handshake data
- */
-static bool hash_handshake(private_tls_crypto_t *this, chunk_t *hash)
-{
- if (this->tls->get_version(this->tls) >= TLS_1_2)
- {
- hasher_t *hasher;
- suite_algs_t *alg;
-
- alg = find_suite(this->suite);
- if (!alg)
- {
- return FALSE;
- }
- hasher = lib->crypto->create_hasher(lib->crypto, alg->hash);
- if (!hasher)
- {
- DBG1(DBG_IKE, "%N not supported", hash_algorithm_names, alg->hash);
- return FALSE;
- }
- hasher->allocate_hash(hasher, this->handshake, hash);
- hasher->destroy(hasher);
- }
- else
- {
- hasher_t *md5, *sha1;
- char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1];
-
- md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
- if (!md5)
- {
- DBG1(DBG_IKE, "%N not supported", hash_algorithm_names, HASH_MD5);
- return FALSE;
- }
- md5->get_hash(md5, this->handshake, buf);
- md5->destroy(md5);
- sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
- if (!sha1)
- {
- DBG1(DBG_IKE, "%N not supported", hash_algorithm_names, HASH_SHA1);
- return FALSE;
- }
- sha1->get_hash(sha1, this->handshake, buf + HASH_SIZE_MD5);
- sha1->destroy(sha1);
-
- *hash = chunk_clone(chunk_from_thing(buf));
- }
- return TRUE;
-}
-
-METHOD(tls_crypto_t, sign_handshake, bool,
- private_tls_crypto_t *this, private_key_t *key, tls_writer_t *writer)
-{
- chunk_t sig, hash;
-
- if (this->tls->get_version(this->tls) >= TLS_1_2)
- {
- /* TODO: use supported algorithms instead of fixed SHA1/RSA */
- if (!key->sign(key, SIGN_RSA_EMSA_PKCS1_SHA1, this->handshake, &sig))
- {
- return FALSE;
- }
- writer->write_uint8(writer, 2);
- writer->write_uint8(writer, 1);
- writer->write_data16(writer, sig);
- free(sig.ptr);
- }
- else
- {
- if (!hash_handshake(this, &hash))
- {
- return FALSE;
- }
- if (!key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, &sig))
- {
- free(hash.ptr);
- return FALSE;
- }
- writer->write_data16(writer, sig);
- free(hash.ptr);
- free(sig.ptr);
- }
- return TRUE;
-}
-
-METHOD(tls_crypto_t, verify_handshake, bool,
- private_tls_crypto_t *this, public_key_t *key, tls_reader_t *reader)
-{
- if (this->tls->get_version(this->tls) >= TLS_1_2)
- {
- u_int8_t hash, alg;
- chunk_t sig;
-
- if (!reader->read_uint8(reader, &hash) ||
- !reader->read_uint8(reader, &alg) ||
- !reader->read_data16(reader, &sig))
- {
- DBG1(DBG_IKE, "received invalid Certificate Verify");
- return FALSE;
- }
- /* TODO: map received hash/sig alg to signature scheme */
- if (hash != 2 || alg != 1 ||
- !key->verify(key, SIGN_RSA_EMSA_PKCS1_SHA1, this->handshake, sig))
- {
- return FALSE;
- }
- }
- else
- {
- chunk_t sig, hash;
-
- if (!reader->read_data16(reader, &sig))
- {
- DBG1(DBG_IKE, "received invalid Certificate Verify");
- return FALSE;
- }
- if (!hash_handshake(this, &hash))
- {
- return FALSE;
- }
- if (!key->verify(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, sig))
- {
- free(hash.ptr);
- return FALSE;
- }
- free(hash.ptr);
- }
- return TRUE;
-}
-
-METHOD(tls_crypto_t, calculate_finished, bool,
- private_tls_crypto_t *this, char *label, char out[12])
-{
- chunk_t seed;
-
- if (!this->prf)
- {
- return FALSE;
- }
- if (!hash_handshake(this, &seed))
- {
- return FALSE;
- }
- this->prf->get_bytes(this->prf, label, seed, 12, out);
- free(seed.ptr);
- return TRUE;
-}
-
-METHOD(tls_crypto_t, derive_secrets, void,
- private_tls_crypto_t *this, chunk_t premaster,
- chunk_t client_random, chunk_t server_random)
-{
- char master[48];
- chunk_t seed, block, client_write, server_write;
- int mks, eks = 0, ivs = 0;
-
- /* derive master secret */
- seed = chunk_cata("cc", client_random, server_random);
- this->prf->set_key(this->prf, premaster);
- this->prf->get_bytes(this->prf, "master secret", seed,
- sizeof(master), master);
-
- this->prf->set_key(this->prf, chunk_from_thing(master));
- memset(master, 0, sizeof(master));
-
- /* derive key block for key expansion */
- mks = this->signer_out->get_key_size(this->signer_out);
- if (this->crypter_out)
- {
- eks = this->crypter_out->get_key_size(this->crypter_out);
- if (this->tls->get_version(this->tls) < TLS_1_1)
- {
- ivs = this->crypter_out->get_block_size(this->crypter_out);
- }
- }
- seed = chunk_cata("cc", server_random, client_random);
- block = chunk_alloca((mks + eks + ivs) * 2);
- this->prf->get_bytes(this->prf, "key expansion", seed, block.len, block.ptr);
-
- /* signer keys */
- client_write = chunk_create(block.ptr, mks);
- block = chunk_skip(block, mks);
- server_write = chunk_create(block.ptr, mks);
- block = chunk_skip(block, mks);
- if (this->tls->is_server(this->tls))
- {
- this->signer_in->set_key(this->signer_in, client_write);
- this->signer_out->set_key(this->signer_out, server_write);
- }
- else
- {
- this->signer_out->set_key(this->signer_out, client_write);
- this->signer_in->set_key(this->signer_in, server_write);
- }
-
- /* crypter keys, and IVs if < TLSv1.2 */
- if (this->crypter_out && this->crypter_in)
- {
- client_write = chunk_create(block.ptr, eks);
- block = chunk_skip(block, eks);
- server_write = chunk_create(block.ptr, eks);
- block = chunk_skip(block, eks);
-
- if (this->tls->is_server(this->tls))
- {
- this->crypter_in->set_key(this->crypter_in, client_write);
- this->crypter_out->set_key(this->crypter_out, server_write);
- }
- else
- {
- this->crypter_out->set_key(this->crypter_out, client_write);
- this->crypter_in->set_key(this->crypter_in, server_write);
- }
- if (ivs)
- {
- client_write = chunk_create(block.ptr, ivs);
- block = chunk_skip(block, ivs);
- server_write = chunk_create(block.ptr, ivs);
- block = chunk_skip(block, ivs);
-
- if (this->tls->is_server(this->tls))
- {
- this->iv_in = chunk_clone(client_write);
- this->iv_out = chunk_clone(server_write);
- }
- else
- {
- this->iv_out = chunk_clone(client_write);
- this->iv_in = chunk_clone(server_write);
- }
- }
- }
-}
-
-METHOD(tls_crypto_t, change_cipher, void,
- private_tls_crypto_t *this, bool inbound)
-{
- if (this->protection)
- {
- if (inbound)
- {
- this->protection->set_cipher(this->protection, TRUE,
- this->signer_in, this->crypter_in, this->iv_in);
- }
- else
- {
- this->protection->set_cipher(this->protection, FALSE,
- this->signer_out, this->crypter_out, this->iv_out);
- }
- }
-}
-
-METHOD(tls_crypto_t, derive_eap_msk, void,
- private_tls_crypto_t *this, chunk_t client_random, chunk_t server_random)
-{
- chunk_t seed;
-
- seed = chunk_cata("cc", client_random, server_random);
- free(this->msk.ptr);
- this->msk = chunk_alloc(64);
- this->prf->get_bytes(this->prf, "client EAP encryption", seed,
- this->msk.len, this->msk.ptr);
-}
-
-METHOD(tls_crypto_t, get_eap_msk, chunk_t,
- private_tls_crypto_t *this)
-{
- return this->msk;
-}
-
-METHOD(tls_crypto_t, destroy, void,
- private_tls_crypto_t *this)
-{
- DESTROY_IF(this->signer_in);
- DESTROY_IF(this->signer_out);
- DESTROY_IF(this->crypter_in);
- DESTROY_IF(this->crypter_out);
- free(this->iv_in.ptr);
- free(this->iv_out.ptr);
- free(this->handshake.ptr);
- free(this->msk.ptr);
- DESTROY_IF(this->prf);
- free(this->suites);
- free(this);
-}
-
-/**
- * See header
- */
-tls_crypto_t *tls_crypto_create(tls_t *tls)
-{
- private_tls_crypto_t *this;
-
- INIT(this,
- .public = {
- .get_cipher_suites = _get_cipher_suites,
- .select_cipher_suite = _select_cipher_suite,
- .set_protection = _set_protection,
- .append_handshake = _append_handshake,
- .sign_handshake = _sign_handshake,
- .verify_handshake = _verify_handshake,
- .calculate_finished = _calculate_finished,
- .derive_secrets = _derive_secrets,
- .change_cipher = _change_cipher,
- .derive_eap_msk = _derive_eap_msk,
- .get_eap_msk = _get_eap_msk,
- .destroy = _destroy,
- },
- .tls = tls,
- );
-
- build_cipher_suite_list(this);
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_crypto.h b/src/libcharon/plugins/eap_tls/tls/tls_crypto.h
deleted file mode 100644
index 69b8da742..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_crypto.h
+++ /dev/null
@@ -1,188 +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.
- */
-
-/**
- * @defgroup tls_crypto tls_crypto
- * @{ @ingroup tls
- */
-
-#ifndef TLS_CRYPTO_H_
-#define TLS_CRYPTO_H_
-
-typedef struct tls_crypto_t tls_crypto_t;
-typedef enum tls_cipher_suite_t tls_cipher_suite_t;
-
-#include "tls.h"
-#include "tls_prf.h"
-#include "tls_protection.h"
-
-#include <credentials/keys/private_key.h>
-
-/**
- * TLS cipher suites
- */
-enum tls_cipher_suite_t {
- TLS_NULL_WITH_NULL_NULL = 0x00,
- TLS_RSA_WITH_NULL_MD5 = 0x01,
- TLS_RSA_WITH_NULL_SHA = 0x02,
- TLS_RSA_WITH_NULL_SHA256 = 0x3B,
- TLS_RSA_WITH_RC4_128_MD5 = 0x04,
- TLS_RSA_WITH_RC4_128_SHA = 0x05,
- TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x0A,
- TLS_RSA_WITH_AES_128_CBC_SHA = 0x2F,
- TLS_RSA_WITH_AES_256_CBC_SHA = 0x35,
- TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x3C,
- TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x3D,
- TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x0D,
- TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x10,
- TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x13,
- TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x16,
- TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x30,
- TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x31,
- TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x32,
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x33,
- TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x36,
- TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x37,
- TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x38,
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x39,
- TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = 0x3E,
- TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = 0x3F,
- TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x40,
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x67,
- TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = 0x68,
- TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = 0x69,
- TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x6A,
- TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x6B,
- TLS_DH_ANON_WITH_RC4_128_MD5 = 0x18,
- TLS_DH_ANON_WITH_3DES_EDE_CBC_SHA = 0x1B,
- TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x34,
- TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x3A,
- TLS_DH_ANON_WITH_AES_128_CBC_SHA256 = 0x6C,
- TLS_DH_ANON_WITH_AES_256_CBC_SHA256 = 0x6D,
-};
-
-/**
- * TLS crypto helper functions.
- */
-struct tls_crypto_t {
-
- /**
- * Get a list of supported TLS cipher suites.
- *
- * @param suites list of suites, points to internal data
- * @return number of suites returned
- */
- int (*get_cipher_suites)(tls_crypto_t *this, tls_cipher_suite_t **suites);
-
- /**
- * Select and store a cipher suite from a given list of candidates.
- *
- * @param suites list of candidates to select from
- * @param count number of suites
- * @return selected suite, 0 if none acceptable
- */
- tls_cipher_suite_t (*select_cipher_suite)(tls_crypto_t *this,
- tls_cipher_suite_t *suites, int count);
-
- /**
- * Set the protection layer of the TLS stack to control it.
- *
- * @param protection protection layer to work on
- */
- void (*set_protection)(tls_crypto_t *this, tls_protection_t *protection);
-
- /**
- * Store exchanged handshake data, used for cryptographic operations.
- *
- * @param type handshake sub type
- * @param data data to append to handshake buffer
- */
- void (*append_handshake)(tls_crypto_t *this,
- tls_handshake_type_t type, chunk_t data);
-
- /**
- * Create a signature of the handshake data using a given private key.
- *
- * @param key private key to use for signature
- * @param writer TLS writer to write signature to
- * @return TRUE if signature create successfully
- */
- bool (*sign_handshake)(tls_crypto_t *this, private_key_t *key,
- tls_writer_t *writer);
-
- /**
- * Verify the signature over handshake data using a given public key.
- *
- * @param key public key to verify signature with
- * @param reader TLS reader to read signature from
- * @return TRUE if signature valid
- */
- bool (*verify_handshake)(tls_crypto_t *this, public_key_t *key,
- tls_reader_t *reader);
-
- /**
- * Calculate the data of a TLS finished message.
- *
- * @param label ASCII label to use for calculation
- * @param out buffer to write finished data to
- * @return TRUE if calculation successful
- */
- bool (*calculate_finished)(tls_crypto_t *this, char *label, char out[12]);
-
- /**
- * Derive the master secret, MAC and encryption keys.
- *
- * @param premaster premaster secret
- * @param client_random random data from client hello
- * @param server_random random data from server hello
- */
- void (*derive_secrets)(tls_crypto_t *this, chunk_t premaster,
- chunk_t client_random, chunk_t server_random);
-
- /**
- * Change the cipher used at protection layer.
- *
- * @param inbound TRUE to change inbound cipher, FALSE for outbound
- */
- void (*change_cipher)(tls_crypto_t *this, bool inbound);
-
- /**
- * Derive the EAP-TLS MSK.
- *
- * @param client_random random data from client hello
- * @param server_random random data from server hello
- */
- void (*derive_eap_msk)(tls_crypto_t *this,
- chunk_t client_random, chunk_t server_random);
-
- /**
- * Get the MSK to use in EAP-TLS.
- *
- * @return MSK, points to internal data
- */
- chunk_t (*get_eap_msk)(tls_crypto_t *this);
-
- /**
- * Destroy a tls_crypto_t.
- */
- void (*destroy)(tls_crypto_t *this);
-};
-
-/**
- * Create a tls_crypto instance.
- */
-tls_crypto_t *tls_crypto_create(tls_t *tls);
-
-#endif /** TLS_CRYPTO_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_fragmentation.c b/src/libcharon/plugins/eap_tls/tls/tls_fragmentation.c
deleted file mode 100644
index 7a99c9235..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_fragmentation.c
+++ /dev/null
@@ -1,256 +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_fragmentation.h"
-
-#include "tls_reader.h"
-
-#include <daemon.h>
-
-typedef struct private_tls_fragmentation_t private_tls_fragmentation_t;
-
-/**
- * Private data of an tls_fragmentation_t object.
- */
-struct private_tls_fragmentation_t {
-
- /**
- * Public tls_fragmentation_t interface.
- */
- tls_fragmentation_t public;
-
- /**
- * Upper layer handshake protocol
- */
- tls_handshake_t *handshake;
-
- /**
- * Handshake input buffer
- */
- chunk_t input;
-
- /**
- * Position in input buffer
- */
- size_t inpos;
-
- /**
- * Currently processed handshake message type
- */
- tls_handshake_type_t type;
-
- /**
- * Handshake output buffer
- */
- chunk_t output;
-};
-
-/**
- * Maximum size of a TLS fragment
- */
-#define MAX_TLS_FRAGMENT_LEN 16384
-
-/**
- * Maximum size of a TLS handshake message we accept
- */
-#define MAX_TLS_HANDSHAKE_LEN 65536
-
-/**
- * Process TLS handshake protocol data
- */
-static status_t process_handshake(private_tls_fragmentation_t *this,
- tls_reader_t *reader)
-{
- while (reader->remaining(reader))
- {
- tls_reader_t *msg;
- u_int8_t type;
- u_int32_t len;
- status_t status;
- chunk_t data;
-
- if (reader->remaining(reader) > MAX_TLS_FRAGMENT_LEN)
- {
- DBG1(DBG_IKE, "TLS fragment has invalid length");
- return FAILED;
- }
-
- if (this->input.len == 0)
- { /* new handshake message */
- if (!reader->read_uint8(reader, &type) ||
- !reader->read_uint24(reader, &len))
- {
- return FAILED;
- }
- this->type = type;
- if (len > MAX_TLS_HANDSHAKE_LEN)
- {
- DBG1(DBG_IKE, "TLS handshake message exceeds maximum length");
- return FAILED;
- }
- chunk_free(&this->input);
- this->inpos = 0;
- if (len)
- {
- this->input = chunk_alloc(len);
- }
- }
-
- len = min(this->input.len - this->inpos, reader->remaining(reader));
- if (!reader->read_data(reader, len, &data))
- {
- return FAILED;
- }
- memcpy(this->input.ptr + this->inpos, data.ptr, len);
- this->inpos += len;
-
- if (this->input.len == this->inpos)
- { /* message completely defragmented, process */
- msg = tls_reader_create(this->input);
- status = this->handshake->process(this->handshake, this->type, msg);
- msg->destroy(msg);
- chunk_free(&this->input);
- if (status != NEED_MORE)
- {
- return status;
- }
- }
- }
- return NEED_MORE;
-}
-
-METHOD(tls_fragmentation_t, process, status_t,
- private_tls_fragmentation_t *this, tls_content_type_t type, chunk_t data)
-{
- tls_reader_t *reader;
- status_t status;
-
- reader = tls_reader_create(data);
- switch (type)
- {
- case TLS_CHANGE_CIPHER_SPEC:
- if (this->handshake->change_cipherspec(this->handshake))
- {
- status = NEED_MORE;
- break;
- }
- status = FAILED;
- break;
- case TLS_ALERT:
- /* TODO: handle Alert */
- status = FAILED;
- break;
- case TLS_HANDSHAKE:
- status = process_handshake(this, reader);
- break;
- case TLS_APPLICATION_DATA:
- /* skip application data */
- status = NEED_MORE;
- break;
- default:
- DBG1(DBG_IKE, "received unknown TLS content type %d, ignored", type);
- status = NEED_MORE;
- break;
- }
- reader->destroy(reader);
- return status;
-}
-
-METHOD(tls_fragmentation_t, build, status_t,
- private_tls_fragmentation_t *this, tls_content_type_t *type, chunk_t *data)
-{
- tls_handshake_type_t hs_type;
- tls_writer_t *writer, *msg;
- status_t status;
-
- if (this->handshake->cipherspec_changed(this->handshake))
- {
- *type = TLS_CHANGE_CIPHER_SPEC;
- *data = chunk_clone(chunk_from_chars(0x01));
- return NEED_MORE;
- }
-
- if (!this->output.len)
- {
- msg = tls_writer_create(64);
- do
- {
- writer = tls_writer_create(64);
- status = this->handshake->build(this->handshake, &hs_type, writer);
- switch (status)
- {
- case NEED_MORE:
- msg->write_uint8(msg, hs_type);
- msg->write_data24(msg, writer->get_buf(writer));
- break;
- case INVALID_STATE:
- this->output = chunk_clone(msg->get_buf(msg));
- break;
- default:
- break;
- }
- writer->destroy(writer);
- }
- while (status == NEED_MORE);
-
- msg->destroy(msg);
- if (status != INVALID_STATE)
- {
- return status;
- }
- }
-
- if (this->output.len)
- {
- *type = TLS_HANDSHAKE;
- if (this->output.len <= MAX_TLS_FRAGMENT_LEN)
- {
- *data = this->output;
- this->output = chunk_empty;
- return NEED_MORE;
- }
- *data = chunk_create(this->output.ptr, MAX_TLS_FRAGMENT_LEN);
- this->output = chunk_clone(chunk_skip(this->output, MAX_TLS_FRAGMENT_LEN));
- return NEED_MORE;
- }
- return status;
-}
-
-METHOD(tls_fragmentation_t, destroy, void,
- private_tls_fragmentation_t *this)
-{
- free(this->input.ptr);
- free(this->output.ptr);
- free(this);
-}
-
-/**
- * See header
- */
-tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake)
-{
- private_tls_fragmentation_t *this;
-
- INIT(this,
- .public = {
- .process = _process,
- .build = _build,
- .destroy = _destroy,
- },
- .handshake = handshake,
- );
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_fragmentation.h b/src/libcharon/plugins/eap_tls/tls/tls_fragmentation.h
deleted file mode 100644
index 61bf5488e..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_fragmentation.h
+++ /dev/null
@@ -1,77 +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.
- */
-
-/**
- * @defgroup tls_fragmentation tls_fragmentation
- * @{ @ingroup tls
- */
-
-#ifndef TLS_FRAGMENTATION_H_
-#define TLS_FRAGMENTATION_H_
-
-typedef struct tls_fragmentation_t tls_fragmentation_t;
-
-#include <library.h>
-
-#include "tls.h"
-#include "tls_handshake.h"
-
-/**
- * TLS record protocol fragmentation layer.
- */
-struct tls_fragmentation_t {
-
- /**
- * Process a fragmented TLS record, pass it to upper layers.
- *
- * @param type type of the TLS record to process
- * @param data associated TLS record data
- * @return
- * - SUCCESS if TLS negotiation complete
- * - FAILED if TLS handshake failed
- * - NEED_MORE if more invocations to process/build needed
- */
- status_t (*process)(tls_fragmentation_t *this,
- tls_content_type_t type, chunk_t data);
-
- /**
- * Query upper layer for TLS messages, build fragmented records.
- *
- * @param type type of the built TLS record
- * @param data allocated data of the built TLS record
- * @return
- * - SUCCESS if TLS negotiation complete
- * - FAILED if TLS handshake failed
- * - NEED_MORE if upper layers have more records to send
- * - INVALID_STATE if more input records required
- */
- status_t (*build)(tls_fragmentation_t *this,
- tls_content_type_t *type, chunk_t *data);
-
- /**
- * Destroy a tls_fragmentation_t.
- */
- void (*destroy)(tls_fragmentation_t *this);
-};
-
-/**
- * Create a tls_fragmentation instance.
- *
- * @param handshake upper layer handshake protocol
- * @return TLS fragmentation layer.
- */
-tls_fragmentation_t *tls_fragmentation_create(tls_handshake_t *handshake);
-
-#endif /** TLS_FRAGMENTATION_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_handshake.h b/src/libcharon/plugins/eap_tls/tls/tls_handshake.h
deleted file mode 100644
index 113974042..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_handshake.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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.
- */
-
-/**
- * @defgroup tls_handshake tls_handshake
- * @{ @ingroup tls
- */
-
-#ifndef TLS_HANDSHAKE_H_
-#define TLS_HANDSHAKE_H_
-
-typedef struct tls_handshake_t tls_handshake_t;
-
-#include "tls.h"
-#include "tls_reader.h"
-#include "tls_writer.h"
-
-/**
- * TLS handshake state machine interface.
- */
-struct tls_handshake_t {
-
- /**
- * Process received TLS handshake message.
- *
- * @param type TLS handshake message type
- * @param reader TLS data buffer
- * @return
- * - SUCCESS if handshake complete
- * - FAILED if handshake failed
- * - NEED_MORE if another invocation of process/build needed
- */
- status_t (*process)(tls_handshake_t *this,
- tls_handshake_type_t type, tls_reader_t *reader);
-
- /**
- * Build TLS handshake messages to send out.
- *
- * @param type type of created handshake message
- * @param writer TLS data buffer to write to
- * @return
- * - SUCCESS if handshake complete
- * - FAILED if handshake failed
- * - NEED_MORE if more messages ready for delivery
- * - INVALID_STATE if more input to process() required
- */
- status_t (*build)(tls_handshake_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer);
-
- /**
- * Check if the cipher spec for outgoing messages has changed.
- *
- * @return TRUE if cipher spec changed
- */
- bool (*cipherspec_changed)(tls_handshake_t *this);
-
- /**
- * Change the cipher spec for incoming messages.
- *
- * @return TRUE if cipher spec changed
- */
- bool (*change_cipherspec)(tls_handshake_t *this);
-
- /**
- * Destroy a tls_handshake_t.
- */
- void (*destroy)(tls_handshake_t *this);
-};
-
-#endif /** TLS_HANDSHAKE_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_peer.c b/src/libcharon/plugins/eap_tls/tls/tls_peer.c
deleted file mode 100644
index 95973598b..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_peer.c
+++ /dev/null
@@ -1,625 +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_peer.h"
-
-#include <daemon.h>
-
-#include <time.h>
-
-typedef struct private_tls_peer_t private_tls_peer_t;
-
-typedef enum {
- STATE_INIT,
- STATE_HELLO_SENT,
- STATE_HELLO_RECEIVED,
- STATE_HELLO_DONE,
- STATE_CERT_SENT,
- STATE_CERT_RECEIVED,
- STATE_CERTREQ_RECEIVED,
- STATE_KEY_EXCHANGE_SENT,
- STATE_VERIFY_SENT,
- STATE_CIPHERSPEC_CHANGED_OUT,
- STATE_FINISHED_SENT,
- STATE_CIPHERSPEC_CHANGED_IN,
- STATE_COMPLETE,
-} peer_state_t;
-
-/**
- * Private data of an tls_peer_t object.
- */
-struct private_tls_peer_t {
-
- /**
- * Public tls_peer_t interface.
- */
- tls_peer_t public;
-
- /**
- * TLS stack
- */
- tls_t *tls;
-
- /**
- * TLS crypto context
- */
- tls_crypto_t *crypto;
-
- /**
- * Peer identity
- */
- identification_t *peer;
-
- /**
- * Server identity
- */
- identification_t *server;
-
- /**
- * State we are in
- */
- peer_state_t state;
-
- /**
- * Hello random data selected by client
- */
- char client_random[32];
-
- /**
- * Hello random data selected by server
- */
- char server_random[32];
-
- /**
- * Auth helper for peer authentication
- */
- auth_cfg_t *peer_auth;
-
- /**
- * Auth helper for server authentication
- */
- auth_cfg_t *server_auth;
-
- /**
- * Peer private key
- */
- private_key_t *private;
-};
-
-/**
- * Process a server hello message
- */
-static status_t process_server_hello(private_tls_peer_t *this,
- tls_reader_t *reader)
-{
- u_int8_t compression;
- u_int16_t version, cipher;
- chunk_t random, session, ext = chunk_empty;
- tls_cipher_suite_t suite;
-
- this->crypto->append_handshake(this->crypto,
- TLS_SERVER_HELLO, reader->peek(reader));
-
- if (!reader->read_uint16(reader, &version) ||
- !reader->read_data(reader, sizeof(this->server_random), &random) ||
- !reader->read_data8(reader, &session) ||
- !reader->read_uint16(reader, &cipher) ||
- !reader->read_uint8(reader, &compression) ||
- (reader->remaining(reader) && !reader->read_data16(reader, &ext)))
- {
- DBG1(DBG_IKE, "received invalid ServerHello");
- return FAILED;
- }
-
- memcpy(this->server_random, random.ptr, sizeof(this->server_random));
-
- if (version < this->tls->get_version(this->tls))
- {
- this->tls->set_version(this->tls, version);
- }
- suite = cipher;
- if (!this->crypto->select_cipher_suite(this->crypto, &suite, 1))
- {
- DBG1(DBG_IKE, "received cipher suite inacceptable");
- return FAILED;
- }
- this->state = STATE_HELLO_RECEIVED;
- return NEED_MORE;
-}
-
-/**
- * Process a Certificate message
- */
-static status_t process_certificate(private_tls_peer_t *this,
- tls_reader_t *reader)
-{
- certificate_t *cert;
- tls_reader_t *certs;
- chunk_t data;
- bool first = TRUE;
-
- this->crypto->append_handshake(this->crypto,
- TLS_CERTIFICATE, reader->peek(reader));
-
- if (!reader->read_data24(reader, &data))
- {
- return FAILED;
- }
- certs = tls_reader_create(data);
- while (certs->remaining(certs))
- {
- if (!certs->read_data24(certs, &data))
- {
- certs->destroy(certs);
- return FAILED;
- }
- cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, data, BUILD_END);
- if (cert)
- {
- if (first)
- {
- this->server_auth->add(this->server_auth,
- AUTH_HELPER_SUBJECT_CERT, cert);
- DBG1(DBG_IKE, "received TLS server certificate '%Y'",
- cert->get_subject(cert));
- first = FALSE;
- }
- else
- {
- DBG1(DBG_IKE, "received TLS intermediate certificate '%Y'",
- cert->get_subject(cert));
- this->server_auth->add(this->server_auth,
- AUTH_HELPER_IM_CERT, cert);
- }
- }
- else
- {
- DBG1(DBG_IKE, "parsing TLS certificate failed, skipped");
- }
- }
- certs->destroy(certs);
- this->state = STATE_CERT_RECEIVED;
- return NEED_MORE;
-}
-
-/**
- * Process a Certificate message
- */
-static status_t process_certreq(private_tls_peer_t *this, tls_reader_t *reader)
-{
- chunk_t types, hashsig, data;
- tls_reader_t *authorities;
- identification_t *id;
- certificate_t *cert;
-
- this->crypto->append_handshake(this->crypto,
- TLS_CERTIFICATE_REQUEST, reader->peek(reader));
-
- if (!reader->read_data8(reader, &types))
- {
- return FAILED;
- }
- if (this->tls->get_version(this->tls) >= TLS_1_2)
- {
- if (!reader->read_data16(reader, &hashsig))
- {
- return FAILED;
- }
- /* TODO: store supported hashsig algorithms */
- }
- if (!reader->read_data16(reader, &data))
- {
- return FAILED;
- }
- authorities = tls_reader_create(data);
- while (authorities->remaining(authorities))
- {
- if (!authorities->read_data16(authorities, &data))
- {
- authorities->destroy(authorities);
- return FAILED;
- }
- id = identification_create_from_encoding(ID_DER_ASN1_DN, data);
- cert = lib->credmgr->get_cert(lib->credmgr,
- CERT_X509, KEY_ANY, id, TRUE);
- if (cert)
- {
- DBG1(DBG_IKE, "received cert request for '%Y", id);
- this->peer_auth->add(this->peer_auth, AUTH_RULE_CA_CERT, cert);
- }
- else
- {
- DBG1(DBG_IKE, "received cert request for unknown CA '%Y'", id);
- }
- id->destroy(id);
- }
- authorities->destroy(authorities);
- this->state = STATE_CERTREQ_RECEIVED;
- return NEED_MORE;
-}
-
-/**
- * Process Hello Done message
- */
-static status_t process_hello_done(private_tls_peer_t *this,
- tls_reader_t *reader)
-{
- this->crypto->append_handshake(this->crypto,
- TLS_SERVER_HELLO_DONE, reader->peek(reader));
- this->state = STATE_HELLO_DONE;
- return NEED_MORE;
-}
-
-/**
- * Process finished message
- */
-static status_t process_finished(private_tls_peer_t *this, tls_reader_t *reader)
-{
- chunk_t received;
- char buf[12];
-
- if (!reader->read_data(reader, sizeof(buf), &received))
- {
- DBG1(DBG_IKE, "received server finished too short");
- return FAILED;
- }
- if (!this->crypto->calculate_finished(this->crypto, "server finished", buf))
- {
- DBG1(DBG_IKE, "calculating server finished failed");
- return FAILED;
- }
- if (!chunk_equals(received, chunk_from_thing(buf)))
- {
- DBG1(DBG_IKE, "received server finished invalid");
- return FAILED;
- }
- this->state = STATE_COMPLETE;
- this->crypto->derive_eap_msk(this->crypto,
- chunk_from_thing(this->client_random),
- chunk_from_thing(this->server_random));
- return NEED_MORE;
-}
-
-METHOD(tls_handshake_t, process, status_t,
- private_tls_peer_t *this, tls_handshake_type_t type, tls_reader_t *reader)
-{
- tls_handshake_type_t expected;
-
- switch (this->state)
- {
- case STATE_HELLO_SENT:
- if (type == TLS_SERVER_HELLO)
- {
- return process_server_hello(this, reader);
- }
- expected = TLS_SERVER_HELLO;
- break;
- case STATE_HELLO_RECEIVED:
- if (type == TLS_CERTIFICATE)
- {
- return process_certificate(this, reader);
- }
- expected = TLS_CERTIFICATE;
- break;
- case STATE_CERT_RECEIVED:
- if (type == TLS_CERTIFICATE_REQUEST)
- {
- return process_certreq(this, reader);
- }
- expected = TLS_CERTIFICATE_REQUEST;
- break;
- case STATE_CERTREQ_RECEIVED:
- if (type == TLS_SERVER_HELLO_DONE)
- {
- return process_hello_done(this, reader);
- }
- expected = TLS_SERVER_HELLO_DONE;
- break;
- case STATE_CIPHERSPEC_CHANGED_IN:
- if (type == TLS_FINISHED)
- {
- return process_finished(this, reader);
- }
- expected = TLS_FINISHED;
- break;
- default:
- DBG1(DBG_IKE, "TLS %N not expected in current state",
- tls_handshake_type_names, type);
- return FAILED;
- }
- DBG1(DBG_IKE, "TLS %N expected, but received %N",
- tls_handshake_type_names, expected, tls_handshake_type_names, type);
- return FAILED;
-}
-
-/**
- * Send a client hello
- */
-static status_t send_client_hello(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
-{
- tls_cipher_suite_t *suite;
- int count, i;
- rng_t *rng;
-
- htoun32(&this->client_random, time(NULL));
- rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- if (!rng)
- {
- return FAILED;
- }
- rng->get_bytes(rng, sizeof(this->client_random) - 4, this->client_random + 4);
- rng->destroy(rng);
-
- writer->write_uint16(writer, this->tls->get_version(this->tls));
- writer->write_data(writer, chunk_from_thing(this->client_random));
- /* session identifier => none */
- writer->write_data8(writer, chunk_empty);
-
- count = this->crypto->get_cipher_suites(this->crypto, &suite);
- writer->write_uint16(writer, count * 2);
- for (i = 0; i < count; i++)
- {
- writer->write_uint16(writer, suite[i]);
- }
- /* NULL compression only */
- writer->write_uint8(writer, 1);
- writer->write_uint8(writer, 0);
-
- *type = TLS_CLIENT_HELLO;
- this->state = STATE_HELLO_SENT;
- this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
- return NEED_MORE;
-}
-
-/**
- * Send Certificate
- */
-static status_t send_certificate(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
-{
- enumerator_t *enumerator;
- certificate_t *cert;
- auth_rule_t rule;
- tls_writer_t *certs;
- chunk_t data;
-
- this->private = lib->credmgr->get_private(lib->credmgr,
- KEY_ANY, this->peer, this->peer_auth);
- if (!this->private)
- {
- DBG1(DBG_IKE, "no TLS peer certificate found for '%Y'", this->peer);
- return FAILED;
- }
-
- /* generate certificate payload */
- certs = tls_writer_create(256);
- cert = this->peer_auth->get(this->peer_auth, AUTH_RULE_SUBJECT_CERT);
- if (cert)
- {
- if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
- {
- DBG1(DBG_IKE, "sending TLS peer certificate '%Y'",
- cert->get_subject(cert));
- certs->write_data24(certs, data);
- free(data.ptr);
- }
- }
- enumerator = this->peer_auth->create_enumerator(this->peer_auth);
- while (enumerator->enumerate(enumerator, &rule, &cert))
- {
- if (rule == AUTH_RULE_IM_CERT)
- {
- if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
- {
- DBG1(DBG_IKE, "sending TLS intermediate certificate '%Y'",
- cert->get_subject(cert));
- certs->write_data24(certs, data);
- free(data.ptr);
- }
- }
- }
- enumerator->destroy(enumerator);
-
- writer->write_data24(writer, certs->get_buf(certs));
- certs->destroy(certs);
-
- *type = TLS_CERTIFICATE;
- this->state = STATE_CERT_SENT;
- this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
- return NEED_MORE;
-}
-
-/**
- * Send client key exchange
- */
-static status_t send_key_exchange(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
-{
- public_key_t *public = NULL, *current;
- enumerator_t *enumerator;
- auth_cfg_t *auth;
- rng_t *rng;
- char premaster[48];
- chunk_t encrypted;
-
- rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
- if (!rng)
- {
- DBG1(DBG_IKE, "no suitable RNG found for TLS premaster secret");
- return FAILED;
- }
- rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2);
- rng->destroy(rng);
- htoun16(premaster, TLS_1_2);
-
- this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster),
- chunk_from_thing(this->client_random),
- chunk_from_thing(this->server_random));
-
- enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
- KEY_ANY, this->server, this->server_auth);
- while (enumerator->enumerate(enumerator, &current, &auth))
- {
- public = current->get_ref(current);
- break;
- }
- enumerator->destroy(enumerator);
-
- if (!public)
- {
- DBG1(DBG_IKE, "no TLS public key found for server '%Y'", this->server);
- return FAILED;
- }
- if (!public->encrypt(public, chunk_from_thing(premaster), &encrypted))
- {
- public->destroy(public);
- DBG1(DBG_IKE, "encrypting TLS premaster secret failed");
- return FAILED;
- }
-
- public->destroy(public);
-
- writer->write_data16(writer, encrypted);
- free(encrypted.ptr);
-
- *type = TLS_CLIENT_KEY_EXCHANGE;
- this->state = STATE_KEY_EXCHANGE_SENT;
- this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
- return NEED_MORE;
-}
-
-/**
- * Send certificate verify
- */
-static status_t send_certificate_verify(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
-{
- if (!this->private ||
- !this->crypto->sign_handshake(this->crypto, this->private, writer))
- {
- DBG1(DBG_IKE, "creating TLS Certificate Verify signature failed");
- return FAILED;
- }
-
- *type = TLS_CERTIFICATE_VERIFY;
- this->state = STATE_VERIFY_SENT;
- this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
- return NEED_MORE;
-}
-
-/**
- * Send Finished
- */
-static status_t send_finished(private_tls_peer_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
-{
- char buf[12];
-
- if (!this->crypto->calculate_finished(this->crypto, "client finished", buf))
- {
- DBG1(DBG_IKE, "calculating client finished data failed");
- return FAILED;
- }
-
- writer->write_data(writer, chunk_from_thing(buf));
-
- *type = TLS_FINISHED;
- this->state = STATE_FINISHED_SENT;
- this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
- return NEED_MORE;
-}
-
-METHOD(tls_handshake_t, build, status_t,
- private_tls_peer_t *this, tls_handshake_type_t *type, tls_writer_t *writer)
-{
- switch (this->state)
- {
- case STATE_INIT:
- return send_client_hello(this, type, writer);
- case STATE_HELLO_DONE:
- return send_certificate(this, type, writer);
- case STATE_CERT_SENT:
- return send_key_exchange(this, type, writer);
- case STATE_KEY_EXCHANGE_SENT:
- return send_certificate_verify(this, type, writer);
- case STATE_CIPHERSPEC_CHANGED_OUT:
- return send_finished(this, type, writer);
- default:
- return INVALID_STATE;
- }
-}
-
-METHOD(tls_handshake_t, cipherspec_changed, bool,
- private_tls_peer_t *this)
-{
- if (this->state == STATE_VERIFY_SENT)
- {
- this->crypto->change_cipher(this->crypto, FALSE);
- this->state = STATE_CIPHERSPEC_CHANGED_OUT;
- return TRUE;
- }
- return FALSE;
-}
-
-METHOD(tls_handshake_t, change_cipherspec, bool,
- private_tls_peer_t *this)
-{
- if (this->state == STATE_FINISHED_SENT)
- {
- this->crypto->change_cipher(this->crypto, TRUE);
- this->state = STATE_CIPHERSPEC_CHANGED_IN;
- return TRUE;
- }
- return FALSE;
-}
-
-METHOD(tls_handshake_t, destroy, void,
- private_tls_peer_t *this)
-{
- DESTROY_IF(this->private);
- this->peer_auth->destroy(this->peer_auth);
- this->server_auth->destroy(this->server_auth);
- free(this);
-}
-
-/**
- * See header
- */
-tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto,
- identification_t *peer, identification_t *server)
-{
- private_tls_peer_t *this;
-
- INIT(this,
- .public.handshake = {
- .process = _process,
- .build = _build,
- .cipherspec_changed = _cipherspec_changed,
- .change_cipherspec = _change_cipherspec,
- .destroy = _destroy,
- },
- .state = STATE_INIT,
- .tls = tls,
- .crypto = crypto,
- .peer = peer,
- .server = server,
- .peer_auth = auth_cfg_create(),
- .server_auth = auth_cfg_create(),
- );
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_peer.h b/src/libcharon/plugins/eap_tls/tls/tls_peer.h
deleted file mode 100644
index 7857d3261..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_peer.h
+++ /dev/null
@@ -1,48 +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.
- */
-
-/**
- * @defgroup tls_peer tls_peer
- * @{ @ingroup tls
- */
-
-#ifndef TLS_PEER_H_
-#define TLS_PEER_H_
-
-typedef struct tls_peer_t tls_peer_t;
-
-#include "tls_handshake.h"
-#include "tls_crypto.h"
-
-#include <library.h>
-
-/**
- * TLS handshake protocol handler as peer.
- */
-struct tls_peer_t {
-
- /**
- * Implements the TLS handshake protocol handler.
- */
- tls_handshake_t handshake;
-};
-
-/**
- * Create a tls_peer instance.
- */
-tls_peer_t *tls_peer_create(tls_t *tls, tls_crypto_t *crypto,
- identification_t *peer, identification_t *server);
-
-#endif /** TLS_PEER_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_prf.c b/src/libcharon/plugins/eap_tls/tls/tls_prf.c
deleted file mode 100644
index f181d01d3..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_prf.c
+++ /dev/null
@@ -1,190 +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_prf.h"
-
-typedef struct private_tls_prf12_t private_tls_prf12_t;
-
-/**
- * Private data of an tls_prf_t object.
- */
-struct private_tls_prf12_t {
-
- /**
- * Public tls_prf_t interface.
- */
- tls_prf_t public;
-
- /**
- * Underlying primitive PRF
- */
- prf_t *prf;
-};
-
-METHOD(tls_prf_t, set_key12, void,
- private_tls_prf12_t *this, chunk_t key)
-{
- this->prf->set_key(this->prf, key);
-}
-
-/**
- * The P_hash function as in TLS 1.0/1.2
- */
-static void p_hash(prf_t *prf, char *label, chunk_t seed, size_t block_size,
- size_t bytes, char *out)
-{
- char buf[block_size], abuf[block_size];
- chunk_t a;
-
- /* seed = label + seed */
- seed = chunk_cata("cc", chunk_create(label, strlen(label)), seed);
- /* A(0) = seed */
- a = seed;
-
- while (TRUE)
- {
- /* A(i) = HMAC_hash(secret, A(i-1)) */
- prf->get_bytes(prf, a, abuf);
- a = chunk_from_thing(abuf);
- /* HMAC_hash(secret, A(i) + seed) */
- prf->get_bytes(prf, a, NULL);
- prf->get_bytes(prf, seed, buf);
-
- if (bytes <= block_size)
- {
- memcpy(out, buf, bytes);
- break;
- }
- memcpy(out, buf, block_size);
- out += block_size;
- bytes -= block_size;
- }
-}
-
-METHOD(tls_prf_t, get_bytes12, void,
- private_tls_prf12_t *this, char *label, chunk_t seed,
- size_t bytes, char *out)
-{
- p_hash(this->prf, label, seed, this->prf->get_block_size(this->prf),
- bytes, out);
-}
-
-METHOD(tls_prf_t, destroy12, void,
- private_tls_prf12_t *this)
-{
- this->prf->destroy(this->prf);
- free(this);
-}
-
-/**
- * See header
- */
-tls_prf_t *tls_prf_create_12(pseudo_random_function_t prf)
-{
- private_tls_prf12_t *this;
-
- INIT(this,
- .public = {
- .set_key = _set_key12,
- .get_bytes = _get_bytes12,
- .destroy = _destroy12,
- },
- .prf = lib->crypto->create_prf(lib->crypto, prf),
- );
- if (!this->prf)
- {
- free(this);
- return NULL;
- }
- return &this->public;
-}
-
-
-typedef struct private_tls_prf10_t private_tls_prf10_t;
-
-/**
- * Private data of an tls_prf_t object.
- */
-struct private_tls_prf10_t {
-
- /**
- * Public tls_prf_t interface.
- */
- tls_prf_t public;
-
- /**
- * Underlying MD5 PRF
- */
- prf_t *md5;
-
- /**
- * Underlying SHA1 PRF
- */
- prf_t *sha1;
-};
-
-METHOD(tls_prf_t, set_key10, void,
- private_tls_prf10_t *this, chunk_t key)
-{
- size_t len = key.len / 2 + key.len % 2;
-
- this->md5->set_key(this->md5, chunk_create(key.ptr, len));
- this->sha1->set_key(this->sha1, chunk_create(key.ptr + key.len - len, len));
-}
-
-METHOD(tls_prf_t, get_bytes10, void,
- private_tls_prf10_t *this, char *label, chunk_t seed,
- size_t bytes, char *out)
-{
- char buf[bytes];
-
- p_hash(this->md5, label, seed, this->md5->get_block_size(this->md5),
- bytes, out);
- p_hash(this->sha1, label, seed, this->sha1->get_block_size(this->sha1),
- bytes, buf);
- memxor(out, buf, bytes);
-}
-
-METHOD(tls_prf_t, destroy10, void,
- private_tls_prf10_t *this)
-{
- DESTROY_IF(this->md5);
- DESTROY_IF(this->sha1);
- free(this);
-}
-
-/**
- * See header
- */
-tls_prf_t *tls_prf_create_10(pseudo_random_function_t prf)
-{
- private_tls_prf10_t *this;
-
- INIT(this,
- .public = {
- .set_key = _set_key10,
- .get_bytes = _get_bytes10,
- .destroy = _destroy10,
- },
- .md5 = lib->crypto->create_prf(lib->crypto, PRF_HMAC_MD5),
- .sha1 = lib->crypto->create_prf(lib->crypto, PRF_HMAC_SHA1),
- );
- if (!this->md5 || !this->sha1)
- {
- destroy10(this);
- return NULL;
- }
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_prf.h b/src/libcharon/plugins/eap_tls/tls/tls_prf.h
deleted file mode 100644
index 7326be98c..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_prf.h
+++ /dev/null
@@ -1,72 +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.
- */
-
-/**
- * @defgroup tls_prf tls_prf
- * @{ @ingroup tls
- */
-
-#ifndef TLS_PRF_H_
-#define TLS_PRF_H_
-
-typedef struct tls_prf_t tls_prf_t;
-
-#include <crypto/prfs/prf.h>
-
-/**
- * The PRF function specified on TLS, based on HMAC.
- */
-struct tls_prf_t {
-
- /**
- * Set the key of the PRF function.
- *
- * @param key key to set
- */
- void (*set_key)(tls_prf_t *this, chunk_t key);
-
- /**
- * Generate a series of bytes using a label and a seed.
- *
- * @param label ASCII input label
- * @param seed seed input value
- * @param bytes number of bytes to get
- * @param out buffer receiving bytes
- */
- void (*get_bytes)(tls_prf_t *this, char *label, chunk_t seed,
- size_t bytes, char *out);
-
- /**
- * Destroy a tls_prf_t.
- */
- void (*destroy)(tls_prf_t *this);
-};
-
-/**
- * Create a tls_prf instance with specific algorithm as in TLS 1.2.
- *
- * @param hash underlying PRF function to use
- * @return TLS PRF algorithm
- */
-tls_prf_t *tls_prf_create_12(pseudo_random_function_t prf);
-
-/**
- * Create a tls_prf instance with XOred SHA1/MD5 as in TLS 1.0/1.1.
- *
- * @return TLS PRF algorithm
- */
-tls_prf_t *tls_prf_create_10();
-
-#endif /** TLS_PRF_H_ @}*/
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;
-}
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_protection.h b/src/libcharon/plugins/eap_tls/tls/tls_protection.h
deleted file mode 100644
index fab913788..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_protection.h
+++ /dev/null
@@ -1,90 +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.
- */
-
-/**
- * @defgroup tls_protection tls_protection
- * @{ @ingroup tls
- */
-
-#ifndef TLS_PROTECTION_H_
-#define TLS_PROTECTION_H_
-
-typedef struct tls_protection_t tls_protection_t;
-
-#include <library.h>
-
-#include "tls.h"
-#include "tls_compression.h"
-
-/**
- * TLS record protocol protection layer.
- */
-struct tls_protection_t {
-
- /**
- * Process a protected TLS record, pass it to upper layers.
- *
- * @param type type of the TLS record to process
- * @param data associated TLS record data
- * @return
- * - SUCCESS if TLS negotiation complete
- * - FAILED if TLS handshake failed
- * - NEED_MORE if more invocations to process/build needed
- */
- status_t (*process)(tls_protection_t *this,
- tls_content_type_t type, chunk_t data);
-
- /**
- * Query upper layer for TLS record, build protected record.
- *
- * @param type type of the built TLS record
- * @param data allocated data of the built TLS record
- * @return
- * - SUCCESS if TLS negotiation complete
- * - FAILED if TLS handshake failed
- * - NEED_MORE if upper layers have more records to send
- * - INVALID_STATE if more input records required
- */
- status_t (*build)(tls_protection_t *this,
- tls_content_type_t *type, chunk_t *data);
-
- /**
- * Set a new cipher, including encryption and integrity algorithms.
- *
- * @param inbound TRUE to use cipher for inbound data, FALSE for outbound
- * @param signer new signer to use, gets owned by protection layer
- * @param crypter new crypter to use, gets owned by protection layer
- * @param iv initial IV for crypter, gets owned by protection layer
- */
- void (*set_cipher)(tls_protection_t *this, bool inbound, signer_t *signer,
- crypter_t *crypter, chunk_t iv);
-
- /**
- * Destroy a tls_protection_t.
- */
- void (*destroy)(tls_protection_t *this);
-};
-
-/**
- * Create a tls_protection instance.
- *
- * @param tls TLS context
- * @param compression compression layer of TLS stack
- * @return TLS protection layer.
- */
-tls_protection_t *tls_protection_create(tls_t *tls,
- tls_compression_t *compression);
-
-#endif /** TLS_PROTECTION_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_reader.c b/src/libcharon/plugins/eap_tls/tls/tls_reader.c
deleted file mode 100644
index b21eb04f3..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_reader.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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_reader.h"
-
-#include <daemon.h>
-
-typedef struct private_tls_reader_t private_tls_reader_t;
-
-/**
- * Private data of an tls_reader_t object.
- */
-struct private_tls_reader_t {
-
- /**
- * Public tls_reader_t interface.
- */
- tls_reader_t public;
-
- /**
- * Remaining data to process
- */
- chunk_t buf;
-};
-
-METHOD(tls_reader_t, remaining, u_int32_t,
- private_tls_reader_t *this)
-{
- return this->buf.len;
-}
-
-METHOD(tls_reader_t, peek, chunk_t,
- private_tls_reader_t *this)
-{
- return this->buf;
-}
-
-METHOD(tls_reader_t, read_uint8, bool,
- private_tls_reader_t *this, u_int8_t *res)
-{
- if (this->buf.len < 1)
- {
- DBG1(DBG_IKE, "%d bytes insufficient to parse uint%d TLS data",
- this->buf.len, 8);
- return FALSE;
- }
- *res = this->buf.ptr[0];
- this->buf = chunk_skip(this->buf, 1);
- return TRUE;
-}
-
-METHOD(tls_reader_t, read_uint16, bool,
- private_tls_reader_t *this, u_int16_t *res)
-{
- if (this->buf.len < 2)
- {
- DBG1(DBG_IKE, "%d bytes insufficient to parse uint%d TLS data",
- this->buf.len, 16);
- return FALSE;
- }
- *res = untoh16(this->buf.ptr);
- this->buf = chunk_skip(this->buf, 2);
- return TRUE;
-}
-
-METHOD(tls_reader_t, read_uint24, bool,
- private_tls_reader_t *this, u_int32_t *res)
-{
- if (this->buf.len < 3)
- {
- DBG1(DBG_IKE, "%d bytes insufficient to parse uint%d TLS data",
- this->buf.len, 24);
- return FALSE;
- }
- *res = untoh32(this->buf.ptr) >> 8;
- this->buf = chunk_skip(this->buf, 3);
- return TRUE;
-}
-
-METHOD(tls_reader_t, read_uint32, bool,
- private_tls_reader_t *this, u_int32_t *res)
-{
- if (this->buf.len < 4)
- {
- DBG1(DBG_IKE, "%d bytes insufficient to parse uint%d TLS data",
- this->buf.len, 32);
- return FALSE;
- }
- *res = untoh32(this->buf.ptr);
- this->buf = chunk_skip(this->buf, 4);
- return TRUE;
-}
-
-METHOD(tls_reader_t, read_data, bool,
- private_tls_reader_t *this, u_int32_t len, chunk_t *res)
-{
- if (this->buf.len < len)
- {
- DBG1(DBG_IKE, "%d bytes insufficient to parse %d bytes TLS data",
- this->buf.len, len);
- return FALSE;
- }
- *res = chunk_create(this->buf.ptr, len);
- this->buf = chunk_skip(this->buf, len);
- return TRUE;
-}
-
-METHOD(tls_reader_t, read_data8, bool,
- private_tls_reader_t *this, chunk_t *res)
-{
- u_int8_t len;
-
- if (!read_uint8(this, &len))
- {
- return FALSE;
- }
- return read_data(this, len, res);
-}
-
-METHOD(tls_reader_t, read_data16, bool,
- private_tls_reader_t *this, chunk_t *res)
-{
- u_int16_t len;
-
- if (!read_uint16(this, &len))
- {
- return FALSE;
- }
- return read_data(this, len, res);
-}
-
-METHOD(tls_reader_t, read_data24, bool,
- private_tls_reader_t *this, chunk_t *res)
-{
- u_int32_t len;
-
- if (!read_uint24(this, &len))
- {
- return FALSE;
- }
- return read_data(this, len, res);
-}
-
-METHOD(tls_reader_t, read_data32, bool,
- private_tls_reader_t *this, chunk_t *res)
-{
- u_int32_t len;
-
- if (!read_uint32(this, &len))
- {
- return FALSE;
- }
- return read_data(this, len, res);
-}
-
-METHOD(tls_reader_t, destroy, void,
- private_tls_reader_t *this)
-{
- free(this);
-}
-
-/**
- * See header
- */
-tls_reader_t *tls_reader_create(chunk_t data)
-{
- private_tls_reader_t *this;
-
- INIT(this,
- .public = {
- .remaining = _remaining,
- .peek = _peek,
- .read_uint8 = _read_uint8,
- .read_uint16 = _read_uint16,
- .read_uint24 = _read_uint24,
- .read_uint32 = _read_uint32,
- .read_data = _read_data,
- .read_data8 = _read_data8,
- .read_data16 = _read_data16,
- .read_data24 = _read_data24,
- .read_data32 = _read_data32,
- .destroy = _destroy,
- },
- .buf = data,
- );
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_reader.h b/src/libcharon/plugins/eap_tls/tls/tls_reader.h
deleted file mode 100644
index a8917dfb6..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_reader.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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.
- */
-
-/**
- * @defgroup tls_reader tls_reader
- * @{ @ingroup tls
- */
-
-#ifndef TLS_READER_H_
-#define TLS_READER_H_
-
-typedef struct tls_reader_t tls_reader_t;
-
-#include <library.h>
-
-/**
- * TLS record parser.
- */
-struct tls_reader_t {
-
- /**
- * Get the number of remaining bytes.
- *
- * @return number of remaining bytes in buffer
- */
- u_int32_t (*remaining)(tls_reader_t *this);
-
- /**
- * Peek the remaining data, not consuming any bytes.
- *
- * @return remaining data
- */
- chunk_t (*peek)(tls_reader_t *this);
-
- /**
- * Read a 8-bit integer from the buffer, advance.
- *
- * @param res pointer to result
- * @return TRUE if integer read successfully
- */
- bool (*read_uint8)(tls_reader_t *this, u_int8_t *res);
-
- /**
- * Read a 16-bit integer from the buffer, advance.
- *
- * @param res pointer to result
- * @return TRUE if integer read successfully
- */
- bool (*read_uint16)(tls_reader_t *this, u_int16_t *res);
-
- /**
- * Read a 24-bit integer from the buffer, advance.
- *
- * @param res pointer to result
- * @return TRUE if integer read successfully
- */
- bool (*read_uint24)(tls_reader_t *this, u_int32_t *res);
-
- /**
- * Read a 32-bit integer from the buffer, advance.
- *
- * @param res pointer to result
- * @return TRUE if integer read successfully
- */
- bool (*read_uint32)(tls_reader_t *this, u_int32_t *res);
-
- /**
- * Read a chunk of len bytes, advance.
- *
- * @param len number of bytes to read
- * @param res pointer to result, not cloned
- * @return TRUE if data read successfully
- */
- bool (*read_data)(tls_reader_t *this, u_int32_t len, chunk_t *res);
-
- /**
- * Read a chunk of bytes with a 8-bit length header, advance.
- *
- * @param res pointer to result, not cloned
- * @return TRUE if data read successfully
- */
- bool (*read_data8)(tls_reader_t *this, chunk_t *res);
-
- /**
- * Read a chunk of bytes with a 16-bit length header, advance.
- *
- * @param res pointer to result, not cloned
- * @return TRUE if data read successfully
- */
- bool (*read_data16)(tls_reader_t *this, chunk_t *res);
-
- /**
- * Read a chunk of bytes with a 24-bit length header, advance.
- *
- * @param res pointer to result, not cloned
- * @return TRUE if data read successfully
- */
- bool (*read_data24)(tls_reader_t *this, chunk_t *res);
-
- /**
- * Read a chunk of bytes with a 32-bit length header, advance.
- *
- * @param res pointer to result, not cloned
- * @return TRUE if data read successfully
- */
- bool (*read_data32)(tls_reader_t *this, chunk_t *res);
-
- /**
- * Destroy a tls_reader_t.
- */
- void (*destroy)(tls_reader_t *this);
-};
-
-/**
- * Create a tls_reader instance.
- */
-tls_reader_t *tls_reader_create(chunk_t data);
-
-#endif /** tls_reader_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_server.c b/src/libcharon/plugins/eap_tls/tls/tls_server.c
deleted file mode 100644
index 60c62684e..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_server.c
+++ /dev/null
@@ -1,607 +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_server.h"
-
-#include <time.h>
-
-#include <daemon.h>
-
-typedef struct private_tls_server_t private_tls_server_t;
-
-
-typedef enum {
- STATE_INIT,
- STATE_HELLO_RECEIVED,
- STATE_HELLO_SENT,
- STATE_CERT_SENT,
- STATE_CERTREQ_SENT,
- STATE_HELLO_DONE,
- STATE_CERT_RECEIVED,
- STATE_KEY_EXCHANGE_RECEIVED,
- STATE_CERT_VERIFY_RECEIVED,
- STATE_CIPHERSPEC_CHANGED_IN,
- STATE_FINISHED_RECEIVED,
- STATE_CIPHERSPEC_CHANGED_OUT,
- STATE_FINISHED_SENT,
-} server_state_t;
-
-/**
- * Private data of an tls_server_t object.
- */
-struct private_tls_server_t {
-
- /**
- * Public tls_server_t interface.
- */
- tls_server_t public;
-
- /**
- * TLS stack
- */
- tls_t *tls;
-
- /**
- * TLS crypto context
- */
- tls_crypto_t *crypto;
-
- /**
- * Server identity
- */
- identification_t *server;
-
- /**
- * Peer identity
- */
- identification_t *peer;
-
- /**
- * State we are in
- */
- server_state_t state;
-
- /**
- * Hello random data selected by client
- */
- char client_random[32];
-
- /**
- * Hello random data selected by server
- */
- char server_random[32];
-
- /**
- * Auth helper for peer authentication
- */
- auth_cfg_t *peer_auth;
-
- /**
- * Auth helper for server authentication
- */
- auth_cfg_t *server_auth;
-
- /**
- * Peer private key
- */
- private_key_t *private;
-
- /**
- * Selected TLS cipher suite
- */
- tls_cipher_suite_t suite;
-};
-
-/**
- * Process client hello message
- */
-static status_t process_client_hello(private_tls_server_t *this,
- tls_reader_t *reader)
-{
- u_int16_t version;
- chunk_t random, session, ciphers, compression, ext = chunk_empty;
- tls_cipher_suite_t *suites;
- int count, i;
-
- this->crypto->append_handshake(this->crypto,
- TLS_CLIENT_HELLO, reader->peek(reader));
-
- if (!reader->read_uint16(reader, &version) ||
- !reader->read_data(reader, sizeof(this->client_random), &random) ||
- !reader->read_data8(reader, &session) ||
- !reader->read_data16(reader, &ciphers) ||
- !reader->read_data8(reader, &compression) ||
- (reader->remaining(reader) && !reader->read_data16(reader, &ext)))
- {
- DBG1(DBG_IKE, "received invalid ClientHello");
- return FAILED;
- }
-
- memcpy(this->client_random, random.ptr, sizeof(this->client_random));
-
- if (version < this->tls->get_version(this->tls))
- {
- this->tls->set_version(this->tls, version);
- }
- count = ciphers.len / sizeof(u_int16_t);
- suites = alloca(count * sizeof(tls_cipher_suite_t));
- for (i = 0; i < count; i++)
- {
- suites[i] = untoh16(&ciphers.ptr[i * sizeof(u_int16_t)]);
- }
- this->suite = this->crypto->select_cipher_suite(this->crypto, suites, count);
- if (!this->suite)
- {
- DBG1(DBG_IKE, "received cipher suite inacceptable");
- return FAILED;
- }
- this->state = STATE_HELLO_RECEIVED;
- return NEED_MORE;
-}
-
-/**
- * Process certificate
- */
-static status_t process_certificate(private_tls_server_t *this,
- tls_reader_t *reader)
-{
- certificate_t *cert;
- tls_reader_t *certs;
- chunk_t data;
- bool first = TRUE;
-
- this->crypto->append_handshake(this->crypto,
- TLS_CERTIFICATE, reader->peek(reader));
-
- if (!reader->read_data24(reader, &data))
- {
- return FAILED;
- }
- certs = tls_reader_create(data);
- while (certs->remaining(certs))
- {
- if (!certs->read_data24(certs, &data))
- {
- certs->destroy(certs);
- return FAILED;
- }
- cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
- BUILD_BLOB_ASN1_DER, data, BUILD_END);
- if (cert)
- {
- if (first)
- {
- this->peer_auth->add(this->peer_auth,
- AUTH_HELPER_SUBJECT_CERT, cert);
- DBG1(DBG_IKE, "received TLS peer certificate '%Y'",
- cert->get_subject(cert));
- first = FALSE;
- }
- else
- {
- DBG1(DBG_IKE, "received TLS intermediate certificate '%Y'",
- cert->get_subject(cert));
- this->peer_auth->add(this->peer_auth, AUTH_HELPER_IM_CERT, cert);
- }
- }
- else
- {
- DBG1(DBG_IKE, "parsing TLS certificate failed, skipped");
- }
- }
- certs->destroy(certs);
- this->state = STATE_CERT_RECEIVED;
- return NEED_MORE;
-}
-
-/**
- * Process Client Key Exchange
- */
-static status_t process_key_exchange(private_tls_server_t *this,
- tls_reader_t *reader)
-{
- chunk_t encrypted, premaster;
-
- this->crypto->append_handshake(this->crypto,
- TLS_CLIENT_KEY_EXCHANGE, reader->peek(reader));
-
- if (!reader->read_data16(reader, &encrypted))
- {
- DBG1(DBG_IKE, "received invalid Client Key Exchange");
- return FAILED;
- }
-
- if (!this->private ||
- !this->private->decrypt(this->private, encrypted, &premaster))
- {
- DBG1(DBG_IKE, "decrypting Client Key Exchange data failed");
- return FAILED;
- }
- this->crypto->derive_secrets(this->crypto, premaster,
- chunk_from_thing(this->client_random),
- chunk_from_thing(this->server_random));
- chunk_clear(&premaster);
-
- this->state = STATE_KEY_EXCHANGE_RECEIVED;
- return NEED_MORE;
-}
-
-/**
- * Process Certificate verify
- */
-static status_t process_cert_verify(private_tls_server_t *this,
- tls_reader_t *reader)
-{
- bool verified = FALSE;
- enumerator_t *enumerator;
- public_key_t *public;
- auth_cfg_t *auth;
- tls_reader_t *sig;
-
- enumerator = lib->credmgr->create_public_enumerator(lib->credmgr,
- KEY_ANY, this->peer, this->peer_auth);
- while (enumerator->enumerate(enumerator, &public, &auth))
- {
- sig = tls_reader_create(reader->peek(reader));
- verified = this->crypto->verify_handshake(this->crypto, public, sig);
- sig->destroy(sig);
- if (verified)
- {
- break;
- }
- DBG1(DBG_IKE, "signature verification failed, trying another key");
- }
- enumerator->destroy(enumerator);
-
- if (!verified)
- {
- DBG1(DBG_IKE, "no trusted certificate found for '%Y' to verify TLS peer",
- this->peer);
- return FAILED;
- }
-
- this->crypto->append_handshake(this->crypto,
- TLS_CERTIFICATE_VERIFY, reader->peek(reader));
- this->state = STATE_CERT_VERIFY_RECEIVED;
- return NEED_MORE;
-}
-
-/**
- * Process finished message
- */
-static status_t process_finished(private_tls_server_t *this,
- tls_reader_t *reader)
-{
- chunk_t received;
- char buf[12];
-
- if (!reader->read_data(reader, sizeof(buf), &received))
- {
- DBG1(DBG_IKE, "received client finished too short");
- return FAILED;
- }
- if (!this->crypto->calculate_finished(this->crypto, "client finished", buf))
- {
- DBG1(DBG_IKE, "calculating client finished failed");
- return FAILED;
- }
- if (!chunk_equals(received, chunk_from_thing(buf)))
- {
- DBG1(DBG_IKE, "received client finished invalid");
- return FAILED;
- }
-
- this->crypto->append_handshake(this->crypto, TLS_FINISHED, received);
- this->state = STATE_FINISHED_RECEIVED;
- return NEED_MORE;
-}
-
-METHOD(tls_handshake_t, process, status_t,
- private_tls_server_t *this, tls_handshake_type_t type, tls_reader_t *reader)
-{
- tls_handshake_type_t expected;
-
- switch (this->state)
- {
- case STATE_INIT:
- if (type == TLS_CLIENT_HELLO)
- {
- return process_client_hello(this, reader);
- }
- expected = TLS_CLIENT_HELLO;
- break;
- case STATE_HELLO_DONE:
- if (type == TLS_CERTIFICATE)
- {
- return process_certificate(this, reader);
- }
- expected = TLS_CERTIFICATE;
- break;
- case STATE_CERT_RECEIVED:
- if (type == TLS_CLIENT_KEY_EXCHANGE)
- {
- return process_key_exchange(this, reader);
- }
- expected = TLS_CLIENT_KEY_EXCHANGE;
- break;
- case STATE_KEY_EXCHANGE_RECEIVED:
- if (type == TLS_CERTIFICATE_VERIFY)
- {
- return process_cert_verify(this, reader);
- }
- expected = TLS_CERTIFICATE_VERIFY;
- break;
- case STATE_CIPHERSPEC_CHANGED_IN:
- if (type == TLS_FINISHED)
- {
- return process_finished(this, reader);
- }
- expected = TLS_FINISHED;
- break;
- default:
- DBG1(DBG_IKE, "TLS %N not expected in current state",
- tls_handshake_type_names, type);
- return FAILED;
- }
- DBG1(DBG_IKE, "TLS %N expected, but received %N",
- tls_handshake_type_names, expected, tls_handshake_type_names, type);
- return FAILED;
-}
-
-/**
- * Send ServerHello message
- */
-static status_t send_server_hello(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
-{
- rng_t *rng;
-
- htoun32(&this->server_random, time(NULL));
- rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- if (!rng)
- {
- return FAILED;
- }
- rng->get_bytes(rng, sizeof(this->server_random) - 4, this->server_random + 4);
- rng->destroy(rng);
-
- writer->write_uint16(writer, this->tls->get_version(this->tls));
- writer->write_data(writer, chunk_from_thing(this->server_random));
- /* session identifier => none, we don't support session resumption */
- writer->write_data8(writer, chunk_empty);
- /* add selected suite */
- writer->write_uint16(writer, this->suite);
- /* NULL compression only */
- writer->write_uint8(writer, 0);
-
- *type = TLS_SERVER_HELLO;
- this->state = STATE_HELLO_SENT;
- this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
- return NEED_MORE;
-}
-
-/**
- * Send Certificate
- */
-static status_t send_certificate(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
-{
- enumerator_t *enumerator;
- certificate_t *cert;
- auth_rule_t rule;
- tls_writer_t *certs;
- chunk_t data;
-
- this->private = lib->credmgr->get_private(lib->credmgr,
- KEY_ANY, this->server, this->server_auth);
- if (!this->private)
- {
- DBG1(DBG_IKE, "no TLS server certificate found for '%Y'", this->server);
- return FAILED;
- }
-
- /* generate certificate payload */
- certs = tls_writer_create(256);
- cert = this->server_auth->get(this->server_auth, AUTH_RULE_SUBJECT_CERT);
- if (cert)
- {
- if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
- {
- DBG1(DBG_IKE, "sending TLS server certificate '%Y'",
- cert->get_subject(cert));
- certs->write_data24(certs, data);
- free(data.ptr);
- }
- }
- enumerator = this->server_auth->create_enumerator(this->server_auth);
- while (enumerator->enumerate(enumerator, &rule, &cert))
- {
- if (rule == AUTH_RULE_IM_CERT)
- {
- if (cert->get_encoding(cert, CERT_ASN1_DER, &data))
- {
- DBG1(DBG_IKE, "sending TLS intermediate certificate '%Y'",
- cert->get_subject(cert));
- certs->write_data24(certs, data);
- free(data.ptr);
- }
- }
- }
- enumerator->destroy(enumerator);
-
- writer->write_data24(writer, certs->get_buf(certs));
- certs->destroy(certs);
-
- *type = TLS_CERTIFICATE;
- this->state = STATE_CERT_SENT;
- this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
- return NEED_MORE;
-}
-
-/**
- * Send Certificate Request
- */
-static status_t send_certificate_request(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
-{
- tls_writer_t *authorities;
- enumerator_t *enumerator;
- certificate_t *cert;
- identification_t *id;
-
- /* currently only RSA signatures are supported */
- writer->write_data8(writer, chunk_from_chars(1));
- if (this->tls->get_version(this->tls) >= TLS_1_2)
- {
- /* enforce RSA with SHA1 signatures */
- writer->write_data16(writer, chunk_from_chars(2, 1));
- }
-
- authorities = tls_writer_create(64);
- enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
- CERT_X509, KEY_RSA, NULL, TRUE);
- while (enumerator->enumerate(enumerator, &cert))
- {
- id = cert->get_subject(cert);
- authorities->write_data16(authorities, id->get_encoding(id));
- }
- enumerator->destroy(enumerator);
- writer->write_data16(writer, authorities->get_buf(authorities));
- authorities->destroy(authorities);
-
- *type = TLS_CERTIFICATE_REQUEST;
- this->state = STATE_CERTREQ_SENT;
- this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
- return NEED_MORE;
-}
-
-/**
- * Send Hello Done
- */
-static status_t send_hello_done(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
-{
- *type = TLS_SERVER_HELLO_DONE;
- this->state = STATE_HELLO_DONE;
- this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer));
- return NEED_MORE;
-}
-
-/**
- * Send Finished
- */
-static status_t send_finished(private_tls_server_t *this,
- tls_handshake_type_t *type, tls_writer_t *writer)
-{
- char buf[12];
-
- if (!this->crypto->calculate_finished(this->crypto, "server finished", buf))
- {
- DBG1(DBG_IKE, "calculating server finished data failed");
- return FAILED;
- }
-
- writer->write_data(writer, chunk_from_thing(buf));
-
- *type = TLS_FINISHED;
- this->state = STATE_FINISHED_SENT;
- this->crypto->derive_eap_msk(this->crypto,
- chunk_from_thing(this->client_random),
- chunk_from_thing(this->server_random));
- return NEED_MORE;
-}
-
-METHOD(tls_handshake_t, build, status_t,
- private_tls_server_t *this, tls_handshake_type_t *type, tls_writer_t *writer)
-{
- switch (this->state)
- {
- case STATE_HELLO_RECEIVED:
- return send_server_hello(this, type, writer);
- case STATE_HELLO_SENT:
- return send_certificate(this, type, writer);
- case STATE_CERT_SENT:
- return send_certificate_request(this, type, writer);
- case STATE_CERTREQ_SENT:
- return send_hello_done(this, type, writer);
- case STATE_CIPHERSPEC_CHANGED_OUT:
- return send_finished(this, type, writer);
- case STATE_FINISHED_SENT:
- return INVALID_STATE;
- default:
- return INVALID_STATE;
- }
-}
-
-METHOD(tls_handshake_t, cipherspec_changed, bool,
- private_tls_server_t *this)
-{
- if (this->state == STATE_FINISHED_RECEIVED)
- {
- this->crypto->change_cipher(this->crypto, FALSE);
- this->state = STATE_CIPHERSPEC_CHANGED_OUT;
- return TRUE;
- }
- return FALSE;
-}
-
-METHOD(tls_handshake_t, change_cipherspec, bool,
- private_tls_server_t *this)
-{
- if (this->state == STATE_CERT_VERIFY_RECEIVED)
- {
- this->crypto->change_cipher(this->crypto, TRUE);
- this->state = STATE_CIPHERSPEC_CHANGED_IN;
- return TRUE;
- }
- return FALSE;
-}
-
-METHOD(tls_handshake_t, destroy, void,
- private_tls_server_t *this)
-{
- DESTROY_IF(this->private);
- this->peer_auth->destroy(this->peer_auth);
- this->server_auth->destroy(this->server_auth);
- free(this);
-}
-
-/**
- * See header
- */
-tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto,
- identification_t *server, identification_t *peer)
-{
- private_tls_server_t *this;
-
- INIT(this,
- .public.handshake = {
- .process = _process,
- .build = _build,
- .cipherspec_changed = _cipherspec_changed,
- .change_cipherspec = _change_cipherspec,
- .destroy = _destroy,
- },
- .tls = tls,
- .crypto = crypto,
- .server = server,
- .peer = peer,
- .state = STATE_INIT,
- .peer_auth = auth_cfg_create(),
- .server_auth = auth_cfg_create(),
- );
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_server.h b/src/libcharon/plugins/eap_tls/tls/tls_server.h
deleted file mode 100644
index 3fddea225..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_server.h
+++ /dev/null
@@ -1,48 +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.
- */
-
-/**
- * @defgroup tls_server tls_server
- * @{ @ingroup tls
- */
-
-#ifndef TLS_SERVER_H_
-#define TLS_SERVER_H_
-
-typedef struct tls_server_t tls_server_t;
-
-#include "tls_handshake.h"
-#include "tls_crypto.h"
-
-#include <library.h>
-
-/**
- * TLS handshake protocol handler as peer.
- */
-struct tls_server_t {
-
- /**
- * Implements the TLS handshake protocol handler.
- */
- tls_handshake_t handshake;
-};
-
-/**
- * Create a tls_server instance.
- */
-tls_server_t *tls_server_create(tls_t *tls, tls_crypto_t *crypto,
- identification_t *server, identification_t *peer);
-
-#endif /** TLS_SERVER_H_ @}*/
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_writer.c b/src/libcharon/plugins/eap_tls/tls/tls_writer.c
deleted file mode 100644
index f1d9d790e..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_writer.c
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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_writer.h"
-
-typedef struct private_tls_writer_t private_tls_writer_t;
-
-/**
- * Private data of an tls_writer_t object.
- */
-struct private_tls_writer_t {
-
- /**
- * Public tls_writer_t interface.
- */
- tls_writer_t public;
-
- /**
- * Allocated buffer
- */
- chunk_t buf;
-
- /**
- * Used bytes in buffer
- */
- size_t used;
-
- /**
- * Number of bytes to increase buffer size
- */
- size_t increase;
-};
-
-/**
- * Increase buffer size
- */
-static void increase(private_tls_writer_t *this)
-{
- this->buf.len += this->increase;
- this->buf.ptr = realloc(this->buf.ptr, this->buf.len);
-}
-
-METHOD(tls_writer_t, write_uint8, void,
- private_tls_writer_t *this, u_int8_t value)
-{
- if (this->used + 1 > this->buf.len)
- {
- increase(this);
- }
- this->buf.ptr[this->used] = value;
- this->used += 1;
-}
-
-METHOD(tls_writer_t, write_uint16, void,
- private_tls_writer_t *this, u_int16_t value)
-{
- if (this->used + 2 > this->buf.len)
- {
- increase(this);
- }
- htoun16(this->buf.ptr + this->used, value);
- this->used += 2;
-}
-
-METHOD(tls_writer_t, write_uint24, void,
- private_tls_writer_t *this, u_int32_t value)
-{
- if (this->used + 3 > this->buf.len)
- {
- increase(this);
- }
- value = htonl(value);
- memcpy(this->buf.ptr + this->used, ((char*)&value) + 1, 3);
- this->used += 3;
-}
-
-METHOD(tls_writer_t, write_uint32, void,
- private_tls_writer_t *this, u_int32_t value)
-{
- if (this->used + 4 > this->buf.len)
- {
- increase(this);
- }
- htoun32(this->buf.ptr + this->used, value);
- this->used += 4;
-}
-
-METHOD(tls_writer_t, write_data, void,
- private_tls_writer_t *this, chunk_t value)
-{
- while (this->used + value.len > this->buf.len)
- {
- increase(this);
- }
- memcpy(this->buf.ptr + this->used, value.ptr, value.len);
- this->used += value.len;
-}
-
-METHOD(tls_writer_t, write_data8, void,
- private_tls_writer_t *this, chunk_t value)
-{
- write_uint8(this, value.len);
- write_data(this, value);
-}
-
-METHOD(tls_writer_t, write_data16, void,
- private_tls_writer_t *this, chunk_t value)
-{
- write_uint16(this, value.len);
- write_data(this, value);
-}
-
-METHOD(tls_writer_t, write_data24, void,
- private_tls_writer_t *this, chunk_t value)
-{
- write_uint24(this, value.len);
- write_data(this, value);
-}
-
-METHOD(tls_writer_t, write_data32, void,
- private_tls_writer_t *this, chunk_t value)
-{
- write_uint32(this, value.len);
- write_data(this, value);
-}
-
-METHOD(tls_writer_t, wrap8, void,
- private_tls_writer_t *this)
-{
- if (this->used + 1 > this->buf.len)
- {
- increase(this);
- }
- memmove(this->buf.ptr + 1, this->buf.ptr, 1);
- this->buf.ptr[0] = this->used;
- this->used += 1;
-}
-
-METHOD(tls_writer_t, wrap16, void,
- private_tls_writer_t *this)
-{
- if (this->used + 2 > this->buf.len)
- {
- increase(this);
- }
- memmove(this->buf.ptr + 2, this->buf.ptr, 2);
- htoun16(this->buf.ptr, this->used);
- this->used += 2;
-}
-
-METHOD(tls_writer_t, wrap24, void,
- private_tls_writer_t *this)
-{
- u_int32_t len;
-
- if (this->used + 3 > this->buf.len)
- {
- increase(this);
- }
- memmove(this->buf.ptr + 3, this->buf.ptr, 3);
-
- len = htonl(this->used);
- memcpy(this->buf.ptr, ((char*)&len) + 1, 3);
- this->used += 3;
-}
-
-METHOD(tls_writer_t, wrap32, void,
- private_tls_writer_t *this)
-{
- if (this->used + 4 > this->buf.len)
- {
- increase(this);
- }
- memmove(this->buf.ptr + 4, this->buf.ptr, 4);
- htoun32(this->buf.ptr, this->used);
- this->used += 4;
-}
-
-METHOD(tls_writer_t, get_buf, chunk_t,
- private_tls_writer_t *this)
-{
- return chunk_create(this->buf.ptr, this->used);
-}
-
-METHOD(tls_writer_t, destroy, void,
- private_tls_writer_t *this)
-{
- free(this->buf.ptr);
- free(this);
-}
-
-/**
- * See header
- */
-tls_writer_t *tls_writer_create(u_int32_t bufsize)
-{
- private_tls_writer_t *this;
-
- INIT(this,
- .public = {
- .write_uint8 = _write_uint8,
- .write_uint16 = _write_uint16,
- .write_uint24 = _write_uint24,
- .write_uint32 = _write_uint32,
- .write_data = _write_data,
- .write_data8 = _write_data8,
- .write_data16 = _write_data16,
- .write_data24 = _write_data24,
- .write_data32 = _write_data32,
- .wrap8 = _wrap8,
- .wrap16 = _wrap16,
- .wrap24 = _wrap24,
- .wrap32 = _wrap32,
- .get_buf = _get_buf,
- .destroy = _destroy,
- },
- .increase = bufsize ?: 32,
- );
- if (bufsize)
- {
- this->buf = chunk_alloc(bufsize);
- }
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_tls/tls/tls_writer.h b/src/libcharon/plugins/eap_tls/tls/tls_writer.h
deleted file mode 100644
index ce8ba6a6e..000000000
--- a/src/libcharon/plugins/eap_tls/tls/tls_writer.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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.
- */
-
-/**
- * @defgroup tls_writer tls_writer
- * @{ @ingroup tls
- */
-
-#ifndef TLS_WRITER_H_
-#define TLS_WRITER_H_
-
-typedef struct tls_writer_t tls_writer_t;
-
-#include <library.h>
-
-/**
- * TLS record generator.
- */
-struct tls_writer_t {
-
- /**
- * Append a 8-bit integer to the buffer.
- *
- * @param value value to append
- */
- void (*write_uint8)(tls_writer_t *this, u_int8_t value);
-
- /**
- * Append a 16-bit integer to the buffer.
- *
- * @param value value to append
- */
- void (*write_uint16)(tls_writer_t *this, u_int16_t value);
-
- /**
- * Append a 24-bit integer to the buffer.
- *
- * @param value value to append
- */
- void (*write_uint24)(tls_writer_t *this, u_int32_t value);
-
- /**
- * Append a 32-bit integer to the buffer.
- *
- * @param value value to append
- */
- void (*write_uint32)(tls_writer_t *this, u_int32_t value);
-
- /**
- * Append a chunk of data without a length header.
- *
- * @param value value to append
- */
- void (*write_data)(tls_writer_t *this, chunk_t value);
-
- /**
- * Append a chunk of data with a 16-bit length header.
- *
- * @param value value to append
- */
- void (*write_data8)(tls_writer_t *this, chunk_t value);
-
- /**
- * Append a chunk of data with a 8-bit length header.
- *
- * @param value value to append
- */
- void (*write_data16)(tls_writer_t *this, chunk_t value);
-
- /**
- * Append a chunk of data with a 24-bit length header.
- *
- * @param value value to append
- */
- void (*write_data24)(tls_writer_t *this, chunk_t value);
-
- /**
- * Append a chunk of data with a 32-bit length header.
- *
- * @param value value to append
- */
- void (*write_data32)(tls_writer_t *this, chunk_t value);
-
- /**
- * Prepend a 8-bit length header to existing data.
- */
- void (*wrap8)(tls_writer_t *this);
-
- /**
- * Prepend a 16-bit length header to existing data.
- */
- void (*wrap16)(tls_writer_t *this);
-
- /**
- * Prepend a 24-bit length header to existing data.
- */
- void (*wrap24)(tls_writer_t *this);
-
- /**
- * Prepend a 32-bit length header to existing data.
- */
- void (*wrap32)(tls_writer_t *this);
-
- /**
- * Get the encoded data buffer.
- *
- * @return chunk to internal buffer
- */
- chunk_t (*get_buf)(tls_writer_t *this);
-
- /**
- * Destroy a tls_writer_t.
- */
- void (*destroy)(tls_writer_t *this);
-};
-
-/**
- * Create a tls_writer instance.
- *
- * @param bufsize initially allocated buffer size
- */
-tls_writer_t *tls_writer_create(u_int32_t bufsize);
-
-#endif /** TLS_WRITER_H_ @}*/