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.
40 #include <mbedtls/config.h>
41 #include <mbedtls/havege.h>
42 #include <mbedtls/certs.h>
43 #include <mbedtls/x509.h>
44 #include <mbedtls/ssl.h>
45 #include <mbedtls/net.h>
49 MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
50 MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,
51 MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,
55 static mbedtls_x509_crt certificate;
56 static inline int x509parse_keyfile(mbedtls_pk_context *pk, const char *path,
62 ret = mbedtls_pk_parse_keyfile(pk, path, pwd);
63 if (ret == 0 && !mbedtls_pk_can_do(pk, MBEDTLS_PK_RSA))
64 ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;
69 static mbedtls_pk_context key;
70 bool_t builtInTestCertificate;
72 #ifdef USE_MBEDTLS_HAVEGE
80 "9CE85640903BF123906947FEDE767261" \
81 "D9B4A973EB8F7D984A8C656E2BCC161C" \
82 "183D4CA471BA78225F940F16D1D99CA3" \
83 "E66152CC68EDCE1311A390F307741835" \
84 "44FF6AB553EC7073AD0CB608F2A3B480" \
85 "19E6C02BCED40BD30E91BB2469089670" \
86 "DEF409C08E8AC24D1732A6128D2220DC53";
89 #ifdef USE_MBEDTLS_TESTCERT
90 static void initTestCert()
93 builtInTestCertificate = true;
94 rc = mbedtls_x509_crt_parse_rsa(&certificate, (unsigned char *)test_srv_crt,
95 strlen(test_srv_crt));
98 Log_fatal("Could not parse built-in test certificate");
101 static void initTestKey()
105 rc = mbedtls_x509parse_key_rsa(&key, (unsigned char *)test_srv_key,
106 strlen(test_srv_key), NULL, 0);
108 Log_fatal("Could not parse built-in test RSA key");
113 * How to generate a self-signed cert with openssl:
114 * openssl genrsa 1024 > host.key
115 * openssl req -new -x509 -nodes -sha1 -days 365 -key host.key > host.cert
117 static void initCert()
120 char *crtfile = (char *)getStrConf(CERTIFICATE);
122 if (crtfile == NULL) {
123 #ifdef USE_MBEDTLS_TESTCERT
124 Log_warn("No certificate file specified. Falling back to test certificate.");
127 Log_fatal("No certificate file specified");
132 rc = mbedtls_x509_crt_parse_file(&certificate, crtfile);
135 #ifdef USE_MBEDTLS_TESTCERT
136 Log_warn("Could not read certificate file '%s'. Falling back to test certificate.", crtfile);
139 Log_fatal("Could not read certificate file '%s'", crtfile);
145 static void initKey()
148 char *keyfile = (char *)getStrConf(KEY);
151 Log_fatal("No key file specified");
152 rc = x509parse_keyfile(&key, keyfile, NULL);
154 Log_fatal("Could not read RSA key file %s", keyfile);
157 #ifndef USE_MBEDTLS_HAVEGE
158 int urandom_bytes(void *ctx, unsigned char *dest, size_t len)
163 cur = read(urandom_fd, dest, len);
172 #define DEBUG_LEVEL 0
173 static void pssl_debug(void *ctx, int level, const char *file, int line, const char *str)
175 if (level <= DEBUG_LEVEL)
176 Log_info("mbedTLS [level %d]: %s", level, str);
179 mbedtls_ssl_config *conf;
187 #ifdef USE_MBEDTLS_TESTCERT
188 if (builtInTestCertificate) {
189 Log_warn("*** Using built-in test certificate and RSA key ***");
190 Log_warn("*** This is not secure! Please use a CA-signed certificate or create a key and self-signed certificate ***");
199 /* Initialize random number generator */
200 #ifdef USE_MBEDTLS_HAVEGE
201 mbedtls_havege_init(&hs);
203 urandom_fd = open("/dev/urandom", O_RDONLY);
205 Log_fatal("Cannot open /dev/urandom");
208 /* Initialize config */
209 conf = Memory_safeCalloc(1, sizeof(mbedtls_ssl_config));
212 Log_fatal("Out of memory");
214 mbedtls_ssl_config_init(conf);
216 if((rc = mbedtls_ssl_config_defaults(conf,
217 MBEDTLS_SSL_IS_SERVER,
218 MBEDTLS_SSL_TRANSPORT_STREAM,
219 MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
220 Log_fatal("mbedtls_ssl_config_defaults returned %d", rc);
222 mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
223 #ifdef USE_MBEDTLS_HAVEGE
224 mbedtls_ssl_conf_rng(conf, HAVEGE_RAND, &hs);
226 mbedtls_ssl_conf_rng(conf, urandom_bytes, NULL);
228 mbedtls_ssl_conf_dbg(conf, pssl_debug, NULL);
230 mbedtls_ssl_conf_ciphersuites(conf, (const int*)&ciphers);
232 mbedtls_ssl_conf_ca_chain(conf, &certificate, NULL);
234 if((rc = mbedtls_ssl_conf_own_cert(conf, &certificate, &key)) != 0)
235 Log_fatal("mbedtls_ssl_conf_own_cert returned %d", rc);
237 if((rc = mbedtls_ssl_conf_dh_param(conf, my_dhm_P, my_dhm_G)) != 0)
238 Log_fatal("mbedtls_ssl_conf_dh_param returned %d", rc);
240 #ifdef MBEDTLS_VERSION_FEATURES
241 mbedtls_version_get_string(verstring);
242 Log_info("mbedTLS library version %s initialized", verstring);
244 Log_info("mbedTLS library initialized");
248 void SSLi_deinit(void)
250 mbedtls_ssl_config_free(conf);
252 mbedtls_x509_crt_free(&certificate);
253 mbedtls_pk_free(&key);
256 /* Create SHA1 of last certificate in the peer's chain. */
257 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
259 mbedtls_x509_crt const *cert;
260 cert = mbedtls_ssl_get_peer_cert(ssl);
265 mbedtls_sha1(cert->raw.p, cert->raw.len, hash);
269 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
271 mbedtls_ssl_context *ssl;
272 mbedtls_ssl_session *ssn;
275 ssl = Memory_safeCalloc(1, sizeof(mbedtls_ssl_context));
276 ssn = Memory_safeCalloc(1, sizeof(mbedtls_ssl_session));
279 Log_fatal("Out of memory");
281 mbedtls_ssl_init(ssl);
282 mbedtls_ssl_set_bio(ssl, fd, mbedtls_net_send, mbedtls_net_recv, NULL);
283 mbedtls_ssl_set_session(ssl, ssn);
285 if((rc = mbedtls_ssl_setup(ssl, conf)) != 0)
286 Log_fatal("mbedtls_ssl_setup returned %d", rc);
291 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
295 rc = mbedtls_ssl_handshake(ssl);
297 if (rc == MBEDTLS_ERR_SSL_WANT_READ || rc == MBEDTLS_ERR_SSL_WANT_WRITE) {
299 } else if (rc == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { /* Allow this (selfsigned etc) */
302 Log_warn("SSL handshake failed: %d", rc);
310 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
314 rc = mbedtls_ssl_read(ssl, buf, len);
315 if (rc == MBEDTLS_ERR_SSL_WANT_READ)
316 return SSLI_ERROR_WANT_READ;
320 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
324 rc = mbedtls_ssl_write(ssl, buf, len);
325 if (rc == MBEDTLS_ERR_SSL_WANT_WRITE)
326 return SSLI_ERROR_WANT_WRITE;
330 int SSLi_get_error(SSL_handle_t *ssl, int code)
335 bool_t SSLi_data_pending(SSL_handle_t *ssl)
337 return mbedtls_ssl_get_bytes_avail(ssl) > 0;
340 void SSLi_shutdown(SSL_handle_t *ssl)
342 mbedtls_ssl_close_notify(ssl);
345 void SSLi_free(SSL_handle_t *ssl)
347 Log_debug("SSLi_free");
348 mbedtls_ssl_free(ssl);