aboutsummaryrefslogtreecommitdiffstats
path: root/src/libtls/tls_server.c
diff options
context:
space:
mode:
authorMartin Willi <martin@revosec.ch>2010-09-03 12:50:18 +0200
committerMartin Willi <martin@revosec.ch>2010-09-03 14:54:43 +0200
commit4cdade5aaecf7c03bc68ede05877ff04eef665fc (patch)
treeb8244f3908d4f588a02cd8ab8c8629b016cb53cd /src/libtls/tls_server.c
parent37a59a8fbfc6f3203ecf79d9294fc10af981baf0 (diff)
downloadstrongswan-4cdade5aaecf7c03bc68ede05877ff04eef665fc.tar.bz2
strongswan-4cdade5aaecf7c03bc68ede05877ff04eef665fc.tar.xz
Select private key based on received cipher suites
Diffstat (limited to 'src/libtls/tls_server.c')
-rw-r--r--src/libtls/tls_server.c66
1 files changed, 54 insertions, 12 deletions
diff --git a/src/libtls/tls_server.c b/src/libtls/tls_server.c
index 1c1c962f1..e965553eb 100644
--- a/src/libtls/tls_server.c
+++ b/src/libtls/tls_server.c
@@ -137,6 +137,58 @@ struct private_tls_server_t {
};
/**
+ * Find a cipher suite and a server key
+ */
+static bool select_suite_and_key(private_tls_server_t *this,
+ tls_cipher_suite_t *suites, int count)
+{
+ private_key_t *key;
+ key_type_t type;
+
+ key = lib->credmgr->get_private(lib->credmgr, KEY_ANY, this->server,
+ this->server_auth);
+ if (!key)
+ {
+ DBG1(DBG_TLS, "no usable TLS server certificate found for '%Y'",
+ this->server);
+ return FALSE;
+ }
+ this->suite = this->crypto->select_cipher_suite(this->crypto,
+ suites, count, key->get_type(key));
+ if (!this->suite)
+ { /* no match for this key, try to find another type */
+ if (key->get_type(key) == KEY_ECDSA)
+ {
+ type = KEY_RSA;
+ }
+ else
+ {
+ type = KEY_ECDSA;
+ }
+ key->destroy(key);
+
+ this->suite = this->crypto->select_cipher_suite(this->crypto,
+ suites, count, type);
+ if (!this->suite)
+ {
+ DBG1(DBG_TLS, "received cipher suites inacceptable");
+ return FALSE;
+ }
+ this->server_auth->destroy(this->server_auth);
+ this->server_auth = auth_cfg_create();
+ key = lib->credmgr->get_private(lib->credmgr, type, this->server,
+ this->server_auth);
+ if (!key)
+ {
+ DBG1(DBG_TLS, "received cipher suites inacceptable");
+ return FALSE;
+ }
+ }
+ this->private = key;
+ return TRUE;
+}
+
+/**
* Process client hello message
*/
static status_t process_client_hello(private_tls_server_t *this,
@@ -216,10 +268,9 @@ static status_t process_client_hello(private_tls_server_t *this,
suites[i] = untoh16(&ciphers.ptr[i * sizeof(u_int16_t)]);
DBG2(DBG_TLS, " %N", tls_cipher_suite_names, suites[i]);
}
- this->suite = this->crypto->select_cipher_suite(this->crypto, suites, count);
- if (!this->suite)
+
+ if (!select_suite_and_key(this, suites, count))
{
- DBG1(DBG_TLS, "received cipher suites inacceptable");
this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE);
return NEED_MORE;
}
@@ -603,15 +654,6 @@ static status_t send_certificate(private_tls_server_t *this,
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_TLS, "no TLS server certificate found for '%Y'", this->server);
- this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR);
- return FAILED;
- }
-
/* generate certificate payload */
certs = tls_writer_create(256);
cert = this->server_auth->get(this->server_auth, AUTH_RULE_SUBJECT_CERT);