1 /* Copyright (C) 2009-2015, Martin Johansson <martin@fatbob.nu>
2 Copyright (C) 2005-2015, Thorvald Natvig <thorvald@natvig.com>
3 Copyright (C) 2015-2015, Szymon Pusz <szymon@pusz.net>
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
11 - Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13 - Redistributions in binary form must reproduce the above copyright notice,
14 this list of conditions and the following disclaimer in the documentation
15 and/or other materials provided with the distribution.
16 - Neither the name of the Developers nor the names of its contributors may
17 be used to endorse or promote products derived from this software without
18 specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include <mbedtls/config.h>
40 #include <mbedtls/havege.h>
41 #include <mbedtls/certs.h>
42 #include <mbedtls/x509.h>
43 #include <mbedtls/ssl.h>
44 #include <mbedtls/net.h>
48 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
49 MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
50 MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
54 static mbedtls_x509_crt certificate;
55 static inline int x509parse_keyfile(mbedtls_pk_context *pk, const char *path,
61 ret = mbedtls_pk_parse_keyfile(pk, path, pwd);
62 if (ret == 0 && !mbedtls_pk_can_do(pk, MBEDTLS_PK_RSA))
63 ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
68 static mbedtls_pk_context key;
69 bool_t builtInTestCertificate;
71 #ifdef USE_MBEDTLS_HAVEGE
79 "9CE85640903BF123906947FEDE767261" \
80 "D9B4A973EB8F7D984A8C656E2BCC161C" \
81 "183D4CA471BA78225F940F16D1D99CA3" \
82 "E66152CC68EDCE1311A390F307741835" \
83 "44FF6AB553EC7073AD0CB608F2A3B480" \
84 "19E6C02BCED40BD30E91BB2469089670" \
85 "DEF409C08E8AC24D1732A6128D2220DC53";
88 #ifdef USE_MBEDTLS_TESTCERT
89 static void initTestCert()
92 builtInTestCertificate = true;
93 rc = mbedtls_x509_crt_parse_rsa(&certificate, (unsigned char *)test_srv_crt,
94 strlen(test_srv_crt));
97 Log_fatal("Could not parse built-in test certificate");
100 static void initTestKey()
104 rc = mbedtls_x509parse_key_rsa(&key, (unsigned char *)test_srv_key,
105 strlen(test_srv_key), NULL, 0);
107 Log_fatal("Could not parse built-in test RSA key");
112 * How to generate a self-signed cert with openssl:
113 * openssl genrsa 1024 > host.key
114 * openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert
116 static void initCert()
119 char *crtfile = (char *)getStrConf(CERTIFICATE);
121 if (crtfile == NULL) {
122 #ifdef USE_MBEDTLS_TESTCERT
123 Log_warn("No certificate file specified. Falling back to test certificate.");
126 Log_fatal("No certificate file specified");
131 rc = mbedtls_x509_crt_parse_file(&certificate, crtfile);
134 #ifdef USE_MBEDTLS_TESTCERT
135 Log_warn("Could not read certificate file '%s'. Falling back to test certificate.", crtfile);
138 Log_fatal("Could not read certificate file '%s'", crtfile);
144 static void initKey()
147 char *keyfile = (char *)getStrConf(KEY);
150 Log_fatal("No key file specified");
151 rc = x509parse_keyfile(&key, keyfile, NULL);
153 Log_fatal("Could not read RSA key file %s", keyfile);
156 #ifndef USE_MBEDTLS_HAVEGE
157 int urandom_bytes(void *ctx, unsigned char *dest, size_t len)
162 cur = read(urandom_fd, dest, len);
171 #define DEBUG_LEVEL 0
172 static void pssl_debug(void *ctx, int level, const char *file, int line, const char *str)
174 if (level <= DEBUG_LEVEL)
175 Log_info("mbedTLS [level %d]: %s", level, str);
178 mbedtls_ssl_config *conf;
186 #ifdef USE_MBEDTLS_TESTCERT
187 if (builtInTestCertificate) {
188 Log_warn("*** Using built-in test certificate and RSA key ***");
189 Log_warn("*** This is not secure! Please use a CA-signed certificate or create a key and self-signed certificate ***");
198 /* Initialize random number generator */
199 #ifdef USE_MBEDTLS_HAVEGE
200 mbedtls_havege_init(&hs);
202 urandom_fd = open("/dev/urandom", O_RDONLY);
204 Log_fatal("Cannot open /dev/urandom");
207 /* Initialize config */
208 conf = calloc(1, sizeof(mbedtls_ssl_config));
211 Log_fatal("Out of memory");
213 mbedtls_ssl_config_init(conf);
215 if((rc = mbedtls_ssl_config_defaults(conf,
216 MBEDTLS_SSL_IS_SERVER,
217 MBEDTLS_SSL_TRANSPORT_STREAM,
218 MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
219 Log_fatal("mbedtls_ssl_config_defaults returned %d", rc);
221 mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
222 #ifdef USE_MBEDTLS_HAVEGE
223 mbedtls_ssl_conf_rng(conf, HAVEGE_RAND, &hs);
225 mbedtls_ssl_conf_rng(conf, urandom_bytes, NULL);
227 mbedtls_ssl_conf_dbg(conf, pssl_debug, NULL);
229 mbedtls_ssl_conf_ciphersuites(conf, (const int*)&ciphers);
231 mbedtls_ssl_conf_ca_chain(conf, &certificate, NULL);
233 if((rc = mbedtls_ssl_conf_own_cert(conf, &certificate, &key)) != 0)
234 Log_fatal("mbedtls_ssl_conf_own_cert returned %d", rc);
236 if((rc = mbedtls_ssl_conf_dh_param(conf, my_dhm_P, my_dhm_G)) != 0)
237 Log_fatal("mbedtls_ssl_conf_dh_param returned %d", rc);
239 #ifdef MBEDTLS_VERSION_FEATURES
240 mbedtls_version_get_string(verstring);
241 Log_info("mbedTLS library version %s initialized", verstring);
243 Log_info("mbedTLS library initialized");
247 void SSLi_deinit(void)
249 mbedtls_ssl_config_free(conf);
251 mbedtls_x509_crt_free(&certificate);
252 mbedtls_pk_free(&key);
255 /* Create SHA1 of last certificate in the peer's chain. */
256 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
258 mbedtls_x509_crt const *cert;
259 cert = mbedtls_ssl_get_peer_cert(ssl);
264 mbedtls_sha1(cert->raw.p, cert->raw.len, hash);
268 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
270 mbedtls_ssl_context *ssl;
271 mbedtls_ssl_session *ssn;
274 ssl = calloc(1, sizeof(mbedtls_ssl_context));
275 ssn = calloc(1, sizeof(mbedtls_ssl_session));
278 Log_fatal("Out of memory");
280 mbedtls_ssl_init(ssl);
281 mbedtls_ssl_set_bio(ssl, fd, mbedtls_net_send, mbedtls_net_recv, NULL);
282 mbedtls_ssl_set_session(ssl, ssn);
284 if((rc = mbedtls_ssl_setup(ssl, conf)) != 0)
285 Log_fatal("mbedtls_ssl_setup returned %d", rc);
290 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
294 rc = mbedtls_ssl_handshake(ssl);
296 if (rc == MBEDTLS_ERR_SSL_WANT_READ || rc == MBEDTLS_ERR_SSL_WANT_WRITE) {
298 } else if (rc == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { /* Allow this (selfsigned etc) */
301 Log_warn("SSL handshake failed: %d", rc);
309 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
313 rc = mbedtls_ssl_read(ssl, buf, len);
314 if (rc == MBEDTLS_ERR_SSL_WANT_READ)
315 return SSLI_ERROR_WANT_READ;
319 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
323 rc = mbedtls_ssl_write(ssl, buf, len);
324 if (rc == MBEDTLS_ERR_SSL_WANT_WRITE)
325 return SSLI_ERROR_WANT_WRITE;
329 int SSLi_get_error(SSL_handle_t *ssl, int code)
334 bool_t SSLi_data_pending(SSL_handle_t *ssl)
336 return mbedtls_ssl_get_bytes_avail(ssl) > 0;
339 void SSLi_shutdown(SSL_handle_t *ssl)
341 mbedtls_ssl_close_notify(ssl);
344 void SSLi_free(SSL_handle_t *ssl)
346 Log_debug("SSLi_free");
347 mbedtls_ssl_free(ssl);