Skip to content

Commit 68efdf6

Browse files
committed
Add Botan, TLS stream and Secure HTTP server
1 parent 6c1a7cb commit 68efdf6

11 files changed

Lines changed: 515 additions & 11 deletions

File tree

CMakeLists.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ set(CMAKE_C_FLAGS "-target i686 -MMD ${CAPABS} ${WARNS} -nostdlib -nostdlibinc -
8989
option(from_bundle "Download and use pre-compiled libraries for cross-comilation" ON)
9090
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/cross_compiled_libraries.txt)
9191

92+
# Botan Crypto & TLS
93+
# Note: Include order matters!
94+
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/botan.cmake)
95+
9296
#
9397
# Subprojects
9498
#
@@ -120,9 +124,6 @@ if(diskbuilder)
120124
)
121125
endif(diskbuilder)
122126

123-
# Botan Crypto & TLS
124-
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/botan.cmake)
125-
126127
option(examples "Build example unikernels in /examples" OFF)
127128
if(examples)
128129
add_subdirectory(examples)

api/https

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// -*- C++ -*-
2+
// This file is a part of the IncludeOS unikernel - www.includeos.org
3+
//
4+
// Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
5+
// and Alfred Bratterud
6+
//
7+
// Licensed under the Apache License, Version 2.0 (the "License");
8+
// you may not use this file except in compliance with the License.
9+
// You may obtain a copy of the License at
10+
//
11+
// http://www.apache.org/licenses/LICENSE-2.0
12+
//
13+
// Unless required by applicable law or agreed to in writing, software
14+
// distributed under the License is distributed on an "AS IS" BASIS,
15+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
// See the License for the specific language governing permissions and
17+
// limitations under the License.
18+
19+
#pragma once
20+
#ifndef API_HTTPS_HEADER
21+
#define API_HTTPS_HEADER
22+
23+
#include "net/http/response.hpp"
24+
#include "net/http/request.hpp"
25+
#include "net/http/secure_server.hpp"
26+
27+
#endif

api/memdisk

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,15 @@
2525

2626
namespace fs
2727
{
28+
// new singleton interface for the memdisk
29+
inline Disk& memdisk()
30+
{
31+
static MemDisk device;
32+
static Disk disk {device};
33+
return disk;
34+
}
2835
// new_shared_memdisk() very likely contains FAT
36+
// Note: deprecated!
2937
inline Disk_ptr new_shared_memdisk()
3038
{
3139
static MemDisk device;

api/net/http/secure_server.hpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// This file is a part of the IncludeOS unikernel - www.includeos.org
2+
//
3+
// Copyright 2016-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_HTTP_SECURE_SERVER_HPP
20+
#define NET_HTTP_SECURE_SERVER_HPP
21+
22+
#include <net/http/server.hpp>
23+
#include <fs/dirent.hpp>
24+
#include <net/tls/server.hpp>
25+
26+
namespace http {
27+
28+
class Secure_server : public http::Server
29+
{
30+
public:
31+
Secure_server(
32+
fs::Dirent& ca_key,
33+
fs::Dirent& ca_cert,
34+
fs::Dirent& server_key,
35+
TCP& tcp,
36+
Request_handler cb
37+
);
38+
39+
Secure_server(
40+
Botan::Credentials_Manager* in_credman,
41+
Botan::RandomNumberGenerator& in_rng,
42+
TCP& tcp,
43+
Request_handler cb)
44+
: http::Server(tcp, cb), rng(in_rng), credman(in_credman)
45+
{
46+
on_connect = {this, &Secure_server::secure_connect};
47+
}
48+
49+
void secure_connect(TCP_conn conn)
50+
{
51+
auto* ptr = new net::tls::Server(conn, rng, *credman);
52+
53+
ptr->on_connect(
54+
[this, ptr] (net::Stream&)
55+
{
56+
// create and pass TLS socket
57+
Server::connect(std::unique_ptr<net::tls::Server>(ptr));
58+
});
59+
ptr->on_close([ptr] {
60+
printf("Secure_HTTP::on_close on %s\n", ptr->to_string().c_str());
61+
delete ptr;
62+
});
63+
}
64+
65+
private:
66+
Botan::RandomNumberGenerator& rng;
67+
std::unique_ptr<Botan::Credentials_Manager> credman;
68+
};
69+
70+
} // http
71+
72+
#endif

api/net/http/server.hpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,11 @@ namespace http {
9090
*/
9191
Response_ptr create_response(status_t code = http::OK) const;
9292

93-
~Server();
93+
virtual ~Server();
94+
95+
protected:
96+
delegate<void(TCP_conn)> on_connect;
97+
void connect(Connection::Stream_ptr stream);
9498

9599
private:
96100
friend class Server_connection;
@@ -109,10 +113,9 @@ namespace http {
109113
Stat& stat_req_bad_;
110114
Stat& stat_timeouts_;
111115

112-
void connect(TCP_conn conn)
113-
{ connect(std::make_unique<Connection::Stream>(conn)); }
114-
115-
void connect(Connection::Stream_ptr stream);
116+
void connected(TCP_conn conn) {
117+
connect(std::make_unique<Connection::Stream>(conn));
118+
}
116119

117120
void close(Server_connection&);
118121

api/net/tls/credman.hpp

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
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

Comments
 (0)