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);
183 #ifdef USE_MBEDTLS_TESTCERT
184 if (builtInTestCertificate) {
185 Log_warn("*** Using built-in test certificate and RSA key ***");
186 Log_warn("*** This is not secure! Please use a CA-signed certificate or create a key and self-signed certificate ***");
195 /* Initialize random number generator */
196 #ifdef USE_MBEDTLS_HAVEGE
197 mbedtls_havege_init(&hs);
199 urandom_fd = open("/dev/urandom", O_RDONLY);
201 Log_fatal("Cannot open /dev/urandom");
204 #ifdef MBEDTLS_VERSION_FEATURES
205 mbedtls_version_get_string(verstring);
206 Log_info("mbedTLS library version %s initialized", verstring);
208 Log_info("mbedTLS library initialized");
212 void SSLi_deinit(void)
214 mbedtls_x509_crt_free(&certificate);
215 mbedtls_pk_free(&key);
218 /* Create SHA1 of last certificate in the peer's chain. */
219 bool_t SSLi_getSHA1Hash(SSL_handle_t *ssl, uint8_t *hash)
221 mbedtls_x509_crt const *cert;
222 cert = mbedtls_ssl_get_peer_cert(ssl);
227 mbedtls_sha1(cert->raw.p, cert->raw.len, hash);
231 SSL_handle_t *SSLi_newconnection(int *fd, bool_t *SSLready)
233 mbedtls_ssl_context *ssl;
234 mbedtls_ssl_session *ssn;
235 mbedtls_ssl_config *conf;
238 ssl = calloc(1, sizeof(mbedtls_ssl_context));
239 ssn = calloc(1, sizeof(mbedtls_ssl_session));
240 conf = calloc(1, sizeof(mbedtls_ssl_config));
242 if (!ssl || !ssn || !conf)
243 Log_fatal("Out of memory");
245 mbedtls_ssl_init(ssl);
246 mbedtls_ssl_config_init(conf);
248 if((rc = mbedtls_ssl_config_defaults(conf,
249 MBEDTLS_SSL_IS_SERVER,
250 MBEDTLS_SSL_TRANSPORT_STREAM,
251 MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
252 Log_fatal("mbedtls_ssl_config_defaults returned %d", rc);
254 mbedtls_ssl_conf_authmode(conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
255 #ifdef USE_MBEDTLS_HAVEGE
256 mbedtls_ssl_conf_rng(conf, HAVEGE_RAND, &hs);
258 mbedtls_ssl_conf_rng(conf, urandom_bytes, NULL);
260 mbedtls_ssl_conf_dbg(conf, pssl_debug, NULL);
261 mbedtls_ssl_set_bio(ssl, fd, mbedtls_net_send, mbedtls_net_recv, NULL);
262 mbedtls_ssl_conf_ciphersuites(conf, (const int*)&ciphers);
263 mbedtls_ssl_set_session(ssl, ssn);
264 mbedtls_ssl_conf_ca_chain(conf, &certificate, NULL);
266 if((rc = mbedtls_ssl_conf_own_cert(conf, &certificate, &key)) != 0)
267 Log_fatal("mbedtls_ssl_conf_own_cert returned %d", rc);
269 if((rc = mbedtls_ssl_conf_dh_param(conf, my_dhm_P, my_dhm_G)) != 0)
270 Log_fatal("mbedtls_ssl_conf_dh_param returned %d", rc);
272 if((rc = mbedtls_ssl_setup(ssl, conf)) != 0)
273 Log_fatal("mbedtls_ssl_setup returned %d", rc);
278 int SSLi_nonblockaccept(SSL_handle_t *ssl, bool_t *SSLready)
282 rc = mbedtls_ssl_handshake(ssl);
284 if (rc == MBEDTLS_ERR_SSL_WANT_READ || rc == MBEDTLS_ERR_SSL_WANT_WRITE) {
286 } else if (rc == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { /* Allow this (selfsigned etc) */
289 Log_warn("SSL handshake failed: %d", rc);
297 int SSLi_read(SSL_handle_t *ssl, uint8_t *buf, int len)
301 rc = mbedtls_ssl_read(ssl, buf, len);
302 if (rc == MBEDTLS_ERR_SSL_WANT_READ)
303 return SSLI_ERROR_WANT_READ;
307 int SSLi_write(SSL_handle_t *ssl, uint8_t *buf, int len)
311 rc = mbedtls_ssl_write(ssl, buf, len);
312 if (rc == MBEDTLS_ERR_SSL_WANT_WRITE)
313 return SSLI_ERROR_WANT_WRITE;
317 int SSLi_get_error(SSL_handle_t *ssl, int code)
322 bool_t SSLi_data_pending(SSL_handle_t *ssl)
324 return mbedtls_ssl_get_bytes_avail(ssl) > 0;
327 void SSLi_shutdown(SSL_handle_t *ssl)
329 mbedtls_ssl_close_notify(ssl);
332 void SSLi_free(SSL_handle_t *ssl)
334 Log_debug("SSLi_free");
335 mbedtls_ssl_config_free((mbedtls_ssl_config*)ssl->conf);
336 mbedtls_ssl_free(ssl);
337 free((mbedtls_ssl_config*)ssl->conf);