diff options
author | lloyd <[email protected]> | 2012-02-03 19:57:14 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2012-02-03 19:57:14 +0000 |
commit | 24c1546324995da70c51137ad138c3bb997a37b9 (patch) | |
tree | 4b2ce029b1387e4424fcdf79357ad96402435906 /doc | |
parent | 863a5420e3ad5efcfc7a175eed0d1a0b641c83c0 (diff) |
Create and save certs on the fly for hostnames as they are asked for
Diffstat (limited to 'doc')
-rw-r--r-- | doc/examples/credentials.h | 106 |
1 files changed, 89 insertions, 17 deletions
diff --git a/doc/examples/credentials.h b/doc/examples/credentials.h index 160fec772..d6350963c 100644 --- a/doc/examples/credentials.h +++ b/doc/examples/credentials.h @@ -3,7 +3,12 @@ #define EXAMPLE_CREDENTIALS_MANAGER_H__ #include <botan/credentials_manager.h> +#include <botan/x509self.h> +#include <botan/rsa.h> +#include <botan/dsa.h> +#include <botan/ecdsa.h> #include <iostream> +#include <fstream> bool value_exists(const std::vector<std::string>& vec, const std::string& val) @@ -19,6 +24,12 @@ class Credentials_Manager_Simple : public Botan::Credentials_Manager public: Credentials_Manager_Simple(Botan::RandomNumberGenerator& rng) : rng(rng) {} + std::string psk_identity_hint(const std::string& type, + const std::string& context) + { + return ""; + } + std::string psk_identity(const std::string&, const std::string&, const std::string& identity_hint) { @@ -29,16 +40,79 @@ class Credentials_Manager_Simple : public Botan::Credentials_Manager const std::string& identity) { if(identity == "Client_identity") - return Botan::SymmetricKey("AABBCC"); + return Botan::SymmetricKey("b5a72e1387552e6dc10766dc0eda12961f5b21e17f98ef4c41e6572e53bd7527"); throw Botan::Internal_Error("No PSK set for " + identity); } + std::pair<Botan::X509_Certificate,Botan::Private_Key*> + load_or_make_cert(const std::string& hostname, + const std::string& key_type, + Botan::RandomNumberGenerator& rng) + { + using namespace Botan; + + const std::string key_fsname_prefix = hostname + "." + key_type + "."; + const std::string key_file_name = key_fsname_prefix + "key"; + const std::string cert_file_name = key_fsname_prefix + "crt"; + + try + { + X509_Certificate cert(cert_file_name); + Private_Key* key = PKCS8::load_key(key_file_name, rng); + + std::cout << "Loaded existing key/cert from " << cert_file_name << " and " << key_file_name << "\n"; + + return std::make_pair(cert, key); + } + catch(...) {} + + // Failed. Instead, make a new one + + std::cout << "Creating new certificate for identifier '" << hostname << "'\n"; + + X509_Cert_Options opts; + + opts.common_name = hostname; + opts.country = "US"; + opts.email = "root@" + hostname; + opts.dns = hostname; + + std::auto_ptr<Private_Key> key; + if(key_type == "rsa") + key.reset(new RSA_PrivateKey(rng, 2048)); + else if(key_type == "dsa") + key.reset(new DSA_PrivateKey(rng, DL_Group("dsa/botan/2048"))); + else if(key_type == "ecdsa") + key.reset(new ECDSA_PrivateKey(rng, EC_Group("secp256r1"))); + else + throw std::runtime_error("Don't know what to do about key type '" + key_type + "'"); + + X509_Certificate cert = + X509::create_self_signed_cert(opts, *key, "SHA-256", rng); + + // Now save both + + std::cout << "Saving new " << key_type << " key to " << key_file_name << "\n"; + std::ofstream key_file(key_file_name.c_str()); + key_file << PKCS8::PEM_encode(*key, rng, ""); + key_file.close(); + + std::cout << "Saving new " << key_type << " cert to " << key_file_name << "\n"; + std::ofstream cert_file(cert_file_name.c_str()); + cert_file << cert.PEM_encode() << "\n"; + cert_file.close(); + + return std::make_pair(cert, key.release()); + } + std::vector<Botan::X509_Certificate> cert_chain( const std::vector<std::string>& cert_key_types, const std::string& type, const std::string& context) { - std::vector<Botan::X509_Certificate> certs; + using namespace Botan; + + std::vector<X509_Certificate> certs; try { @@ -46,27 +120,25 @@ class Credentials_Manager_Simple : public Botan::Credentials_Manager { const std::string hostname = (context == "" ? "localhost" : context); - if(value_exists(cert_key_types, "RSA")) - { - Botan::X509_Certificate cert(hostname + ".crt"); - Botan::Private_Key* key = Botan::PKCS8::load_key(hostname + ".key", rng); + std::string key_name = ""; - certs_and_keys[cert] = key; - certs.push_back(cert); - } + if(value_exists(cert_key_types, "RSA")) + key_name = "rsa"; else if(value_exists(cert_key_types, "DSA")) - { - Botan::X509_Certificate cert(hostname + ".dsa.crt"); - Botan::Private_Key* key = Botan::PKCS8::load_key(hostname + ".dsa.key", rng); + key_name = "dsa"; + else if(value_exists(cert_key_types, "ECDSA")) + key_name = "ecdsa"; + + std::pair<X509_Certificate, Private_Key*> cert_and_key = + load_or_make_cert(hostname, key_name, rng); - certs_and_keys[cert] = key; - certs.push_back(cert); - } + certs_and_keys[cert_and_key.first] = cert_and_key.second; + certs.push_back(cert_and_key.first); } else if(type == "tls-client") { - Botan::X509_Certificate cert("user-rsa.crt"); - Botan::Private_Key* key = Botan::PKCS8::load_key("user-rsa.key", rng); + X509_Certificate cert("user-rsa.crt"); + Private_Key* key = PKCS8::load_key("user-rsa.key", rng); certs_and_keys[cert] = key; certs.push_back(cert); |