aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <lloyd@randombit.net>2012-02-01 17:55:03 +0000
committerlloyd <lloyd@randombit.net>2012-02-01 17:55:03 +0000
commit863a5420e3ad5efcfc7a175eed0d1a0b641c83c0 (patch)
treead82580eca85f784b2965ec61a1d1bb25fac1695
parente2e9105071f2d0a1360603f06c2acf68865ff072 (diff)
Actually check CA signatures in Credentials_Manager. This area needs a
lot more work before this can be deployed.
-rw-r--r--src/cert/x509cert/x509cert.cpp28
-rw-r--r--src/cert/x509cert/x509cert.h6
-rw-r--r--src/credentials/credentials_manager.cpp28
-rw-r--r--src/credentials/credentials_manager.h5
-rw-r--r--src/tls/tls_client.cpp4
-rw-r--r--src/tls/tls_server.cpp2
6 files changed, 55 insertions, 18 deletions
diff --git a/src/cert/x509cert/x509cert.cpp b/src/cert/x509cert/x509cert.cpp
index 88aeebd77..7b57f6b1c 100644
--- a/src/cert/x509cert/x509cert.cpp
+++ b/src/cert/x509cert/x509cert.cpp
@@ -284,6 +284,34 @@ X509_DN X509_Certificate::subject_dn() const
return create_dn(subject);
}
+namespace {
+
+bool cert_subject_dns_match(const std::string& name,
+ const std::vector<std::string>& cert_names)
+ {
+ for(size_t i = 0; i != cert_names.size(); ++i)
+ {
+ // support basic wildcarding?
+ if(cert_names[i] == name)
+ return true;
+ }
+
+ return false;
+ }
+
+}
+
+bool X509_Certificate::matches_dns_name(const std::string& name) const
+ {
+ if(cert_subject_dns_match(name, subject_info("DNS")))
+ return true;
+
+ if(cert_subject_dns_match(name, subject_info("Name")))
+ return true;
+
+ return false;
+ }
+
/*
* Compare two certificates for equality
*/
diff --git a/src/cert/x509cert/x509cert.h b/src/cert/x509cert/x509cert.h
index cd49aa02f..26c57e524 100644
--- a/src/cert/x509cert/x509cert.h
+++ b/src/cert/x509cert/x509cert.h
@@ -146,6 +146,12 @@ class BOTAN_DLL X509_Certificate : public X509_Object
std::string to_string() const;
/**
+ * Check if a certain DNS name matches up with the information in
+ * the cert
+ */
+ bool matches_dns_name(const std::string& name) const;
+
+ /**
* Check to certificates for equality.
* @return true both certificates are (binary) equal
*/
diff --git a/src/credentials/credentials_manager.cpp b/src/credentials/credentials_manager.cpp
index 7ca6ac657..ef5d44819 100644
--- a/src/credentials/credentials_manager.cpp
+++ b/src/credentials/credentials_manager.cpp
@@ -6,6 +6,7 @@
*/
#include <botan/credentials_manager.h>
+#include <botan/x509stor.h>
namespace Botan {
@@ -88,31 +89,32 @@ Credentials_Manager::trusted_certificate_authorities(
}
void Credentials_Manager::verify_certificate_chain(
- const std::vector<X509_Certificate>& cert_chain,
- const std::string& purported_hostname)
+ const std::string& type,
+ const std::string& purported_hostname,
+ const std::vector<X509_Certificate>& cert_chain)
{
if(cert_chain.empty())
throw std::invalid_argument("Certificate chain was empty");
-#if 0
- X509_Store store;
+ if(!cert_chain[0].matches_dns_name(purported_hostname))
+ throw std::runtime_error("Certificate did not match hostname");
+
+ std::vector<X509_Certificate> CAs = trusted_certificate_authorities(type, purported_hostname);
- std::vector<X509_Certificate> CAs = trusted_certificate_authorities();
+ X509_Store store;
- for(size_t i = 1; i != CAs.size(); ++i)
+ for(size_t i = 0; i != CAs.size(); ++i)
store.add_cert(CAs[i], true);
- for(size_t i = 1; i != cert_chain.size(); ++i)
+ for(size_t i = 0; i != cert_chain.size(); ++i)
store.add_cert(cert_chain[i]);
- X509_Code result = store.validate_cert(cert_chain[0], TLS_SERVER);
+ X509_Code result = store.validate_cert(cert_chain[0], X509_Store::TLS_SERVER);
+
+ if(CAs.empty() && result == CERT_ISSUER_NOT_FOUND)
+ return;
if(result != VERIFIED)
throw std::runtime_error("Certificate did not validate");
-
- if(!cert_chain[0].matches_dns_name(purported_hostname))
- throw std::runtime_error("Certificate did not match hostname");
-
-#endif
}
}
diff --git a/src/credentials/credentials_manager.h b/src/credentials/credentials_manager.h
index 7dc049722..3994de6c6 100644
--- a/src/credentials/credentials_manager.h
+++ b/src/credentials/credentials_manager.h
@@ -124,8 +124,9 @@ class BOTAN_DLL Credentials_Manager
* certificate chain cannot be verified.
*/
virtual void verify_certificate_chain(
- const std::vector<X509_Certificate>& cert_chain,
- const std::string& hostname = "");
+ const std::string& type,
+ const std::string& hostname,
+ const std::vector<X509_Certificate>& cert_chain);
/**
* @return private key associated with this certificate if we should
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index 2bcdf7457..8b5ea9347 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -266,8 +266,8 @@ void Client::process_handshake_msg(Handshake_Type type,
try
{
- creds.verify_certificate_chain(peer_certs,
- state->client_hello->sni_hostname());
+ const std::string hostname = state->client_hello->sni_hostname();
+ creds.verify_certificate_chain("tls-client", hostname, peer_certs);
}
catch(std::exception& e)
{
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index d186ddac4..a7857edf3 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -384,7 +384,7 @@ void Server::process_handshake_msg(Handshake_Type type,
try
{
- creds.verify_certificate_chain(client_certs);
+ creds.verify_certificate_chain("tls-server", "", client_certs);
}
catch(std::exception& e)
{