diff options
author | lloyd <[email protected]> | 2012-01-24 16:42:18 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-01-24 16:42:18 +0000 |
commit | e4eb73dca7d7a74ecf8ef792d65640c4e44e2ab1 (patch) | |
tree | 5e7cd62ff1fe191c0369a41617b43ebf77d20ef9 /src/tls/tls_server.cpp | |
parent | b8a8ba0428cd4235e1ac2ba8530e8f817a166773 (diff) |
We can now actually handle multiple certificate types in the server
and will choose one depending on which ciphersuites the client
offered.
Diffstat (limited to 'src/tls/tls_server.cpp')
-rw-r--r-- | src/tls/tls_server.cpp | 48 |
1 files changed, 31 insertions, 17 deletions
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index 207d40990..8aff79793 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -1,6 +1,6 @@ /* * TLS Server -* (C) 2004-2011 Jack Lloyd +* (C) 2004-2011,2012 Jack Lloyd * * Released under the terms of the Botan license */ @@ -11,6 +11,7 @@ #include <botan/internal/stl_util.h> #include <botan/dh.h> #include <botan/ecdh.h> +#include <memory> namespace Botan { @@ -218,23 +219,27 @@ void Server::process_handshake_msg(Handshake_Type type, } else // new session { - std::vector<X509_Certificate> server_certs = - creds.cert_chain("", - "tls-server", - m_hostname); + std::map<std::string, std::vector<X509_Certificate> > cert_chains; - Private_Key* private_key = - server_certs.empty() ? 0 : - (creds.private_key_for(server_certs[0], - "tls-server", - m_hostname)); + cert_chains["RSA"] = creds.cert_chain_single_type("RSA", "tls-server", m_hostname); + cert_chains["DSA"] = creds.cert_chain_single_type("DSA", "tls-server", m_hostname); + cert_chains["ECDSA"] = creds.cert_chain_single_type("ECDSA", "tls-server", m_hostname); + + std::vector<std::string> available_cert_types; + + for(std::map<std::string, std::vector<X509_Certificate> >::const_iterator i = cert_chains.begin(); + i != cert_chains.end(); ++i) + { + if(!i->second.empty()) + available_cert_types.push_back(i->first); + } state->server_hello = new Server_Hello( writer, state->hash, state->version, *(state->client_hello), - server_certs, + available_cert_types, policy, secure_renegotiation.supported(), secure_renegotiation.for_server_hello(), @@ -250,19 +255,28 @@ void Server::process_handshake_msg(Handshake_Type type, state->suite = Ciphersuite::lookup_ciphersuite(state->server_hello->ciphersuite()); - if(state->suite.sig_algo() != "") + const std::string sig_algo = state->suite.sig_algo(); + const std::string kex_algo = state->suite.kex_algo(); + + std::auto_ptr<Private_Key> private_key(0); + + if(sig_algo != "") { state->server_certs = new Certificate(writer, state->hash, - server_certs); - } + cert_chains[sig_algo]); - const std::string kex_algo = state->suite.kex_algo(); + private_key.reset(creds.private_key_for(state->server_certs->cert_chain()[0], + "tls-server", + m_hostname)); + } if(kex_algo != "") { if(kex_algo == "DH") + { state->kex_priv = new DH_PrivateKey(rng, policy.dh_group()); + } else if(kex_algo == "ECDH") { const std::vector<std::string>& curves = @@ -284,10 +298,10 @@ void Server::process_handshake_msg(Handshake_Type type, kex_algo); state->server_kex = - new Server_Key_Exchange(writer, state, rng, private_key); + new Server_Key_Exchange(writer, state, rng, private_key.get()); } else - state->kex_priv = PKCS8::copy_key(*private_key, rng); + state->kex_priv = private_key.release(); std::vector<X509_Certificate> client_auth_CAs = creds.trusted_certificate_authorities("tls-server", m_hostname); |