aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-01-03 14:18:03 +0000
committerlloyd <[email protected]>2012-01-03 14:18:03 +0000
commit5c00cc7305718fe209757142f7a43b711cccd8f9 (patch)
tree560b225a66b06682d16182c5f0c57988242c8d48 /src
parent52868a93300a3b7e8666c49ccc786e6dba66438e (diff)
Add Credentials_Manager which is an interface to something that knows
what certs, keys, etc are available to the app. Needs polishing but it seems like it should be sound.
Diffstat (limited to 'src')
-rw-r--r--src/cert/x509cert/x509cert.cpp18
-rw-r--r--src/cert/x509cert/x509cert.h6
-rw-r--r--src/credentials/credentials_manager.cpp51
-rw-r--r--src/credentials/credentials_manager.h78
-rw-r--r--src/credentials/info.txt1
-rw-r--r--src/tls/hello.cpp3
-rw-r--r--src/tls/tls_client.cpp45
-rw-r--r--src/tls/tls_client.h17
-rw-r--r--src/tls/tls_magic.h3
-rw-r--r--src/tls/tls_messages.h1
-rw-r--r--src/tls/tls_server.cpp36
-rw-r--r--src/tls/tls_server.h16
12 files changed, 202 insertions, 73 deletions
diff --git a/src/cert/x509cert/x509cert.cpp b/src/cert/x509cert/x509cert.cpp
index 7d9370f2a..88aeebd77 100644
--- a/src/cert/x509cert/x509cert.cpp
+++ b/src/cert/x509cert/x509cert.cpp
@@ -296,6 +296,24 @@ bool X509_Certificate::operator==(const X509_Certificate& other) const
subject == other.subject);
}
+bool X509_Certificate::operator<(const X509_Certificate& other) const
+ {
+ /* If signature values are not equal, sort by lexicographic ordering of that */
+ if(sig != other.sig)
+ {
+ if(sig < other.sig)
+ return true;
+ return false;
+ }
+
+ /*
+ * same signatures, highly unlikely case, revert to compare
+ * of entire contents
+ */
+
+ return to_string() < other.to_string();
+ }
+
/*
* X.509 Certificate Comparison
*/
diff --git a/src/cert/x509cert/x509cert.h b/src/cert/x509cert/x509cert.h
index 8798ef1c2..cd49aa02f 100644
--- a/src/cert/x509cert/x509cert.h
+++ b/src/cert/x509cert/x509cert.h
@@ -152,6 +152,12 @@ class BOTAN_DLL X509_Certificate : public X509_Object
bool operator==(const X509_Certificate& other) const;
/**
+ * Impose an arbitrary (but consistent) ordering
+ * @return true if this is less than other by some unspecified criteria
+ */
+ bool operator<(const X509_Certificate& other) const;
+
+ /**
* Create a certificate from a data source providing the DER or
* PEM encoded certificate.
* @param source the data source
diff --git a/src/credentials/credentials_manager.cpp b/src/credentials/credentials_manager.cpp
new file mode 100644
index 000000000..46d9e300c
--- /dev/null
+++ b/src/credentials/credentials_manager.cpp
@@ -0,0 +1,51 @@
+/*
+* Credentials Manager
+* (C) 2011,2012 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/credentials_manager.h>
+
+namespace Botan {
+
+std::string Credentials_Manager::srp_identifier(const std::string& type,
+ const std::string& context)
+ {
+ return "";
+ }
+
+std::string Credentials_Manager::srp_password(const std::string& identifier,
+ const std::string& type,
+ const std::string& context)
+ {
+ return "";
+ }
+
+bool Credentials_Manager::srp_verifier(const std::string& identifier,
+ const std::string& type,
+ const std::string& context,
+ BigInt& group_prime,
+ BigInt& group_generator,
+ BigInt& verifier,
+ MemoryRegion<byte>& salt)
+ {
+ return false;
+ }
+
+std::vector<X509_Certificate> Credentials_Manager::cert_chain(
+ const std::string& cert_key_type,
+ const std::string& type,
+ const std::string& context)
+ {
+ return std::vector<X509_Certificate>();
+ }
+
+Private_Key* Credentials_Manager::private_key_for(const X509_Certificate& cert,
+ const std::string& type,
+ const std::string& context)
+ {
+ return 0;
+ }
+
+}
diff --git a/src/credentials/credentials_manager.h b/src/credentials/credentials_manager.h
new file mode 100644
index 000000000..a54b2ec31
--- /dev/null
+++ b/src/credentials/credentials_manager.h
@@ -0,0 +1,78 @@
+/*
+* Credentials Manager
+* (C) 2011,2012 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_CREDENTIALS_MANAGER_H__
+#define BOTAN_CREDENTIALS_MANAGER_H__
+
+#include <botan/x509cert.h>
+#include <botan/secmem.h>
+#include <string>
+
+namespace Botan {
+
+class BigInt;
+
+/**
+* Interface for a credentials manager.
+*
+* A type is a fairly static value that represents the general nature
+* of the transaction occuring. Currently defined are "tls-client" and
+* "tls-server". Context represents a hostname, email address,
+* username, or other identifier.
+*/
+class BOTAN_DLL Credentials_Manager
+ {
+ public:
+ virtual ~Credentials_Manager() {}
+
+ /**
+ * @return identifier for client-side SRP auth, if available
+ for this type/context
+ */
+ virtual std::string srp_identifier(const std::string& type,
+ const std::string& context);
+
+ /**
+ * @return password for client-side SRP auth, if available
+ for this identifier/type/context
+ */
+ virtual std::string srp_password(const std::string& identifier,
+ const std::string& type,
+ const std::string& context);
+
+ /**
+ * @todo add option for faking verifier if identifier is unknown
+ */
+ virtual bool srp_verifier(const std::string& identifier,
+ const std::string& type,
+ const std::string& context,
+ BigInt& group_prime,
+ BigInt& group_generator,
+ BigInt& verifier,
+ MemoryRegion<byte>& salt);
+
+ /**
+ * @param cert_key_type is a string representing the key type
+ * ("RSA", "DSA", "ECDSA") or empty if no preference.
+ */
+ virtual std::vector<X509_Certificate> cert_chain(
+ const std::string& cert_key_type,
+ const std::string& type,
+ const std::string& context);
+
+ /**
+ * @return private key associated with this certificate if we should
+ * use it with this context
+ */
+ virtual Private_Key* private_key_for(const X509_Certificate& cert,
+ const std::string& type,
+ const std::string& context);
+ };
+
+}
+
+#endif
diff --git a/src/credentials/info.txt b/src/credentials/info.txt
new file mode 100644
index 000000000..f6dcdd64d
--- /dev/null
+++ b/src/credentials/info.txt
@@ -0,0 +1 @@
+define CREDENTIALS_MANAGER
diff --git a/src/tls/hello.cpp b/src/tls/hello.cpp
index 49115fd62..17a624381 100644
--- a/src/tls/hello.cpp
+++ b/src/tls/hello.cpp
@@ -282,10 +282,9 @@ Server_Hello::Server_Hello(Record_Writer& writer,
const MemoryRegion<byte>& reneg_info,
const std::vector<X509_Certificate>& certs,
const Client_Hello& c_hello,
- const MemoryRegion<byte>& session_id,
Version_Code ver) :
s_version(ver),
- sess_id(session_id),
+ sess_id(rng.random_vec(32)),
s_random(rng.random_vec(32)),
m_fragment_size(c_hello.fragment_size()),
has_secure_renegotiation(client_has_secure_renegotiation),
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index 1d9554ee8..b7249081b 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -22,21 +22,23 @@ TLS_Client::TLS_Client(std::tr1::function<void (const byte[], size_t)> output_fn
std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
std::tr1::function<void (const TLS_Session&)> handshake_fn,
TLS_Session_Manager& session_manager,
+ Credentials_Manager& creds,
const TLS_Policy& policy,
RandomNumberGenerator& rng,
- const std::string& hostname,
- const std::string& srp_identifier,
- const std::string& srp_password) :
+ const std::string& hostname) :
TLS_Channel(output_fn, proc_fn, handshake_fn),
policy(policy),
rng(rng),
- session_manager(session_manager)
+ session_manager(session_manager),
+ creds(creds)
{
writer.set_version(SSL_V3);
state = new Handshake_State;
state->set_expected_next(SERVER_HELLO);
+ const std::string srp_identifier = creds.srp_identifier("tls-client", hostname);
+
if(hostname != "")
{
TLS_Session session_info;
@@ -70,21 +72,6 @@ TLS_Client::TLS_Client(std::tr1::function<void (const byte[], size_t)> output_fn
secure_renegotiation.update(state->client_hello);
}
-void TLS_Client::add_client_cert(const X509_Certificate& cert,
- Private_Key* cert_key)
- {
- certs.push_back(std::make_pair(cert, cert_key));
- }
-
-/*
-* TLS Client Destructor
-*/
-TLS_Client::~TLS_Client()
- {
- for(size_t i = 0; i != certs.size(); i++)
- delete certs[i].second;
- }
-
/*
* Send a new client hello to renegotiate
*/
@@ -308,17 +295,19 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
state->server_hello_done = new Server_Hello_Done(contents);
- std::vector<X509_Certificate> send_certs;
-
if(state->received_handshake_msg(CERTIFICATE_REQUEST))
{
std::vector<Certificate_Type> types =
state->cert_req->acceptable_types();
- // FIXME: Fill in useful certs here, if any
+ std::vector<X509_Certificate> client_certs =
+ creds.cert_chain("", // use types here
+ "tls-client",
+ state->client_hello->sni_hostname());
+
state->client_certs = new Certificate(writer,
state->hash,
- send_certs);
+ client_certs);
}
state->client_kex =
@@ -327,11 +316,15 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
state->client_hello->version());
if(state->received_handshake_msg(CERTIFICATE_REQUEST) &&
- !send_certs.empty())
+ !state->client_certs->empty())
{
- Private_Key* key_matching_cert = 0; // FIXME
+ Private_Key* private_key =
+ creds.private_key_for(state->client_certs->cert_chain()[0],
+ "tls-client",
+ state->client_hello->sni_hostname());
+
state->client_verify = new Certificate_Verify(writer, state->hash,
- rng, key_matching_cert);
+ rng, private_key);
}
state->keys = SessionKeys(state->suite, state->version,
diff --git a/src/tls/tls_client.h b/src/tls/tls_client.h
index eccddef6f..543dda144 100644
--- a/src/tls/tls_client.h
+++ b/src/tls/tls_client.h
@@ -10,6 +10,7 @@
#include <botan/tls_channel.h>
#include <botan/tls_session_manager.h>
+#include <botan/credentials_manager.h>
#include <vector>
namespace Botan {
@@ -26,28 +27,21 @@ class BOTAN_DLL TLS_Client : public TLS_Channel
* @param proc_fn is called when new data (application or alerts) is received
* @param handshake_complete is called when a handshake is completed
* @param session_manager manages session state
+ * @param creds manages application/user credentials
* @param policy specifies other connection policy information
* @param rng a random number generator
* @param servername the server's DNS name, if known
- * @param srp_username a SRP identifier to use for SRP key exchange
- * @param srp_password a SRP password to use for SRP key exchange
*/
TLS_Client(std::tr1::function<void (const byte[], size_t)> socket_output_fn,
std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
std::tr1::function<void (const TLS_Session&)> handshake_complete,
TLS_Session_Manager& session_manager,
+ Credentials_Manager& creds,
const TLS_Policy& policy,
RandomNumberGenerator& rng,
- const std::string& servername = "",
- const std::string& srp_username = "",
- const std::string& srp_password = "");
-
- void add_client_cert(const X509_Certificate& cert,
- Private_Key* cert_key);
+ const std::string& servername = "");
void renegotiate();
-
- ~TLS_Client();
private:
void process_handshake_msg(Handshake_Type type,
const MemoryRegion<byte>& contents);
@@ -55,8 +49,7 @@ class BOTAN_DLL TLS_Client : public TLS_Channel
const TLS_Policy& policy;
RandomNumberGenerator& rng;
TLS_Session_Manager& session_manager;
-
- std::vector<std::pair<X509_Certificate, Private_Key*> > certs;
+ Credentials_Manager& creds;
};
}
diff --git a/src/tls/tls_magic.h b/src/tls/tls_magic.h
index 3629cd112..d49ec1e48 100644
--- a/src/tls/tls_magic.h
+++ b/src/tls/tls_magic.h
@@ -164,11 +164,12 @@ enum TLS_Ciphersuite_Algos {
TLS_ALGO_SIGNER_ECDSA = 0x04000000,
TLS_ALGO_KEYEXCH_MASK = 0x00FF0000,
- TLS_ALGO_KEYEXCH_NOKEX = 0x00010000,
+ TLS_ALGO_KEYEXCH_NOKEX = 0x00010000, // exchange via key in server cert
TLS_ALGO_KEYEXCH_RSA = 0x00020000,
TLS_ALGO_KEYEXCH_DH = 0x00030000,
TLS_ALGO_KEYEXCH_ECDH = 0x00040000,
TLS_ALGO_KEYEXCH_SRP = 0x00050000,
+ TLS_ALGO_KEYEXCH_ANON = 0x00060000,
TLS_ALGO_MAC_MASK = 0x0000FF00,
TLS_ALGO_MAC_MD5 = 0x00000100,
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index f0620003b..16069f048 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -150,7 +150,6 @@ class Server_Hello : public Handshake_Message
const MemoryRegion<byte>& reneg_info,
const std::vector<X509_Certificate>& certs,
const Client_Hello& other,
- const MemoryRegion<byte>& session_id,
Version_Code version);
Server_Hello(Record_Writer& writer,
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index 0e2e173cf..b981bdc69 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -85,25 +85,15 @@ TLS_Server::TLS_Server(std::tr1::function<void (const byte[], size_t)> output_fn
std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
std::tr1::function<void (const TLS_Session&)> handshake_fn,
TLS_Session_Manager& session_manager,
+ Credentials_Manager& creds,
const TLS_Policy& policy,
- RandomNumberGenerator& rng,
- const X509_Certificate& cert,
- const Private_Key& cert_key) :
+ RandomNumberGenerator& rng) :
TLS_Channel(output_fn, proc_fn, handshake_fn),
policy(policy),
rng(rng),
- session_manager(session_manager)
+ session_manager(session_manager),
+ creds(creds)
{
- cert_chain.push_back(cert);
- private_key = PKCS8::copy_key(cert_key, rng);
- }
-
-/*
-* TLS Server Destructor
-*/
-TLS_Server::~TLS_Server()
- {
- delete private_key;
}
/*
@@ -183,7 +173,6 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
{
// resume session
- printf("Resuming a session\n");
state->server_hello = new Server_Hello(
writer,
state->hash,
@@ -222,6 +211,17 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
}
else // new session
{
+ std::vector<X509_Certificate> server_certs =
+ creds.cert_chain("",
+ "tls-server",
+ client_requested_hostname);
+
+ Private_Key* private_key =
+ server_certs.empty() ? 0 :
+ (creds.private_key_for(server_certs[0],
+ "tls-server",
+ client_requested_hostname));
+
state->server_hello = new Server_Hello(
writer,
state->hash,
@@ -229,9 +229,8 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
rng,
secure_renegotiation.supported(),
secure_renegotiation.for_server_hello(),
- cert_chain,
+ server_certs,
*(state->client_hello),
- rng.random_vec(32),
state->version);
if(state->client_hello->fragment_size())
@@ -241,10 +240,9 @@ void TLS_Server::process_handshake_msg(Handshake_Type type,
if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON)
{
- // FIXME: should choose certs based on sig type
state->server_certs = new Certificate(writer,
state->hash,
- cert_chain);
+ server_certs);
}
if(state->suite.kex_type() == TLS_ALGO_KEYEXCH_NOKEX)
diff --git a/src/tls/tls_server.h b/src/tls/tls_server.h
index d684a4a11..e07f89eba 100644
--- a/src/tls/tls_server.h
+++ b/src/tls/tls_server.h
@@ -10,6 +10,7 @@
#include <botan/tls_channel.h>
#include <botan/tls_session_manager.h>
+#include <botan/credentials_manager.h>
#include <vector>
namespace Botan {
@@ -20,23 +21,16 @@ namespace Botan {
class BOTAN_DLL TLS_Server : public TLS_Channel
{
public:
-
/**
* TLS_Server initialization
- *
- * FIXME: support cert chains (!)
- * FIXME: support anonymous servers
*/
TLS_Server(std::tr1::function<void (const byte[], size_t)> socket_output_fn,
std::tr1::function<void (const byte[], size_t, u16bit)> proc_fn,
std::tr1::function<void (const TLS_Session&)> handshake_complete,
TLS_Session_Manager& session_manager,
+ Credentials_Manager& creds,
const TLS_Policy& policy,
- RandomNumberGenerator& rng,
- const X509_Certificate& cert,
- const Private_Key& cert_key);
-
- ~TLS_Server();
+ RandomNumberGenerator& rng);
void renegotiate();
@@ -53,9 +47,7 @@ class BOTAN_DLL TLS_Server : public TLS_Channel
const TLS_Policy& policy;
RandomNumberGenerator& rng;
TLS_Session_Manager& session_manager;
-
- std::vector<X509_Certificate> cert_chain;
- Private_Key* private_key;
+ Credentials_Manager& creds;
std::string client_requested_hostname;
};