2 * libratbox: a library used by ircd-ratbox and other things
3 * openssl.c: openssl related code
5 * Copyright (C) 2007-2008 ircd-ratbox development team
6 * Copyright (C) 2007-2008 Aaron Sethman <androsyn@ratbox.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
23 * $Id: commio.c 24808 2008-01-02 08:17:05Z androsyn $
26 #include <libratbox_config.h>
27 #include <ratbox_lib.h>
31 #include <commio-int.h>
32 #include <commio-ssl.h>
33 #include <openssl/ssl.h>
34 #include <openssl/dh.h>
35 #include <openssl/err.h>
36 #include <openssl/evp.h>
37 #include <openssl/rand.h>
38 #include <openssl/opensslv.h>
41 * This is a mess but what can you do when the library authors
42 * refuse to play ball with established conventions?
44 #if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x20020002L)
45 # define LRB_HAVE_TLS_METHOD_API 1
47 # if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
48 # define LRB_HAVE_TLS_METHOD_API 1
52 static SSL_CTX
*ssl_server_ctx
;
53 static SSL_CTX
*ssl_client_ctx
;
54 static int libratbox_index
= -1;
59 unsigned long t_err
, err
= 0;
60 err
= ERR_get_error();
64 while((t_err
= ERR_get_error()) > 0)
71 rb_ssl_shutdown(rb_fde_t
*F
)
74 if(F
== NULL
|| F
->ssl
== NULL
)
76 SSL_set_shutdown((SSL
*) F
->ssl
, SSL_RECEIVED_SHUTDOWN
);
78 for(i
= 0; i
< 4; i
++)
80 if(SSL_shutdown((SSL
*) F
->ssl
))
84 SSL_free((SSL
*) F
->ssl
);
88 rb_ssl_handshake_count(rb_fde_t
*F
)
90 return F
->handshake_count
;
94 rb_ssl_clear_handshake_count(rb_fde_t
*F
)
96 F
->handshake_count
= 0;
100 rb_ssl_timeout(rb_fde_t
*F
, void *notused
)
102 lrb_assert(F
->accept
!= NULL
);
103 F
->accept
->callback(F
, RB_ERR_TIMEOUT
, NULL
, 0, F
->accept
->data
);
108 rb_ssl_info_callback(SSL
* ssl
, int where
, int ret
)
110 if(where
& SSL_CB_HANDSHAKE_START
)
112 rb_fde_t
*F
= SSL_get_ex_data(ssl
, libratbox_index
);
115 F
->handshake_count
++;
120 rb_setup_ssl_cb(rb_fde_t
*F
)
122 SSL_set_ex_data(F
->ssl
, libratbox_index
, (char *)F
);
123 SSL_set_info_callback((SSL
*) F
->ssl
, (void (*)(const SSL
*,int,int))rb_ssl_info_callback
);
127 rb_ssl_tryaccept(rb_fde_t
*F
, void *data
)
130 lrb_assert(F
->accept
!= NULL
);
132 struct acceptdata
*ad
;
134 if(!SSL_is_init_finished((SSL
*) F
->ssl
))
136 if((ssl_err
= SSL_accept((SSL
*) F
->ssl
)) <= 0)
138 switch (ssl_err
= SSL_get_error((SSL
*) F
->ssl
, ssl_err
))
140 case SSL_ERROR_WANT_READ
:
141 case SSL_ERROR_WANT_WRITE
:
142 if(ssl_err
== SSL_ERROR_WANT_WRITE
)
143 flags
= RB_SELECT_WRITE
;
145 flags
= RB_SELECT_READ
;
146 F
->ssl_errno
= get_last_err();
147 rb_setselect(F
, flags
, rb_ssl_tryaccept
, NULL
);
149 case SSL_ERROR_SYSCALL
:
150 F
->accept
->callback(F
, RB_ERROR
, NULL
, 0, F
->accept
->data
);
153 F
->ssl_errno
= get_last_err();
154 F
->accept
->callback(F
, RB_ERROR_SSL
, NULL
, 0, F
->accept
->data
);
160 rb_settimeout(F
, 0, NULL
, NULL
);
161 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
, NULL
, NULL
);
165 ad
->callback(F
, RB_OK
, (struct sockaddr
*)&ad
->S
, ad
->addrlen
, ad
->data
);
172 rb_ssl_accept_common(rb_fde_t
*new_F
)
175 if((ssl_err
= SSL_accept((SSL
*) new_F
->ssl
)) <= 0)
177 switch (ssl_err
= SSL_get_error((SSL
*) new_F
->ssl
, ssl_err
))
179 case SSL_ERROR_SYSCALL
:
180 if(rb_ignore_errno(errno
))
181 case SSL_ERROR_WANT_READ
:
182 case SSL_ERROR_WANT_WRITE
:
184 new_F
->ssl_errno
= get_last_err();
185 rb_setselect(new_F
, RB_SELECT_READ
| RB_SELECT_WRITE
,
186 rb_ssl_tryaccept
, NULL
);
190 new_F
->ssl_errno
= get_last_err();
191 new_F
->accept
->callback(new_F
, RB_ERROR_SSL
, NULL
, 0, new_F
->accept
->data
);
197 rb_ssl_tryaccept(new_F
, NULL
);
202 rb_ssl_start_accepted(rb_fde_t
*new_F
, ACCB
* cb
, void *data
, int timeout
)
204 new_F
->type
|= RB_FD_SSL
;
205 new_F
->ssl
= SSL_new(ssl_server_ctx
);
206 new_F
->accept
= rb_malloc(sizeof(struct acceptdata
));
208 new_F
->accept
->callback
= cb
;
209 new_F
->accept
->data
= data
;
210 rb_settimeout(new_F
, timeout
, rb_ssl_timeout
, NULL
);
212 new_F
->accept
->addrlen
= 0;
213 SSL_set_fd((SSL
*) new_F
->ssl
, rb_get_fd(new_F
));
214 rb_setup_ssl_cb(new_F
);
215 rb_ssl_accept_common(new_F
);
222 rb_ssl_accept_setup(rb_fde_t
*F
, rb_fde_t
*new_F
, struct sockaddr
*st
, int addrlen
)
224 new_F
->type
|= RB_FD_SSL
;
225 new_F
->ssl
= SSL_new(ssl_server_ctx
);
226 new_F
->accept
= rb_malloc(sizeof(struct acceptdata
));
228 new_F
->accept
->callback
= F
->accept
->callback
;
229 new_F
->accept
->data
= F
->accept
->data
;
230 rb_settimeout(new_F
, 10, rb_ssl_timeout
, NULL
);
231 memcpy(&new_F
->accept
->S
, st
, addrlen
);
232 new_F
->accept
->addrlen
= addrlen
;
234 SSL_set_fd((SSL
*) new_F
->ssl
, rb_get_fd(new_F
));
235 rb_setup_ssl_cb(new_F
);
236 rb_ssl_accept_common(new_F
);
240 rb_ssl_read_or_write(int r_or_w
, rb_fde_t
*F
, void *rbuf
, const void *wbuf
, size_t count
)
247 ret
= (ssize_t
) SSL_read(ssl
, rbuf
, (int)count
);
249 ret
= (ssize_t
) SSL_write(ssl
, wbuf
, (int)count
);
253 switch (SSL_get_error(ssl
, ret
))
255 case SSL_ERROR_WANT_READ
:
257 return RB_RW_SSL_NEED_READ
;
258 case SSL_ERROR_WANT_WRITE
:
260 return RB_RW_SSL_NEED_WRITE
;
261 case SSL_ERROR_ZERO_RETURN
:
263 case SSL_ERROR_SYSCALL
:
264 err
= get_last_err();
268 return RB_RW_IO_ERROR
;
272 err
= get_last_err();
278 errno
= EIO
; /* not great but... */
279 return RB_RW_SSL_ERROR
;
281 return RB_RW_IO_ERROR
;
287 rb_ssl_read(rb_fde_t
*F
, void *buf
, size_t count
)
289 return rb_ssl_read_or_write(0, F
, buf
, NULL
, count
);
293 rb_ssl_write(rb_fde_t
*F
, const void *buf
, size_t count
)
295 return rb_ssl_read_or_write(1, F
, NULL
, buf
, count
);
299 verify_accept_all_cb(int preverify_ok
, X509_STORE_CTX
*x509_ctx
)
305 get_ssl_error(unsigned long err
)
307 static char buf
[512];
309 ERR_error_string_n(err
, buf
, sizeof buf
);
317 char libratbox_data
[] = "libratbox data";
318 const char libratbox_ciphers
[] = "kEECDH+HIGH:kEDH+HIGH:HIGH:!RC4:!aNULL";
319 SSL_load_error_strings();
321 libratbox_index
= SSL_get_ex_new_index(0, libratbox_data
, NULL
, NULL
, NULL
);
323 #ifndef LRB_HAVE_TLS_METHOD_API
324 ssl_server_ctx
= SSL_CTX_new(SSLv23_server_method());
326 ssl_server_ctx
= SSL_CTX_new(TLS_server_method());
329 if(ssl_server_ctx
== NULL
)
331 rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s",
332 get_ssl_error(ERR_get_error()));
336 long server_options
= SSL_CTX_get_options(ssl_server_ctx
);
338 #ifndef LRB_HAVE_TLS_METHOD_API
339 server_options
|= SSL_OP_NO_SSLv2
;
340 server_options
|= SSL_OP_NO_SSLv3
;
343 #ifdef SSL_OP_SINGLE_DH_USE
344 server_options
|= SSL_OP_SINGLE_DH_USE
;
347 #ifdef SSL_OP_SINGLE_ECDH_USE
348 server_options
|= SSL_OP_SINGLE_ECDH_USE
;
351 #ifdef SSL_OP_NO_TICKET
352 server_options
|= SSL_OP_NO_TICKET
;
355 server_options
|= SSL_OP_CIPHER_SERVER_PREFERENCE
;
357 SSL_CTX_set_options(ssl_server_ctx
, server_options
);
358 SSL_CTX_set_verify(ssl_server_ctx
, SSL_VERIFY_PEER
| SSL_VERIFY_CLIENT_ONCE
, verify_accept_all_cb
);
359 SSL_CTX_set_session_cache_mode(ssl_server_ctx
, SSL_SESS_CACHE_OFF
);
360 SSL_CTX_set_cipher_list(ssl_server_ctx
, libratbox_ciphers
);
362 /* Set ECDHE on OpenSSL 1.00+, but make sure it's actually available because redhat are dicks
363 and bastardise their OpenSSL for stupid reasons... */
364 #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && defined(NID_secp384r1)
365 EC_KEY
*key
= EC_KEY_new_by_curve_name(NID_secp384r1
);
367 SSL_CTX_set_tmp_ecdh(ssl_server_ctx
, key
);
372 #ifndef LRB_HAVE_TLS_METHOD_API
373 ssl_client_ctx
= SSL_CTX_new(SSLv23_client_method());
375 ssl_client_ctx
= SSL_CTX_new(TLS_client_method());
378 if(ssl_client_ctx
== NULL
)
380 rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s",
381 get_ssl_error(ERR_get_error()));
385 #ifndef LRB_HAVE_TLS_METHOD_API
386 SSL_CTX_set_options(ssl_client_ctx
, SSL_OP_NO_SSLv2
| SSL_OP_NO_SSLv3
);
389 #ifdef SSL_OP_NO_TICKET
390 SSL_CTX_set_options(ssl_client_ctx
, SSL_OP_NO_TICKET
);
393 SSL_CTX_set_cipher_list(ssl_client_ctx
, libratbox_ciphers
);
400 rb_setup_ssl_server(const char *cert
, const char *keyfile
, const char *dhfile
, const char *cipher_list
)
406 rb_lib_log("rb_setup_ssl_server: No certificate file");
409 if(!SSL_CTX_use_certificate_chain_file(ssl_server_ctx
, cert
) || !SSL_CTX_use_certificate_chain_file(ssl_client_ctx
, cert
))
411 err
= ERR_get_error();
412 rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", cert
,
419 rb_lib_log("rb_setup_ssl_server: No key file");
424 if(!SSL_CTX_use_PrivateKey_file(ssl_server_ctx
, keyfile
, SSL_FILETYPE_PEM
) || !SSL_CTX_use_PrivateKey_file(ssl_client_ctx
, keyfile
, SSL_FILETYPE_PEM
))
426 err
= ERR_get_error();
427 rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile
,
434 /* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */
435 BIO
*bio
= BIO_new_file(dhfile
, "r");
438 dh
= PEM_read_bio_DHparams(bio
, NULL
, NULL
, NULL
);
441 err
= ERR_get_error();
443 ("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
444 dhfile
, get_ssl_error(err
));
449 SSL_CTX_set_tmp_dh(ssl_server_ctx
, dh
);
453 err
= ERR_get_error();
454 rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
455 dhfile
, get_ssl_error(err
));
459 if (cipher_list
!= NULL
)
461 SSL_CTX_set_cipher_list(ssl_server_ctx
, cipher_list
);
468 rb_ssl_listen(rb_fde_t
*F
, int backlog
, int defer_accept
)
472 result
= rb_listen(F
, backlog
, defer_accept
);
473 F
->type
= RB_FD_SOCKET
| RB_FD_LISTEN
| RB_FD_SSL
;
486 rb_ssl_connect_realcb(rb_fde_t
*F
, int status
, struct ssl_connect
*sconn
)
488 F
->connect
->callback
= sconn
->callback
;
489 F
->connect
->data
= sconn
->data
;
491 rb_connect_callback(F
, status
);
495 rb_ssl_tryconn_timeout_cb(rb_fde_t
*F
, void *data
)
497 rb_ssl_connect_realcb(F
, RB_ERR_TIMEOUT
, data
);
501 rb_ssl_tryconn_cb(rb_fde_t
*F
, void *data
)
503 struct ssl_connect
*sconn
= data
;
505 if(!SSL_is_init_finished((SSL
*) F
->ssl
))
507 if((ssl_err
= SSL_connect((SSL
*) F
->ssl
)) <= 0)
509 switch (ssl_err
= SSL_get_error((SSL
*) F
->ssl
, ssl_err
))
511 case SSL_ERROR_SYSCALL
:
512 if(rb_ignore_errno(errno
))
513 case SSL_ERROR_WANT_READ
:
514 case SSL_ERROR_WANT_WRITE
:
516 F
->ssl_errno
= get_last_err();
517 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
,
518 rb_ssl_tryconn_cb
, sconn
);
522 F
->ssl_errno
= get_last_err();
523 rb_ssl_connect_realcb(F
, RB_ERROR_SSL
, sconn
);
529 rb_ssl_connect_realcb(F
, RB_OK
, sconn
);
535 rb_ssl_tryconn(rb_fde_t
*F
, int status
, void *data
)
537 struct ssl_connect
*sconn
= data
;
541 rb_ssl_connect_realcb(F
, status
, sconn
);
545 F
->type
|= RB_FD_SSL
;
546 F
->ssl
= SSL_new(ssl_client_ctx
);
547 SSL_set_fd((SSL
*) F
->ssl
, F
->fd
);
549 rb_settimeout(F
, sconn
->timeout
, rb_ssl_tryconn_timeout_cb
, sconn
);
550 if((ssl_err
= SSL_connect((SSL
*) F
->ssl
)) <= 0)
552 switch (ssl_err
= SSL_get_error((SSL
*) F
->ssl
, ssl_err
))
554 case SSL_ERROR_SYSCALL
:
555 if(rb_ignore_errno(errno
))
556 case SSL_ERROR_WANT_READ
:
557 case SSL_ERROR_WANT_WRITE
:
559 F
->ssl_errno
= get_last_err();
560 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
,
561 rb_ssl_tryconn_cb
, sconn
);
565 F
->ssl_errno
= get_last_err();
566 rb_ssl_connect_realcb(F
, RB_ERROR_SSL
, sconn
);
572 rb_ssl_connect_realcb(F
, RB_OK
, sconn
);
577 rb_connect_tcp_ssl(rb_fde_t
*F
, struct sockaddr
*dest
,
578 struct sockaddr
*clocal
, int socklen
, CNCB
* callback
, void *data
, int timeout
)
580 struct ssl_connect
*sconn
;
584 sconn
= rb_malloc(sizeof(struct ssl_connect
));
586 sconn
->callback
= callback
;
587 sconn
->timeout
= timeout
;
588 rb_connect_tcp(F
, dest
, clocal
, socklen
, rb_ssl_tryconn
, sconn
, timeout
);
593 rb_ssl_start_connected(rb_fde_t
*F
, CNCB
* callback
, void *data
, int timeout
)
595 struct ssl_connect
*sconn
;
600 sconn
= rb_malloc(sizeof(struct ssl_connect
));
602 sconn
->callback
= callback
;
603 sconn
->timeout
= timeout
;
604 F
->connect
= rb_malloc(sizeof(struct conndata
));
605 F
->connect
->callback
= callback
;
606 F
->connect
->data
= data
;
607 F
->type
|= RB_FD_SSL
;
608 F
->ssl
= SSL_new(ssl_client_ctx
);
610 SSL_set_fd((SSL
*) F
->ssl
, F
->fd
);
612 rb_settimeout(F
, sconn
->timeout
, rb_ssl_tryconn_timeout_cb
, sconn
);
613 if((ssl_err
= SSL_connect((SSL
*) F
->ssl
)) <= 0)
615 switch (ssl_err
= SSL_get_error((SSL
*) F
->ssl
, ssl_err
))
617 case SSL_ERROR_SYSCALL
:
618 if(rb_ignore_errno(errno
))
619 case SSL_ERROR_WANT_READ
:
620 case SSL_ERROR_WANT_WRITE
:
622 F
->ssl_errno
= get_last_err();
623 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
,
624 rb_ssl_tryconn_cb
, sconn
);
628 F
->ssl_errno
= get_last_err();
629 rb_ssl_connect_realcb(F
, RB_ERROR_SSL
, sconn
);
635 rb_ssl_connect_realcb(F
, RB_OK
, sconn
);
640 rb_init_prng(const char *path
, prng_seed_t seed_type
)
642 if(seed_type
== RB_PRNG_DEFAULT
)
647 return RAND_status();
650 return RAND_status();
655 if(RAND_load_file(path
, -1) == -1)
667 return RAND_status();
671 rb_get_random(void *buf
, size_t length
)
675 if((ret
= RAND_bytes(buf
, length
)) == 0)
677 /* remove the error from the queue */
684 rb_get_ssl_strerror(rb_fde_t
*F
)
686 return get_ssl_error(F
->ssl_errno
);
690 rb_get_ssl_certfp(rb_fde_t
*F
, uint8_t certfp
[RB_SSL_CERTFP_LEN
], int method
)
698 cert
= SSL_get_peer_certificate((SSL
*) F
->ssl
);
701 res
= SSL_get_verify_result((SSL
*) F
->ssl
);
704 res
== X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
||
705 res
== X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
||
706 res
== X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
||
707 res
== X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
)
714 case RB_SSL_CERTFP_METH_SHA1
:
716 len
= RB_SSL_CERTFP_LEN_SHA1
;
718 case RB_SSL_CERTFP_METH_SHA256
:
720 len
= RB_SSL_CERTFP_LEN_SHA256
;
722 case RB_SSL_CERTFP_METH_SHA512
:
724 len
= RB_SSL_CERTFP_LEN_SHA512
;
730 X509_digest(cert
, evp
, certfp
, &len
);
741 rb_supports_ssl(void)
747 rb_get_ssl_info(char *buf
, size_t len
)
749 snprintf(buf
, len
, "Using SSL: %s compiled: 0x%lx, library 0x%lx",
750 SSLeay_version(SSLEAY_VERSION
),
751 (long)OPENSSL_VERSION_NUMBER
, SSLeay());
755 rb_ssl_get_cipher(rb_fde_t
*F
)
757 const SSL_CIPHER
*sslciph
;
759 if(F
== NULL
|| F
->ssl
== NULL
)
762 if((sslciph
= SSL_get_current_cipher(F
->ssl
)) == NULL
)
765 return SSL_CIPHER_get_name(sslciph
);
768 #endif /* HAVE_OPESSL */