2 * librb: a library used by ircd-ratbox and other things
3 * openssl.c: OpenSSL backend
5 * Copyright (C) 2007-2008 ircd-ratbox development team
6 * Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
7 * Copyright (C) 2015-2016 Aaron Jones <aaronmdjones@gmail.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
26 #include <librb_config.h>
31 #include <commio-int.h>
32 #include <commio-ssl.h>
34 #include "openssl_ratbox.h"
38 RB_FD_TLS_DIRECTION_IN
= 0,
39 RB_FD_TLS_DIRECTION_OUT
= 1
40 } rb_fd_tls_direction
;
42 #define SSL_P(x) ((SSL *)((x)->ssl))
46 static SSL_CTX
*ssl_ctx
= NULL
;
55 static const char *rb_ssl_strerror(unsigned long);
56 static void rb_ssl_connect_realcb(rb_fde_t
*, int, struct ssl_connect
*);
61 * Internal OpenSSL-specific code
67 unsigned long err_saved
, err
= 0;
69 while((err_saved
= ERR_get_error()) != 0)
76 rb_ssl_init_fd(rb_fde_t
*const F
, const rb_fd_tls_direction dir
)
78 (void) rb_ssl_last_err();
80 F
->ssl
= SSL_new(ssl_ctx
);
84 rb_lib_log("%s: SSL_new: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
91 case RB_FD_TLS_DIRECTION_IN
:
92 SSL_set_accept_state(SSL_P(F
));
94 case RB_FD_TLS_DIRECTION_OUT
:
95 SSL_set_connect_state(SSL_P(F
));
99 SSL_set_fd(SSL_P(F
), rb_get_fd(F
));
103 rb_ssl_accept_common(rb_fde_t
*const F
, void *const data
)
105 lrb_assert(F
!= NULL
);
106 lrb_assert(F
->accept
!= NULL
);
107 lrb_assert(F
->accept
->callback
!= NULL
);
108 lrb_assert(F
->ssl
!= NULL
);
110 (void) rb_ssl_last_err();
112 int ret
= SSL_do_handshake(SSL_P(F
));
113 int err
= SSL_get_error(SSL_P(F
), ret
);
117 F
->handshake_count
++;
119 rb_settimeout(F
, 0, NULL
, NULL
);
120 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
, NULL
, NULL
);
122 struct acceptdata
*const ad
= F
->accept
;
124 ad
->callback(F
, RB_OK
, (struct sockaddr
*)&ad
->S
, ad
->addrlen
, ad
->data
);
129 if(ret
== -1 && err
== SSL_ERROR_WANT_READ
)
131 rb_setselect(F
, RB_SELECT_READ
, rb_ssl_accept_common
, NULL
);
134 if(ret
== -1 && err
== SSL_ERROR_WANT_WRITE
)
136 rb_setselect(F
, RB_SELECT_WRITE
, rb_ssl_accept_common
, NULL
);
141 F
->ssl_errno
= (unsigned long) err
;
142 F
->accept
->callback(F
, RB_ERROR_SSL
, NULL
, 0, F
->accept
->data
);
146 rb_ssl_connect_common(rb_fde_t
*const F
, void *const data
)
148 lrb_assert(F
!= NULL
);
149 lrb_assert(F
->ssl
!= NULL
);
151 (void) rb_ssl_last_err();
153 int ret
= SSL_do_handshake(SSL_P(F
));
154 int err
= SSL_get_error(SSL_P(F
), ret
);
158 F
->handshake_count
++;
160 rb_settimeout(F
, 0, NULL
, NULL
);
161 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
, NULL
, NULL
);
163 rb_ssl_connect_realcb(F
, RB_OK
, data
);
167 if(ret
== -1 && err
== SSL_ERROR_WANT_READ
)
169 rb_setselect(F
, RB_SELECT_READ
, rb_ssl_connect_common
, data
);
172 if(ret
== -1 && err
== SSL_ERROR_WANT_WRITE
)
174 rb_setselect(F
, RB_SELECT_WRITE
, rb_ssl_connect_common
, data
);
179 F
->ssl_errno
= (unsigned long) err
;
180 rb_ssl_connect_realcb(F
, RB_ERROR_SSL
, data
);
184 rb_ssl_strerror(const unsigned long err
)
186 static char errbuf
[512];
188 ERR_error_string_n(err
, errbuf
, sizeof errbuf
);
194 verify_accept_all_cb(const int preverify_ok
, X509_STORE_CTX
*const x509_ctx
)
200 rb_ssl_read_or_write(const int r_or_w
, rb_fde_t
*const F
, void *const rbuf
, const void *const wbuf
, const size_t count
)
205 (void) rb_ssl_last_err();
208 ret
= (ssize_t
) SSL_read(SSL_P(F
), rbuf
, (int)count
);
210 ret
= (ssize_t
) SSL_write(SSL_P(F
), wbuf
, (int)count
);
214 switch(SSL_get_error(SSL_P(F
), ret
))
216 case SSL_ERROR_WANT_READ
:
218 return RB_RW_SSL_NEED_READ
;
219 case SSL_ERROR_WANT_WRITE
:
221 return RB_RW_SSL_NEED_WRITE
;
222 case SSL_ERROR_ZERO_RETURN
:
224 case SSL_ERROR_SYSCALL
:
225 err
= rb_ssl_last_err();
229 return RB_RW_IO_ERROR
;
233 err
= rb_ssl_last_err();
240 errno
= EIO
; /* not great but... */
241 return RB_RW_SSL_ERROR
;
243 return RB_RW_IO_ERROR
;
249 make_certfp(X509
*const cert
, uint8_t certfp
[const RB_SSL_CERTFP_LEN
], const int method
)
251 unsigned int hashlen
= 0;
252 const EVP_MD
*md_type
= NULL
;
253 const ASN1_ITEM
*item
= NULL
;
258 case RB_SSL_CERTFP_METH_CERT_SHA1
:
259 hashlen
= RB_SSL_CERTFP_LEN_SHA1
;
260 md_type
= EVP_sha1();
261 item
= ASN1_ITEM_rptr(X509
);
264 case RB_SSL_CERTFP_METH_CERT_SHA256
:
265 hashlen
= RB_SSL_CERTFP_LEN_SHA256
;
266 md_type
= EVP_sha256();
267 item
= ASN1_ITEM_rptr(X509
);
270 case RB_SSL_CERTFP_METH_CERT_SHA512
:
271 hashlen
= RB_SSL_CERTFP_LEN_SHA512
;
272 md_type
= EVP_sha512();
273 item
= ASN1_ITEM_rptr(X509
);
276 case RB_SSL_CERTFP_METH_SPKI_SHA256
:
277 hashlen
= RB_SSL_CERTFP_LEN_SHA256
;
278 md_type
= EVP_sha256();
279 item
= ASN1_ITEM_rptr(X509_PUBKEY
);
280 data
= X509_get_X509_PUBKEY(cert
);
282 case RB_SSL_CERTFP_METH_SPKI_SHA512
:
283 hashlen
= RB_SSL_CERTFP_LEN_SHA512
;
284 md_type
= EVP_sha512();
285 item
= ASN1_ITEM_rptr(X509_PUBKEY
);
286 data
= X509_get_X509_PUBKEY(cert
);
292 if(ASN1_item_digest(item
, md_type
, data
, certfp
, &hashlen
) != 1)
294 rb_lib_log("%s: ASN1_item_digest: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
298 return (int) hashlen
;
304 * External OpenSSL-specific code
308 rb_ssl_shutdown(rb_fde_t
*const F
)
310 if(F
== NULL
|| F
->ssl
== NULL
)
313 (void) rb_ssl_last_err();
315 for(int i
= 0; i
< 4; i
++)
317 int ret
= SSL_shutdown(SSL_P(F
));
318 int err
= SSL_get_error(SSL_P(F
), ret
);
320 if(ret
>= 0 || (err
!= SSL_ERROR_WANT_READ
&& err
!= SSL_ERROR_WANT_WRITE
))
331 #ifndef LRB_SSL_NO_EXPLICIT_INIT
332 (void) SSL_library_init();
333 SSL_load_error_strings();
336 rb_lib_log("%s: OpenSSL backend initialised", __func__
);
341 rb_setup_ssl_server(const char *const certfile
, const char *keyfile
,
342 const char *const dhfile
, const char *cipherlist
)
346 rb_lib_log("%s: no certificate file specified", __func__
);
353 if(cipherlist
== NULL
)
354 cipherlist
= rb_default_ciphers
;
357 (void) rb_ssl_last_err();
359 #ifdef LRB_HAVE_TLS_METHOD_API
360 SSL_CTX
*const ssl_ctx_new
= SSL_CTX_new(TLS_method());
362 SSL_CTX
*const ssl_ctx_new
= SSL_CTX_new(SSLv23_method());
365 if(ssl_ctx_new
== NULL
)
367 rb_lib_log("%s: SSL_CTX_new: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
371 if(SSL_CTX_use_certificate_chain_file(ssl_ctx_new
, certfile
) != 1)
373 rb_lib_log("%s: SSL_CTX_use_certificate_chain_file ('%s'): %s", __func__
, certfile
,
374 rb_ssl_strerror(rb_ssl_last_err()));
376 SSL_CTX_free(ssl_ctx_new
);
380 if(SSL_CTX_use_PrivateKey_file(ssl_ctx_new
, keyfile
, SSL_FILETYPE_PEM
) != 1)
382 rb_lib_log("%s: SSL_CTX_use_PrivateKey_file ('%s'): %s", __func__
, keyfile
,
383 rb_ssl_strerror(rb_ssl_last_err()));
385 SSL_CTX_free(ssl_ctx_new
);
391 rb_lib_log("%s: no DH parameters file specified", __func__
);
395 FILE *const dhf
= fopen(dhfile
, "r");
400 rb_lib_log("%s: fopen ('%s'): %s", __func__
, dhfile
, strerror(errno
));
402 else if(PEM_read_DHparams(dhf
, &dhp
, NULL
, NULL
) == NULL
)
404 rb_lib_log("%s: PEM_read_DHparams ('%s'): %s", __func__
, dhfile
,
405 rb_ssl_strerror(rb_ssl_last_err()));
410 SSL_CTX_set_tmp_dh(ssl_ctx_new
, dhp
);
416 if(SSL_CTX_set_cipher_list(ssl_ctx_new
, cipherlist
) != 1)
418 rb_lib_log("%s: SSL_CTX_set_cipher_list: could not configure any ciphers", __func__
);
419 SSL_CTX_free(ssl_ctx_new
);
423 SSL_CTX_set_session_cache_mode(ssl_ctx_new
, SSL_SESS_CACHE_OFF
);
424 SSL_CTX_set_verify(ssl_ctx_new
, SSL_VERIFY_PEER
| SSL_VERIFY_CLIENT_ONCE
, verify_accept_all_cb
);
426 #ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
427 (void) SSL_CTX_clear_options(ssl_ctx_new
, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
);
430 #ifndef LRB_HAVE_TLS_METHOD_API
431 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_NO_SSLv2
| SSL_OP_NO_SSLv3
);
434 #ifdef SSL_OP_NO_TLSv1
435 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_NO_TLSv1
);
438 #ifdef SSL_OP_NO_TICKET
439 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_NO_TICKET
);
442 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
443 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_CIPHER_SERVER_PREFERENCE
);
446 #ifdef SSL_OP_SINGLE_DH_USE
447 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_SINGLE_DH_USE
);
450 #ifdef SSL_OP_SINGLE_ECDH_USE
451 (void) SSL_CTX_set_options(ssl_ctx_new
, SSL_OP_SINGLE_ECDH_USE
);
454 #ifdef LRB_HAVE_TLS_ECDH_AUTO
455 (void) SSL_CTX_set_ecdh_auto(ssl_ctx_new
, 1);
458 #ifdef LRB_HAVE_TLS_SET_CURVES
459 (void) SSL_CTX_set1_curves_list(ssl_ctx_new
, rb_default_curves
);
461 # if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && !defined(OPENSSL_NO_ECDH) && defined(NID_secp384r1)
462 EC_KEY
*const ec_key
= EC_KEY_new_by_curve_name(NID_secp384r1
);
465 SSL_CTX_set_tmp_ecdh(ssl_ctx_new
, ec_key
);
469 rb_lib_log("%s: EC_KEY_new_by_curve_name failed; will not enable ECDHE- ciphers", __func__
);
471 rb_lib_log("%s: OpenSSL built without ECDH support; will not enable ECDHE- ciphers", __func__
);
477 SSL_CTX_free(ssl_ctx
);
479 ssl_ctx
= ssl_ctx_new
;
482 rb_lib_log("%s: TLS configuration successful", __func__
);
487 rb_init_prng(const char *const path
, prng_seed_t seed_type
)
489 (void) rb_ssl_last_err();
491 if(seed_type
== RB_PRNG_FILE
&& RAND_load_file(path
, -1) < 0)
492 rb_lib_log("%s: RAND_load_file: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
494 if(RAND_status() != 1)
496 rb_lib_log("%s: RAND_status: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
500 rb_lib_log("%s: PRNG initialised", __func__
);
505 rb_get_random(void *const buf
, const size_t length
)
507 (void) rb_ssl_last_err();
509 if(RAND_bytes(buf
, (int) length
) != 1)
511 rb_lib_log("%s: RAND_bytes: %s", __func__
, rb_ssl_strerror(rb_ssl_last_err()));
519 rb_get_ssl_strerror(rb_fde_t
*const F
)
521 return rb_ssl_strerror(F
->ssl_errno
);
525 rb_get_ssl_certfp(rb_fde_t
*const F
, uint8_t certfp
[const RB_SSL_CERTFP_LEN
], const int method
)
527 if(F
== NULL
|| F
->ssl
== NULL
)
530 X509
*const peer_cert
= SSL_get_peer_certificate(SSL_P(F
));
531 if(peer_cert
== NULL
)
536 switch(SSL_get_verify_result(SSL_P(F
)))
539 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
:
540 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
:
541 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
:
542 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
:
543 case X509_V_ERR_CERT_UNTRUSTED
:
544 len
= make_certfp(peer_cert
, certfp
, method
);
546 X509_free(peer_cert
);
552 rb_get_ssl_certfp_file(const char *const filename
, uint8_t certfp
[const RB_SSL_CERTFP_LEN
], const int method
)
554 FILE *const fp
= fopen(filename
, "r");
558 X509
*const cert
= PEM_read_X509(fp
, NULL
, NULL
, NULL
);
565 int len
= make_certfp(cert
, certfp
, method
);
574 rb_get_ssl_info(char *const buf
, const size_t len
)
576 #ifdef LRB_SSL_FULL_VERSION_INFO
577 if(LRB_SSL_VNUM_RUNTIME
== LRB_SSL_VNUM_COMPILETIME
)
578 (void) snprintf(buf
, len
, "OpenSSL: compiled 0x%lx, library %s",
579 LRB_SSL_VNUM_COMPILETIME
, LRB_SSL_VTEXT_COMPILETIME
);
581 (void) snprintf(buf
, len
, "OpenSSL: compiled (0x%lx, %s), library (0x%lx, %s)",
582 LRB_SSL_VNUM_COMPILETIME
, LRB_SSL_VTEXT_COMPILETIME
,
583 LRB_SSL_VNUM_RUNTIME
, LRB_SSL_VTEXT_RUNTIME
);
585 (void) snprintf(buf
, len
, "OpenSSL: compiled 0x%lx, library %s",
586 LRB_SSL_VNUM_COMPILETIME
, LRB_SSL_VTEXT_RUNTIME
);
591 rb_ssl_get_cipher(rb_fde_t
*const F
)
593 if(F
== NULL
|| F
->ssl
== NULL
)
596 static char buf
[512];
598 const char *const version
= SSL_get_version(SSL_P(F
));
599 const char *const cipher
= SSL_get_cipher_name(SSL_P(F
));
601 (void) snprintf(buf
, sizeof buf
, "%s, %s", version
, cipher
);
607 rb_ssl_read(rb_fde_t
*const F
, void *const buf
, const size_t count
)
609 return rb_ssl_read_or_write(0, F
, buf
, NULL
, count
);
613 rb_ssl_write(rb_fde_t
*const F
, const void *const buf
, const size_t count
)
615 return rb_ssl_read_or_write(1, F
, NULL
, buf
, count
);
621 * Internal library-agnostic code
625 rb_ssl_connect_realcb(rb_fde_t
*const F
, const int status
, struct ssl_connect
*const sconn
)
627 lrb_assert(F
->connect
!= NULL
);
629 F
->connect
->callback
= sconn
->callback
;
630 F
->connect
->data
= sconn
->data
;
632 rb_connect_callback(F
, status
);
637 rb_ssl_timeout_cb(rb_fde_t
*const F
, void *const data
)
639 lrb_assert(F
->accept
!= NULL
);
640 lrb_assert(F
->accept
->callback
!= NULL
);
642 F
->accept
->callback(F
, RB_ERR_TIMEOUT
, NULL
, 0, F
->accept
->data
);
646 rb_ssl_tryconn_timeout_cb(rb_fde_t
*const F
, void *const data
)
648 rb_ssl_connect_realcb(F
, RB_ERR_TIMEOUT
, data
);
652 rb_ssl_tryconn(rb_fde_t
*const F
, const int status
, void *const data
)
654 lrb_assert(F
!= NULL
);
656 struct ssl_connect
*const sconn
= data
;
660 rb_ssl_connect_realcb(F
, status
, sconn
);
664 F
->type
|= RB_FD_SSL
;
666 rb_settimeout(F
, sconn
->timeout
, rb_ssl_tryconn_timeout_cb
, sconn
);
667 rb_ssl_init_fd(F
, RB_FD_TLS_DIRECTION_OUT
);
668 rb_ssl_connect_common(F
, sconn
);
674 * External library-agnostic code
678 rb_supports_ssl(void)
684 rb_ssl_handshake_count(rb_fde_t
*const F
)
686 return F
->handshake_count
;
690 rb_ssl_clear_handshake_count(rb_fde_t
*const F
)
692 F
->handshake_count
= 0;
696 rb_ssl_start_accepted(rb_fde_t
*const F
, ACCB
*const cb
, void *const data
, const int timeout
)
698 F
->type
|= RB_FD_SSL
;
700 F
->accept
= rb_malloc(sizeof(struct acceptdata
));
701 F
->accept
->callback
= cb
;
702 F
->accept
->data
= data
;
703 F
->accept
->addrlen
= 0;
704 (void) memset(&F
->accept
->S
, 0x00, sizeof F
->accept
->S
);
706 rb_settimeout(F
, timeout
, rb_ssl_timeout_cb
, NULL
);
707 rb_ssl_init_fd(F
, RB_FD_TLS_DIRECTION_IN
);
708 rb_ssl_accept_common(F
, NULL
);
712 rb_ssl_accept_setup(rb_fde_t
*const srv_F
, rb_fde_t
*const cli_F
, struct sockaddr
*const st
, const int addrlen
)
714 cli_F
->type
|= RB_FD_SSL
;
716 cli_F
->accept
= rb_malloc(sizeof(struct acceptdata
));
717 cli_F
->accept
->callback
= srv_F
->accept
->callback
;
718 cli_F
->accept
->data
= srv_F
->accept
->data
;
719 cli_F
->accept
->addrlen
= (rb_socklen_t
) addrlen
;
720 (void) memset(&cli_F
->accept
->S
, 0x00, sizeof cli_F
->accept
->S
);
721 (void) memcpy(&cli_F
->accept
->S
, st
, (size_t) addrlen
);
723 rb_settimeout(cli_F
, 10, rb_ssl_timeout_cb
, NULL
);
724 rb_ssl_init_fd(cli_F
, RB_FD_TLS_DIRECTION_IN
);
725 rb_ssl_accept_common(cli_F
, NULL
);
729 rb_ssl_listen(rb_fde_t
*const F
, const int backlog
, const int defer_accept
)
731 int result
= rb_listen(F
, backlog
, defer_accept
);
733 F
->type
= RB_FD_SOCKET
| RB_FD_LISTEN
| RB_FD_SSL
;
739 rb_connect_tcp_ssl(rb_fde_t
*const F
, struct sockaddr
*const dest
, struct sockaddr
*const clocal
,
740 CNCB
*const callback
, void *const data
, const int timeout
)
745 struct ssl_connect
*const sconn
= rb_malloc(sizeof *sconn
);
747 sconn
->callback
= callback
;
748 sconn
->timeout
= timeout
;
750 rb_connect_tcp(F
, dest
, clocal
, rb_ssl_tryconn
, sconn
, timeout
);
754 rb_ssl_start_connected(rb_fde_t
*const F
, CNCB
*const callback
, void *const data
, const int timeout
)
759 struct ssl_connect
*const sconn
= rb_malloc(sizeof *sconn
);
761 sconn
->callback
= callback
;
762 sconn
->timeout
= timeout
;
764 F
->connect
= rb_malloc(sizeof(struct conndata
));
765 F
->connect
->callback
= callback
;
766 F
->connect
->data
= data
;
767 F
->type
|= RB_FD_SSL
;
769 rb_settimeout(F
, sconn
->timeout
, rb_ssl_tryconn_timeout_cb
, sconn
);
770 rb_ssl_init_fd(F
, RB_FD_TLS_DIRECTION_OUT
);
771 rb_ssl_connect_common(F
, sconn
);
774 #endif /* HAVE_OPENSSL */