diff options
author | lloyd <[email protected]> | 2012-05-25 22:52:00 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-05-25 22:52:00 +0000 |
commit | 12090a7148d9ee73572cc1a7268fc489504a8173 (patch) | |
tree | 51e50ce0852c56231e9e6dc13f168b10edd45d01 /src/credentials | |
parent | 9594979caf775dc4062850044715b804d1fda60c (diff) | |
parent | 65cc04445f8d40497f02a14bd8cb97081790e54b (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.cpp | 149 | ||||
-rw-r--r-- | src/credentials/credentials_manager.h | 153 | ||||
-rw-r--r-- | src/credentials/info.txt | 6 |
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> |