2 * ustream-ssl - library for SSL over ustream
4 * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 #include <sys/types.h>
25 #include "ustream-ssl.h"
26 #include "ustream-internal.h"
28 static int urandom_fd
= -1;
30 static int s_ustream_read(void *ctx
, unsigned char *buf
, size_t len
)
32 struct ustream
*s
= ctx
;
39 sbuf
= ustream_get_read_buf(s
, &slen
);
44 return MBEDTLS_ERR_SSL_WANT_READ
;
46 memcpy(buf
, sbuf
, slen
);
47 ustream_consume(s
, slen
);
52 static int s_ustream_write(void *ctx
, const unsigned char *buf
, size_t len
)
54 struct ustream
*s
= ctx
;
57 ret
= ustream_write(s
, (const char *) buf
, len
, false);
58 if (ret
< 0 || s
->write_error
)
59 return MBEDTLS_ERR_NET_SEND_FAILED
;
64 __hidden
void ustream_set_io(struct ustream_ssl_ctx
*ctx
, void *ssl
, struct ustream
*conn
)
66 mbedtls_ssl_set_bio(ssl
, conn
, s_ustream_write
, s_ustream_read
, NULL
);
69 static bool urandom_init(void)
74 urandom_fd
= open("/dev/urandom", O_RDONLY
);
81 static int _urandom(void *ctx
, unsigned char *out
, size_t len
)
83 if (read(urandom_fd
, out
, len
) < 0)
84 return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED
;
89 #define TLS_DEFAULT_CIPHERS \
90 TLS_CIPHER(AES_256_CBC_SHA256) \
91 TLS_CIPHER(AES_256_GCM_SHA384) \
92 TLS_CIPHER(AES_256_CBC_SHA) \
93 TLS_CIPHER(CAMELLIA_256_CBC_SHA256) \
94 TLS_CIPHER(CAMELLIA_256_CBC_SHA) \
95 TLS_CIPHER(AES_128_CBC_SHA256) \
96 TLS_CIPHER(AES_128_GCM_SHA256) \
97 TLS_CIPHER(AES_128_CBC_SHA) \
98 TLS_CIPHER(CAMELLIA_128_CBC_SHA256) \
99 TLS_CIPHER(CAMELLIA_128_CBC_SHA) \
100 TLS_CIPHER(3DES_EDE_CBC_SHA)
102 static const int default_ciphersuites_nodhe
[] =
104 #define TLS_CIPHER(v) \
105 MBEDTLS_TLS_RSA_WITH_##v,
111 static const int default_ciphersuites
[] =
113 #define TLS_CIPHER(v) \
114 MBEDTLS_TLS_DHE_RSA_WITH_##v, \
115 MBEDTLS_TLS_RSA_WITH_##v,
122 __hidden
struct ustream_ssl_ctx
*
123 __ustream_ssl_context_new(bool server
)
125 struct ustream_ssl_ctx
*ctx
;
126 mbedtls_ssl_config
*conf
;
132 ctx
= calloc(1, sizeof(*ctx
));
136 ctx
->server
= server
;
137 mbedtls_pk_init(&ctx
->key
);
138 mbedtls_x509_crt_init(&ctx
->cert
);
139 mbedtls_x509_crt_init(&ctx
->ca_cert
);
141 #if defined(MBEDTLS_SSL_CACHE_C)
142 mbedtls_ssl_cache_init(&ctx
->cache
);
143 mbedtls_ssl_cache_set_timeout(&ctx
->cache
, 30 * 60);
144 mbedtls_ssl_cache_set_max_entries(&ctx
->cache
, 5);
148 mbedtls_ssl_config_init(conf
);
151 mbedtls_ssl_conf_ciphersuites(conf
, default_ciphersuites_nodhe
);
152 ep
= MBEDTLS_SSL_IS_SERVER
;
154 mbedtls_ssl_conf_ciphersuites(conf
, default_ciphersuites
);
155 ep
= MBEDTLS_SSL_IS_CLIENT
;
158 mbedtls_ssl_config_defaults(conf
, ep
, MBEDTLS_SSL_TRANSPORT_STREAM
,
159 MBEDTLS_SSL_PRESET_DEFAULT
);
160 mbedtls_ssl_conf_authmode(conf
, MBEDTLS_SSL_VERIFY_NONE
);
161 mbedtls_ssl_conf_rng(conf
, _urandom
, NULL
);
163 #if defined(MBEDTLS_SSL_CACHE_C)
164 mbedtls_ssl_conf_session_cache(conf
, &ctx
->cache
,
165 mbedtls_ssl_cache_get
,
166 mbedtls_ssl_cache_set
);
171 static void ustream_ssl_update_own_cert(struct ustream_ssl_ctx
*ctx
)
173 if (!ctx
->cert
.version
)
177 mbedtls_ssl_conf_ca_chain(&ctx
->conf
, &ctx
->cert
, NULL
);
181 if (!ctx
->key
.pk_info
)
185 mbedtls_ssl_conf_ca_chain(&ctx
->conf
, ctx
->cert
.next
, NULL
);
186 mbedtls_ssl_conf_own_cert(&ctx
->conf
, &ctx
->cert
, &ctx
->key
);
189 __hidden
int __ustream_ssl_add_ca_crt_file(struct ustream_ssl_ctx
*ctx
, const char *file
)
193 ret
= mbedtls_x509_crt_parse_file(&ctx
->ca_cert
, file
);
197 mbedtls_ssl_conf_ca_chain(&ctx
->conf
, &ctx
->ca_cert
, NULL
);
198 mbedtls_ssl_conf_authmode(&ctx
->conf
, MBEDTLS_SSL_VERIFY_OPTIONAL
);
202 __hidden
int __ustream_ssl_set_crt_file(struct ustream_ssl_ctx
*ctx
, const char *file
)
206 ret
= mbedtls_x509_crt_parse_file(&ctx
->cert
, file
);
210 ustream_ssl_update_own_cert(ctx
);
214 __hidden
int __ustream_ssl_set_key_file(struct ustream_ssl_ctx
*ctx
, const char *file
)
218 ret
= mbedtls_pk_parse_keyfile(&ctx
->key
, file
, NULL
);
222 ustream_ssl_update_own_cert(ctx
);
226 __hidden
void __ustream_ssl_context_free(struct ustream_ssl_ctx
*ctx
)
228 #if defined(MBEDTLS_SSL_CACHE_C)
229 mbedtls_ssl_cache_free(&ctx
->cache
);
231 mbedtls_pk_free(&ctx
->key
);
232 mbedtls_x509_crt_free(&ctx
->ca_cert
);
233 mbedtls_x509_crt_free(&ctx
->cert
);
234 mbedtls_ssl_config_free(&ctx
->conf
);
238 static void ustream_ssl_error(struct ustream_ssl
*us
, int ret
)
241 uloop_timeout_set(&us
->error_timer
, 0);
244 static bool ssl_do_wait(int ret
)
247 case MBEDTLS_ERR_SSL_WANT_READ
:
248 case MBEDTLS_ERR_SSL_WANT_WRITE
:
255 static void ustream_ssl_verify_cert(struct ustream_ssl
*us
)
258 const char *msg
= NULL
;
262 r
= mbedtls_ssl_get_verify_result(ssl
);
263 cn_mismatch
= r
& MBEDTLS_X509_BADCERT_CN_MISMATCH
;
264 r
&= ~MBEDTLS_X509_BADCERT_CN_MISMATCH
;
266 if (r
& MBEDTLS_X509_BADCERT_EXPIRED
)
267 msg
= "certificate has expired";
268 else if (r
& MBEDTLS_X509_BADCERT_REVOKED
)
269 msg
= "certificate has been revoked";
270 else if (r
& MBEDTLS_X509_BADCERT_NOT_TRUSTED
)
271 msg
= "certificate is self-signed or not signed by a trusted CA";
273 msg
= "unknown error";
276 if (us
->notify_verify_error
)
277 us
->notify_verify_error(us
, r
, msg
);
285 __hidden
enum ssl_conn_status
__ustream_ssl_connect(struct ustream_ssl
*us
)
290 r
= mbedtls_ssl_handshake(ssl
);
292 ustream_ssl_verify_cert(us
);
297 return U_SSL_PENDING
;
299 ustream_ssl_error(us
, r
);
303 __hidden
int __ustream_ssl_write(struct ustream_ssl
*us
, const char *buf
, int len
)
306 int done
= 0, ret
= 0;
308 while (done
!= len
) {
309 ret
= mbedtls_ssl_write(ssl
, (const unsigned char *) buf
+ done
, len
- done
);
312 if (ssl_do_wait(ret
))
315 ustream_ssl_error(us
, ret
);
325 __hidden
int __ustream_ssl_read(struct ustream_ssl
*us
, char *buf
, int len
)
327 int ret
= mbedtls_ssl_read(us
->ssl
, (unsigned char *) buf
, len
);
330 if (ssl_do_wait(ret
))
331 return U_SSL_PENDING
;
333 if (ret
== MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY
)
336 ustream_ssl_error(us
, ret
);
343 __hidden
void *__ustream_ssl_session_new(struct ustream_ssl_ctx
*ctx
)
345 mbedtls_ssl_context
*ssl
;
347 ssl
= calloc(1, sizeof(*ssl
));
351 mbedtls_ssl_init(ssl
);
353 if (mbedtls_ssl_setup(ssl
, &ctx
->conf
)) {
361 __hidden
void __ustream_ssl_session_free(void *ssl
)
363 mbedtls_ssl_free(ssl
);