2 * librb: 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
25 #include <librb_config.h>
30 #include <commio-int.h>
31 #include <commio-ssl.h>
32 #include <openssl/ssl.h>
33 #include <openssl/dh.h>
34 #include <openssl/err.h>
35 #include <openssl/evp.h>
36 #include <openssl/rand.h>
37 #include <openssl/opensslv.h>
40 * This is a mess but what can you do when the library authors
41 * refuse to play ball with established conventions?
43 #if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x20020002L)
44 # define LRB_HAVE_TLS_METHOD_API 1
46 # if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
47 # define LRB_HAVE_TLS_METHOD_API 1
52 * Use SSL_CTX_set_ecdh_auto() in OpenSSL 1.0.2 only
53 * Use SSL_CTX_set1_curves_list() in OpenSSL 1.0.2 and above
54 * TODO: Merge this into the block above if LibreSSL implements them
56 #if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10002000L)
57 # define LRB_HAVE_TLS_SET_CURVES 1
58 # if (OPENSSL_VERSION_NUMBER < 0x10100000L)
59 # define LRB_HAVE_TLS_ECDH_AUTO 1
64 * More LibreSSL compatibility mess
65 * Used in rb_get_ssl_info() below.
67 #if !defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER >= 0x10100000L)
69 # define LRB_SSL_VTEXT_COMPILETIME OPENSSL_VERSION_TEXT
70 # define LRB_SSL_VTEXT_RUNTIME OpenSSL_version(OPENSSL_VERSION)
71 # define LRB_SSL_VNUM_COMPILETIME OPENSSL_VERSION_NUMBER
72 # define LRB_SSL_VNUM_RUNTIME OpenSSL_version_num()
73 # define LRB_SSL_FULL_VERSION_INFO 1
76 * "Full version info" above means we have access to all 4 pieces of information.
78 * For the below, this is not the case; LibreSSL version number at runtime returns
79 * the wrong version number, and OpenSSL version text at compile time does not exist.
80 * Thus, we only reliably have version text at runtime, and version number at compile
83 # if defined(LIBRESSL_VERSION_NUMBER) && (LIBRESSL_VERSION_NUMBER >= 0x20200000L)
85 # define LRB_SSL_VTEXT_RUNTIME SSLeay_version(SSLEAY_VERSION)
86 # define LRB_SSL_VNUM_COMPILETIME LIBRESSL_VERSION_NUMBER
88 /* OpenSSL < 1.1.0 or LibreSSL < 2.2.0 */
89 # define LRB_SSL_VTEXT_RUNTIME SSLeay_version(SSLEAY_VERSION)
90 # define LRB_SSL_VNUM_COMPILETIME SSLEAY_VERSION_NUMBER
94 static SSL_CTX
*ssl_server_ctx
= NULL
;
95 static SSL_CTX
*ssl_client_ctx
= NULL
;
96 static int librb_index
= -1;
101 unsigned long t_err
, err
= 0;
102 err
= ERR_get_error();
106 while((t_err
= ERR_get_error()) > 0)
113 rb_ssl_shutdown(rb_fde_t
*F
)
116 if(F
== NULL
|| F
->ssl
== NULL
)
118 SSL_set_shutdown((SSL
*) F
->ssl
, SSL_RECEIVED_SHUTDOWN
);
120 for(i
= 0; i
< 4; i
++)
122 if(SSL_shutdown((SSL
*) F
->ssl
))
126 SSL_free((SSL
*) F
->ssl
);
130 rb_ssl_handshake_count(rb_fde_t
*F
)
132 return F
->handshake_count
;
136 rb_ssl_clear_handshake_count(rb_fde_t
*F
)
138 F
->handshake_count
= 0;
142 rb_ssl_timeout(rb_fde_t
*F
, void *notused
)
144 lrb_assert(F
->accept
!= NULL
);
145 F
->accept
->callback(F
, RB_ERR_TIMEOUT
, NULL
, 0, F
->accept
->data
);
150 rb_ssl_info_callback(SSL
* ssl
, int where
, int ret
)
152 if(where
& SSL_CB_HANDSHAKE_START
)
154 rb_fde_t
*F
= SSL_get_ex_data(ssl
, librb_index
);
157 F
->handshake_count
++;
162 rb_setup_ssl_cb(rb_fde_t
*F
)
164 SSL_set_ex_data(F
->ssl
, librb_index
, (char *)F
);
165 SSL_set_info_callback((SSL
*) F
->ssl
, (void (*)(const SSL
*,int,int))rb_ssl_info_callback
);
169 rb_ssl_tryaccept(rb_fde_t
*F
, void *data
)
172 lrb_assert(F
->accept
!= NULL
);
174 struct acceptdata
*ad
;
176 if(!SSL_is_init_finished((SSL
*) F
->ssl
))
178 if((ssl_err
= SSL_accept((SSL
*) F
->ssl
)) <= 0)
180 switch (ssl_err
= SSL_get_error((SSL
*) F
->ssl
, ssl_err
))
182 case SSL_ERROR_WANT_READ
:
183 case SSL_ERROR_WANT_WRITE
:
184 if(ssl_err
== SSL_ERROR_WANT_WRITE
)
185 flags
= RB_SELECT_WRITE
;
187 flags
= RB_SELECT_READ
;
188 F
->ssl_errno
= get_last_err();
189 rb_setselect(F
, flags
, rb_ssl_tryaccept
, NULL
);
191 case SSL_ERROR_SYSCALL
:
192 F
->accept
->callback(F
, RB_ERROR
, NULL
, 0, F
->accept
->data
);
195 F
->ssl_errno
= get_last_err();
196 F
->accept
->callback(F
, RB_ERROR_SSL
, NULL
, 0, F
->accept
->data
);
202 rb_settimeout(F
, 0, NULL
, NULL
);
203 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
, NULL
, NULL
);
207 ad
->callback(F
, RB_OK
, (struct sockaddr
*)&ad
->S
, ad
->addrlen
, ad
->data
);
214 rb_ssl_accept_common(rb_fde_t
*new_F
)
217 if((ssl_err
= SSL_accept((SSL
*) new_F
->ssl
)) <= 0)
219 switch (ssl_err
= SSL_get_error((SSL
*) new_F
->ssl
, ssl_err
))
221 case SSL_ERROR_SYSCALL
:
222 if(rb_ignore_errno(errno
))
223 case SSL_ERROR_WANT_READ
:
224 case SSL_ERROR_WANT_WRITE
:
226 new_F
->ssl_errno
= get_last_err();
227 rb_setselect(new_F
, RB_SELECT_READ
| RB_SELECT_WRITE
,
228 rb_ssl_tryaccept
, NULL
);
232 new_F
->ssl_errno
= get_last_err();
233 new_F
->accept
->callback(new_F
, RB_ERROR_SSL
, NULL
, 0, new_F
->accept
->data
);
239 rb_ssl_tryaccept(new_F
, NULL
);
244 rb_ssl_start_accepted(rb_fde_t
*new_F
, ACCB
* cb
, void *data
, int timeout
)
246 new_F
->type
|= RB_FD_SSL
;
247 new_F
->ssl
= SSL_new(ssl_server_ctx
);
248 new_F
->accept
= rb_malloc(sizeof(struct acceptdata
));
250 new_F
->accept
->callback
= cb
;
251 new_F
->accept
->data
= data
;
252 rb_settimeout(new_F
, timeout
, rb_ssl_timeout
, NULL
);
254 new_F
->accept
->addrlen
= 0;
255 SSL_set_fd((SSL
*) new_F
->ssl
, rb_get_fd(new_F
));
256 rb_setup_ssl_cb(new_F
);
257 rb_ssl_accept_common(new_F
);
264 rb_ssl_accept_setup(rb_fde_t
*F
, rb_fde_t
*new_F
, struct sockaddr
*st
, int addrlen
)
266 new_F
->type
|= RB_FD_SSL
;
267 new_F
->ssl
= SSL_new(ssl_server_ctx
);
268 new_F
->accept
= rb_malloc(sizeof(struct acceptdata
));
270 new_F
->accept
->callback
= F
->accept
->callback
;
271 new_F
->accept
->data
= F
->accept
->data
;
272 rb_settimeout(new_F
, 10, rb_ssl_timeout
, NULL
);
273 memcpy(&new_F
->accept
->S
, st
, addrlen
);
274 new_F
->accept
->addrlen
= addrlen
;
276 SSL_set_fd((SSL
*) new_F
->ssl
, rb_get_fd(new_F
));
277 rb_setup_ssl_cb(new_F
);
278 rb_ssl_accept_common(new_F
);
282 rb_ssl_read_or_write(int r_or_w
, rb_fde_t
*F
, void *rbuf
, const void *wbuf
, size_t count
)
289 ret
= (ssize_t
) SSL_read(ssl
, rbuf
, (int)count
);
291 ret
= (ssize_t
) SSL_write(ssl
, wbuf
, (int)count
);
295 switch (SSL_get_error(ssl
, ret
))
297 case SSL_ERROR_WANT_READ
:
299 return RB_RW_SSL_NEED_READ
;
300 case SSL_ERROR_WANT_WRITE
:
302 return RB_RW_SSL_NEED_WRITE
;
303 case SSL_ERROR_ZERO_RETURN
:
305 case SSL_ERROR_SYSCALL
:
306 err
= get_last_err();
310 return RB_RW_IO_ERROR
;
314 err
= get_last_err();
320 errno
= EIO
; /* not great but... */
321 return RB_RW_SSL_ERROR
;
323 return RB_RW_IO_ERROR
;
329 rb_ssl_read(rb_fde_t
*F
, void *buf
, size_t count
)
331 return rb_ssl_read_or_write(0, F
, buf
, NULL
, count
);
335 rb_ssl_write(rb_fde_t
*F
, const void *buf
, size_t count
)
337 return rb_ssl_read_or_write(1, F
, NULL
, buf
, count
);
341 verify_accept_all_cb(int preverify_ok
, X509_STORE_CTX
*x509_ctx
)
347 get_ssl_error(unsigned long err
)
349 static char buf
[512];
351 ERR_error_string_n(err
, buf
, sizeof buf
);
358 char librb_data
[] = "librb data";
360 #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
362 * OpenSSL 1.1.0 and above automatically initialises itself with sane defaults
365 SSL_load_error_strings();
368 librb_index
= SSL_get_ex_new_index(0, librb_data
, NULL
, NULL
, NULL
);
374 rb_setup_ssl_server(const char *certfile
, const char *keyfile
, const char *dhfile
, const char *cipher_list
)
376 const char librb_ciphers
[] = "kEECDH+HIGH:kEDH+HIGH:HIGH:!aNULL";
378 #ifdef LRB_HAVE_TLS_SET_CURVES
379 const char librb_curves
[] = "P-521:P-384:P-256";
384 rb_lib_log("rb_setup_ssl_server: No certificate file");
391 if(cipher_list
== NULL
)
392 cipher_list
= librb_ciphers
;
395 SSL_CTX_free(ssl_server_ctx
);
398 SSL_CTX_free(ssl_client_ctx
);
400 #ifdef LRB_HAVE_TLS_METHOD_API
401 ssl_server_ctx
= SSL_CTX_new(TLS_server_method());
402 ssl_client_ctx
= SSL_CTX_new(TLS_client_method());
404 ssl_server_ctx
= SSL_CTX_new(SSLv23_server_method());
405 ssl_client_ctx
= SSL_CTX_new(SSLv23_client_method());
408 if(ssl_server_ctx
== NULL
)
410 rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s",
411 get_ssl_error(ERR_get_error()));
415 if(ssl_client_ctx
== NULL
)
417 rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s",
418 get_ssl_error(ERR_get_error()));
422 #ifndef LRB_HAVE_TLS_METHOD_API
423 SSL_CTX_set_options(ssl_server_ctx
, SSL_OP_NO_SSLv2
| SSL_OP_NO_SSLv3
);
424 SSL_CTX_set_options(ssl_client_ctx
, SSL_OP_NO_SSLv2
| SSL_OP_NO_SSLv3
);
427 #ifdef SSL_OP_SINGLE_DH_USE
428 SSL_CTX_set_options(ssl_server_ctx
, SSL_OP_SINGLE_DH_USE
);
431 #ifdef SSL_OP_SINGLE_ECDH_USE
432 SSL_CTX_set_options(ssl_server_ctx
, SSL_OP_SINGLE_ECDH_USE
);
435 #ifdef SSL_OP_NO_TICKET
436 SSL_CTX_set_options(ssl_server_ctx
, SSL_OP_NO_TICKET
);
437 SSL_CTX_set_options(ssl_client_ctx
, SSL_OP_NO_TICKET
);
440 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
441 SSL_CTX_set_options(ssl_server_ctx
, SSL_OP_CIPHER_SERVER_PREFERENCE
);
444 SSL_CTX_set_verify(ssl_server_ctx
, SSL_VERIFY_PEER
| SSL_VERIFY_CLIENT_ONCE
, verify_accept_all_cb
);
445 SSL_CTX_set_session_cache_mode(ssl_server_ctx
, SSL_SESS_CACHE_OFF
);
447 #ifdef LRB_HAVE_TLS_SET_CURVES
448 SSL_CTX_set1_curves_list(ssl_server_ctx
, librb_curves
);
451 #ifdef LRB_HAVE_TLS_ECDH_AUTO
452 SSL_CTX_set_ecdh_auto(ssl_server_ctx
, 1);
456 * Set manual ECDHE curve on OpenSSL 1.0.0 & 1.0.1, but make sure it's actually available
458 #if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && (OPENSSL_VERSION_NUMBER < 0x10002000L) && !defined(OPENSSL_NO_ECDH)
459 EC_KEY
*key
= EC_KEY_new_by_curve_name(NID_secp384r1
);
461 SSL_CTX_set_tmp_ecdh(ssl_server_ctx
, key
);
466 SSL_CTX_set_cipher_list(ssl_server_ctx
, cipher_list
);
467 SSL_CTX_set_cipher_list(ssl_client_ctx
, cipher_list
);
469 if(!SSL_CTX_use_certificate_chain_file(ssl_server_ctx
, certfile
) || !SSL_CTX_use_certificate_chain_file(ssl_client_ctx
, certfile
))
471 rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", certfile
,
472 get_ssl_error(ERR_get_error()));
476 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
))
478 rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile
,
479 get_ssl_error(ERR_get_error()));
485 /* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */
486 FILE *fp
= fopen(dhfile
, "r");
491 rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
492 dhfile
, strerror(errno
));
494 else if(PEM_read_DHparams(fp
, &dh
, NULL
, NULL
) == NULL
)
496 rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
497 dhfile
, get_ssl_error(ERR_get_error()));
502 SSL_CTX_set_tmp_dh(ssl_server_ctx
, dh
);
512 rb_ssl_listen(rb_fde_t
*F
, int backlog
, int defer_accept
)
516 result
= rb_listen(F
, backlog
, defer_accept
);
517 F
->type
= RB_FD_SOCKET
| RB_FD_LISTEN
| RB_FD_SSL
;
530 rb_ssl_connect_realcb(rb_fde_t
*F
, int status
, struct ssl_connect
*sconn
)
532 F
->connect
->callback
= sconn
->callback
;
533 F
->connect
->data
= sconn
->data
;
535 rb_connect_callback(F
, status
);
539 rb_ssl_tryconn_timeout_cb(rb_fde_t
*F
, void *data
)
541 rb_ssl_connect_realcb(F
, RB_ERR_TIMEOUT
, data
);
545 rb_ssl_tryconn_cb(rb_fde_t
*F
, void *data
)
547 struct ssl_connect
*sconn
= data
;
549 if(!SSL_is_init_finished((SSL
*) F
->ssl
))
551 if((ssl_err
= SSL_connect((SSL
*) F
->ssl
)) <= 0)
553 switch (ssl_err
= SSL_get_error((SSL
*) F
->ssl
, ssl_err
))
555 case SSL_ERROR_SYSCALL
:
556 if(rb_ignore_errno(errno
))
557 case SSL_ERROR_WANT_READ
:
558 case SSL_ERROR_WANT_WRITE
:
560 F
->ssl_errno
= get_last_err();
561 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
,
562 rb_ssl_tryconn_cb
, sconn
);
566 F
->ssl_errno
= get_last_err();
567 rb_ssl_connect_realcb(F
, RB_ERROR_SSL
, sconn
);
573 rb_ssl_connect_realcb(F
, RB_OK
, sconn
);
579 rb_ssl_tryconn(rb_fde_t
*F
, int status
, void *data
)
581 struct ssl_connect
*sconn
= data
;
585 rb_ssl_connect_realcb(F
, status
, sconn
);
589 F
->type
|= RB_FD_SSL
;
590 F
->ssl
= SSL_new(ssl_client_ctx
);
591 SSL_set_fd((SSL
*) F
->ssl
, F
->fd
);
593 rb_settimeout(F
, sconn
->timeout
, rb_ssl_tryconn_timeout_cb
, sconn
);
594 if((ssl_err
= SSL_connect((SSL
*) F
->ssl
)) <= 0)
596 switch (ssl_err
= SSL_get_error((SSL
*) F
->ssl
, ssl_err
))
598 case SSL_ERROR_SYSCALL
:
599 if(rb_ignore_errno(errno
))
600 case SSL_ERROR_WANT_READ
:
601 case SSL_ERROR_WANT_WRITE
:
603 F
->ssl_errno
= get_last_err();
604 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
,
605 rb_ssl_tryconn_cb
, sconn
);
609 F
->ssl_errno
= get_last_err();
610 rb_ssl_connect_realcb(F
, RB_ERROR_SSL
, sconn
);
616 rb_ssl_connect_realcb(F
, RB_OK
, sconn
);
621 rb_connect_tcp_ssl(rb_fde_t
*F
, struct sockaddr
*dest
,
622 struct sockaddr
*clocal
, CNCB
* callback
, void *data
, int timeout
)
624 struct ssl_connect
*sconn
;
628 sconn
= rb_malloc(sizeof(struct ssl_connect
));
630 sconn
->callback
= callback
;
631 sconn
->timeout
= timeout
;
632 rb_connect_tcp(F
, dest
, clocal
, rb_ssl_tryconn
, sconn
, timeout
);
636 rb_ssl_start_connected(rb_fde_t
*F
, CNCB
* callback
, void *data
, int timeout
)
638 struct ssl_connect
*sconn
;
643 sconn
= rb_malloc(sizeof(struct ssl_connect
));
645 sconn
->callback
= callback
;
646 sconn
->timeout
= timeout
;
647 F
->connect
= rb_malloc(sizeof(struct conndata
));
648 F
->connect
->callback
= callback
;
649 F
->connect
->data
= data
;
650 F
->type
|= RB_FD_SSL
;
651 F
->ssl
= SSL_new(ssl_client_ctx
);
653 SSL_set_fd((SSL
*) F
->ssl
, F
->fd
);
655 rb_settimeout(F
, sconn
->timeout
, rb_ssl_tryconn_timeout_cb
, sconn
);
656 if((ssl_err
= SSL_connect((SSL
*) F
->ssl
)) <= 0)
658 switch (ssl_err
= SSL_get_error((SSL
*) F
->ssl
, ssl_err
))
660 case SSL_ERROR_SYSCALL
:
661 if(rb_ignore_errno(errno
))
662 case SSL_ERROR_WANT_READ
:
663 case SSL_ERROR_WANT_WRITE
:
665 F
->ssl_errno
= get_last_err();
666 rb_setselect(F
, RB_SELECT_READ
| RB_SELECT_WRITE
,
667 rb_ssl_tryconn_cb
, sconn
);
671 F
->ssl_errno
= get_last_err();
672 rb_ssl_connect_realcb(F
, RB_ERROR_SSL
, sconn
);
678 rb_ssl_connect_realcb(F
, RB_OK
, sconn
);
683 rb_init_prng(const char *path
, prng_seed_t seed_type
)
685 if(seed_type
== RB_PRNG_DEFAULT
)
690 return RAND_status();
693 return RAND_status();
698 if(RAND_load_file(path
, -1) == -1)
710 return RAND_status();
714 rb_get_random(void *buf
, size_t length
)
718 if((ret
= RAND_bytes(buf
, length
)) == 0)
720 /* remove the error from the queue */
727 rb_get_ssl_strerror(rb_fde_t
*F
)
729 return get_ssl_error(F
->ssl_errno
);
733 make_certfp(X509
*cert
, uint8_t certfp
[RB_SSL_CERTFP_LEN
], int method
)
742 case RB_SSL_CERTFP_METH_CERT_SHA1
:
743 it
= ASN1_ITEM_rptr(X509
);
746 len
= RB_SSL_CERTFP_LEN_SHA1
;
748 case RB_SSL_CERTFP_METH_CERT_SHA256
:
749 it
= ASN1_ITEM_rptr(X509
);
752 len
= RB_SSL_CERTFP_LEN_SHA256
;
754 case RB_SSL_CERTFP_METH_CERT_SHA512
:
755 it
= ASN1_ITEM_rptr(X509
);
758 len
= RB_SSL_CERTFP_LEN_SHA512
;
760 case RB_SSL_CERTFP_METH_SPKI_SHA256
:
761 it
= ASN1_ITEM_rptr(X509_PUBKEY
);
763 data
= X509_get_X509_PUBKEY(cert
);
764 len
= RB_SSL_CERTFP_LEN_SHA256
;
766 case RB_SSL_CERTFP_METH_SPKI_SHA512
:
767 it
= ASN1_ITEM_rptr(X509_PUBKEY
);
769 data
= X509_get_X509_PUBKEY(cert
);
770 len
= RB_SSL_CERTFP_LEN_SHA512
;
776 if (ASN1_item_digest(it
, evp
, data
, certfp
, &len
) != 1)
782 rb_get_ssl_certfp(rb_fde_t
*F
, uint8_t certfp
[RB_SSL_CERTFP_LEN
], int method
)
791 cert
= SSL_get_peer_certificate((SSL
*) F
->ssl
);
795 res
= SSL_get_verify_result((SSL
*) F
->ssl
);
799 case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
:
800 case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
:
801 case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
:
802 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
:
803 case X509_V_ERR_CERT_UNTRUSTED
:
804 len
= make_certfp(cert
, certfp
, method
);
806 default: /* to silence code inspectors */
815 rb_get_ssl_certfp_file(const char *filename
, uint8_t certfp
[RB_SSL_CERTFP_LEN
], int method
)
818 FILE *f
= fopen(filename
, "r");
823 cert
= PEM_read_X509(f
, NULL
, NULL
, NULL
);
827 unsigned int len
= make_certfp(cert
, certfp
, method
);
835 rb_supports_ssl(void)
841 rb_get_ssl_info(char *buf
, size_t len
)
843 #ifdef LRB_SSL_FULL_VERSION_INFO
844 if (LRB_SSL_VNUM_RUNTIME
== LRB_SSL_VNUM_COMPILETIME
)
845 snprintf(buf
, len
, "OpenSSL: compiled 0x%lx, library %s",
846 LRB_SSL_VNUM_COMPILETIME
, LRB_SSL_VTEXT_COMPILETIME
);
848 snprintf(buf
, len
, "OpenSSL: compiled (0x%lx, %s), library (0x%lx, %s)",
849 LRB_SSL_VNUM_COMPILETIME
, LRB_SSL_VTEXT_COMPILETIME
,
850 LRB_SSL_VNUM_RUNTIME
, LRB_SSL_VTEXT_RUNTIME
);
852 snprintf(buf
, len
, "OpenSSL: compiled 0x%lx, library %s",
853 LRB_SSL_VNUM_COMPILETIME
, LRB_SSL_VTEXT_RUNTIME
);
858 rb_ssl_get_cipher(rb_fde_t
*F
)
860 const SSL_CIPHER
*sslciph
;
862 if(F
== NULL
|| F
->ssl
== NULL
)
865 if((sslciph
= SSL_get_current_cipher(F
->ssl
)) == NULL
)
868 return SSL_CIPHER_get_name(sslciph
);
871 #endif /* HAVE_OPENSSL */