|
| 1 | +// This file is a part of the IncludeOS unikernel - www.includeos.org |
| 2 | +// |
| 3 | +// Copyright 2015-2017 Oslo and Akershus University College of Applied Sciences |
| 4 | +// and Alfred Bratterud |
| 5 | +// |
| 6 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 7 | +// you may not use this file except in compliance with the License. |
| 8 | +// You may obtain a copy of the License at |
| 9 | +// |
| 10 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 11 | +// |
| 12 | +// Unless required by applicable law or agreed to in writing, software |
| 13 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 14 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | +// See the License for the specific language governing permissions and |
| 16 | +// limitations under the License. |
| 17 | + |
| 18 | +#pragma once |
| 19 | +#ifndef NET_TLS_CREDMAN_HPP |
| 20 | +#define NET_TLS_CREDMAN_HPP |
| 21 | + |
| 22 | +#include <botan/credentials_manager.h> |
| 23 | +#include <botan/pk_algs.h> |
| 24 | +#include <botan/rng.h> |
| 25 | +#include <botan/x509cert.h> |
| 26 | +#include <botan/x509_ca.h> |
| 27 | +//#include <botan/x509path.h> |
| 28 | +#include <botan/x509self.h> |
| 29 | +#include <memory> |
| 30 | + |
| 31 | +namespace net |
| 32 | +{ |
| 33 | +typedef std::chrono::duration<int, std::ratio<31556926>> years; |
| 34 | + |
| 35 | +class Credman : public Botan::Credentials_Manager |
| 36 | +{ |
| 37 | +public: |
| 38 | + Credman(const Botan::X509_Certificate server_cert, |
| 39 | + const Botan::X509_Certificate ca_cert, |
| 40 | + std::unique_ptr<Botan::Private_Key> server_key) : |
| 41 | + m_server_cert(std::move(server_cert)), |
| 42 | + m_ca_cert(std::move(ca_cert)), |
| 43 | + m_server_key(std::move(server_key)) |
| 44 | + { |
| 45 | + std::unique_ptr<Botan::Certificate_Store> store(new Botan::Certificate_Store_In_Memory(m_ca_cert)); |
| 46 | + m_stores.push_back(std::move(store)); |
| 47 | + m_provides_client_certs = false; |
| 48 | + } |
| 49 | + |
| 50 | + std::vector<Botan::Certificate_Store*> |
| 51 | + trusted_certificate_authorities(const std::string&, |
| 52 | + const std::string&) override |
| 53 | + { |
| 54 | + std::vector<Botan::Certificate_Store*> v; |
| 55 | + for (auto&& store : m_stores) |
| 56 | + v.push_back(store.get()); |
| 57 | + return v; |
| 58 | + } |
| 59 | + |
| 60 | + std::vector<Botan::X509_Certificate> cert_chain( |
| 61 | + const std::vector<std::string>& cert_key_types, |
| 62 | + const std::string& type, |
| 63 | + const std::string&) override |
| 64 | + { |
| 65 | + std::vector<Botan::X509_Certificate> chain; |
| 66 | + |
| 67 | + if (type == "tls-server" || (type == "tls-client" && m_provides_client_certs)) |
| 68 | + { |
| 69 | + bool have_match = false; |
| 70 | + for (size_t i = 0; i != cert_key_types.size(); ++i) |
| 71 | + if(cert_key_types[i] == m_server_key->algo_name()) |
| 72 | + have_match = true; |
| 73 | + |
| 74 | + if(have_match) |
| 75 | + { |
| 76 | + chain.push_back(m_server_cert); |
| 77 | + chain.push_back(m_ca_cert); |
| 78 | + } |
| 79 | + } |
| 80 | + return chain; |
| 81 | + } |
| 82 | + |
| 83 | + Botan::Private_Key* private_key_for(const Botan::X509_Certificate&, |
| 84 | + const std::string&, |
| 85 | + const std::string&) override |
| 86 | + { |
| 87 | + return m_server_key.get(); |
| 88 | + } |
| 89 | + |
| 90 | + Botan::SymmetricKey psk(const std::string&, |
| 91 | + const std::string&, |
| 92 | + const std::string&) override |
| 93 | + { |
| 94 | + //if (type == "tls-server" && context == "session-ticket") |
| 95 | + // return Botan::SymmetricKey("AABBCCDDEEFF012345678012345678"); |
| 96 | + |
| 97 | + return Botan::SymmetricKey("20B602D1475F2DF888FCB60D2AE03AFD"); // PSK key |
| 98 | + } |
| 99 | + |
| 100 | + static Credman* create( |
| 101 | + Botan::RandomNumberGenerator& rng, |
| 102 | + std::unique_ptr<Botan::Private_Key> ca_key, |
| 103 | + Botan::X509_Certificate ca_cert, |
| 104 | + std::unique_ptr<Botan::Private_Key> server_key); |
| 105 | + |
| 106 | +public: |
| 107 | + Botan::X509_Certificate m_server_cert, m_ca_cert; |
| 108 | + std::unique_ptr<Botan::Private_Key> m_server_key; |
| 109 | + std::vector<std::unique_ptr<Botan::Certificate_Store>> m_stores; |
| 110 | + bool m_provides_client_certs; |
| 111 | +}; |
| 112 | + |
| 113 | +/** |
| 114 | + * 3. create private key 2 <server> |
| 115 | + * 4. create certificate request <req> with private key 2 |
| 116 | + * 5. create CA with <CA> key and <CA> cert |
| 117 | + * 6, create certificate <server> by signing <req> |
| 118 | + * |
| 119 | +**/ |
| 120 | +inline Credman* Credman::create( |
| 121 | + Botan::RandomNumberGenerator& rng, |
| 122 | + std::unique_ptr<Botan::Private_Key> ca_key, |
| 123 | + Botan::X509_Certificate ca_cert, |
| 124 | + std::unique_ptr<Botan::Private_Key> server_key) |
| 125 | +{ |
| 126 | + Botan::X509_CA ca(ca_cert, *ca_key, "SHA-256", rng); |
| 127 | + |
| 128 | + // create server certificate from CA |
| 129 | + auto now = std::chrono::system_clock::now(); |
| 130 | + Botan::X509_Time start_time(now); |
| 131 | + Botan::X509_Time end_time(now + years(1)); |
| 132 | + |
| 133 | + // create certificate request |
| 134 | + Botan::X509_Cert_Options server_opts; |
| 135 | + server_opts.common_name = "server.example.com"; |
| 136 | + server_opts.country = "VT"; |
| 137 | + |
| 138 | + auto req = Botan::X509::create_cert_req(server_opts, *server_key, "SHA-256", rng); |
| 139 | + |
| 140 | + auto server_cert = ca.sign_request(req, rng, start_time, end_time); |
| 141 | + |
| 142 | + // create credentials manager |
| 143 | + return new Credman(server_cert, ca_cert, std::move(server_key)); |
| 144 | +} |
| 145 | + |
| 146 | +} // net |
| 147 | + |
| 148 | +#endif |
0 commit comments