aboutsummaryrefslogtreecommitdiffstats
path: root/src/credentials
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-05-25 22:52:00 +0000
committerlloyd <[email protected]>2012-05-25 22:52:00 +0000
commit12090a7148d9ee73572cc1a7268fc489504a8173 (patch)
tree51e50ce0852c56231e9e6dc13f168b10edd45d01 /src/credentials
parent9594979caf775dc4062850044715b804d1fda60c (diff)
parent65cc04445f8d40497f02a14bd8cb97081790e54b (diff)
propagate from branch 'net.randombit.botan.x509-path-validation' (head 63b5a20eab129ca13287fda33d2d02eec329708f)
to branch 'net.randombit.botan' (head 8b8150f09c55184f028f2929c4e7f7cd0d46d96e)
Diffstat (limited to 'src/credentials')
-rw-r--r--src/credentials/credentials_manager.cpp149
-rw-r--r--src/credentials/credentials_manager.h153
-rw-r--r--src/credentials/info.txt6
3 files changed, 308 insertions, 0 deletions
diff --git a/src/credentials/credentials_manager.cpp b/src/credentials/credentials_manager.cpp
new file mode 100644
index 000000000..adb3a64fc
--- /dev/null
+++ b/src/credentials/credentials_manager.cpp
@@ -0,0 +1,149 @@
+/*
+* Credentials Manager
+* (C) 2011,2012 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/credentials_manager.h>
+#include <botan/x509stor.h>
+
+namespace Botan {
+
+std::string Credentials_Manager::psk_identity_hint(const std::string&,
+ const std::string&)
+ {
+ return "";
+ }
+
+std::string Credentials_Manager::psk_identity(const std::string&,
+ const std::string&,
+ const std::string&)
+ {
+ return "";
+ }
+
+SymmetricKey Credentials_Manager::psk(const std::string&,
+ const std::string&,
+ const std::string& identity)
+ {
+ throw Internal_Error("No PSK set for identity " + identity);
+ }
+
+bool Credentials_Manager::attempt_srp(const std::string&,
+ const std::string&)
+ {
+ return false;
+ }
+
+std::string Credentials_Manager::srp_identifier(const std::string&,
+ const std::string&)
+ {
+ return "";
+ }
+
+std::string Credentials_Manager::srp_password(const std::string&,
+ const std::string&,
+ const std::string&)
+ {
+ return "";
+ }
+
+bool Credentials_Manager::srp_verifier(const std::string&,
+ const std::string&,
+ const std::string&,
+ std::string&,
+ BigInt&,
+ std::vector<byte>&,
+ bool)
+ {
+ return false;
+ }
+
+std::vector<X509_Certificate> Credentials_Manager::cert_chain(
+ const std::vector<std::string>&,
+ const std::string&,
+ const std::string&)
+ {
+ return std::vector<X509_Certificate>();
+ }
+
+std::vector<X509_Certificate> Credentials_Manager::cert_chain_single_type(
+ const std::string& cert_key_type,
+ const std::string& type,
+ const std::string& context)
+ {
+ std::vector<std::string> cert_types;
+ cert_types.push_back(cert_key_type);
+ return cert_chain(cert_types, type, context);
+ }
+
+Private_Key* Credentials_Manager::private_key_for(const X509_Certificate&,
+ const std::string&,
+ const std::string&)
+ {
+ return nullptr;
+ }
+
+std::vector<X509_Certificate>
+Credentials_Manager::trusted_certificate_authorities(
+ const std::string&,
+ const std::string&)
+ {
+ return std::vector<X509_Certificate>();
+ }
+
+void Credentials_Manager::verify_certificate_chain(
+ 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(purported_hostname != "" && !cert_chain[0].matches_dns_name(purported_hostname))
+ throw std::runtime_error("Certificate did not match hostname");
+
+#if 1
+ std::vector<X509_Certificate> CAs = trusted_certificate_authorities(type, purported_hostname);
+
+ X509_Store store;
+
+ for(size_t i = 0; i != CAs.size(); ++i)
+ store.add_cert(CAs[i], true);
+ 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], X509_Store::TLS_SERVER);
+
+ if(CAs.empty())
+ {
+ if(result == CERT_ISSUER_NOT_FOUND)
+ return;
+ if(result == CANNOT_ESTABLISH_TRUST)
+ return;
+ }
+
+ if(result != VERIFIED)
+ throw std::runtime_error("Certificate did not validate, code " +
+ std::to_string(result));
+#else
+
+ // New X.509 API
+ const Certificate_Store& CAs =
+ trusted_certificate_authorities(type, purported_hostname);
+
+ Path_Validation_Result result =
+ x509_path_validate(cert_chain,
+ Path_Validation_Restrictions(),
+ store);
+
+ if(!result.successful_validation())
+ throw std::runtime_error("Certificate validation failure: " + result.as_string());
+
+ if(!CAs.certificate_known(result.trust_root())
+ throw std::runtime_error("Certificate chain roots in unknown/untrusted CA");
+#endif
+ }
+
+}
diff --git a/src/credentials/credentials_manager.h b/src/credentials/credentials_manager.h
new file mode 100644
index 000000000..57ebd8b38
--- /dev/null
+++ b/src/credentials/credentials_manager.h
@@ -0,0 +1,153 @@
+/*
+* 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/symkey.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 used values 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() {}
+
+ virtual std::string psk_identity_hint(const std::string& type,
+ const std::string& context);
+
+ /**
+ * @param identity_hint was passed by the server (but may be empty)
+ * @return the PSK identity we want to use
+ */
+ virtual std::string psk_identity(const std::string& type,
+ const std::string& context,
+ const std::string& identity_hint);
+
+ /**
+ * @return the PSK used for identity, or throw an exception if no
+ * key exists
+ */
+ virtual SymmetricKey psk(const std::string& type,
+ const std::string& context,
+ const std::string& identity);
+
+ /**
+ * Return true if we should attempt SRP authentication
+ */
+ virtual bool attempt_srp(const std::string& type,
+ const std::string& context);
+
+ /**
+ * @return identifier for client-side SRP auth, if available
+ for this type/context. Should return empty string
+ if password auth not desired/available.
+ */
+ virtual std::string srp_identifier(const std::string& type,
+ const std::string& context);
+
+ /**
+ * @param identifier specifies what identifier we want the
+ * password for. This will be a value previously returned
+ * by srp_identifier.
+ * @return password for client-side SRP auth, if available
+ for this identifier/type/context.
+ */
+ virtual std::string srp_password(const std::string& type,
+ const std::string& context,
+ const std::string& identifier);
+
+ /**
+ * Retrieve SRP verifier parameters
+ */
+ virtual bool srp_verifier(const std::string& type,
+ const std::string& context,
+ const std::string& identifier,
+ std::string& group_name,
+ BigInt& verifier,
+ std::vector<byte>& salt,
+ bool generate_fake_on_unknown);
+
+ /**
+ * Return a cert chain we can use, ordered from leaf to root,
+ * or else an empty vector.
+ *
+ * It is assumed that the caller can get the private key of the
+ * leaf with private_key_for
+ *
+ * @param cert_key_types specifies the key types desired ("RSA",
+ * "DSA", "ECDSA", etc), or empty if there
+ * is no preference by the caller.
+ */
+ virtual std::vector<X509_Certificate> cert_chain(
+ const std::vector<std::string>& cert_key_types,
+ const std::string& type,
+ const std::string& context);
+
+ /**
+ * Return a cert chain we can use, ordered from leaf to root,
+ * or else an empty vector.
+ *
+ * It is assumed that the caller can get the private key of the
+ * leaf with private_key_for
+ *
+ * @param cert_key_type specifies the type of key requested
+ * ("RSA", "DSA", "ECDSA", etc)
+ */
+ std::vector<X509_Certificate> cert_chain_single_type(
+ const std::string& cert_key_type,
+ const std::string& type,
+ const std::string& context);
+
+ /**
+ * Return a list of the certificates of CAs that we trust in this
+ * type/context.
+ */
+ virtual std::vector<X509_Certificate> trusted_certificate_authorities(
+ const std::string& type,
+ const std::string& context);
+
+ /**
+ * Check the certificate chain is valid up to a trusted root, and
+ * optionally (if hostname != "") that the hostname given is
+ * consistent with the leaf certificate.
+ *
+ * This function should throw an exception derived from
+ * std::exception with an informative what() result if the
+ * certificate chain cannot be verified.
+ */
+ virtual void verify_certificate_chain(
+ 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
+ * use it with this context. cert was returned by cert_chain
+ * @note this object should retain ownership of the returned key;
+ * it should not be deleted by the caller.
+ */
+ 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..689c4f1ae
--- /dev/null
+++ b/src/credentials/info.txt
@@ -0,0 +1,6 @@
+define CREDENTIALS_MANAGER
+
+<requires>
+x509cert
+x509store
+</requires>