1 /* source: xio-openssl.c */
2 /* Copyright Gerhard Rieger 2002-2008 */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* this file contains the implementation of the openssl addresses */
7 #include "xiosysincludes.h"
8 #if WITH_OPENSSL /* make this address configure dependend */
12 #include "xio-socket.h" /* _xioopen_connect() */
13 #include "xio-listen.h"
14 #include "xio-ipapp.h"
15 #include "xio-openssl.h"
17 /* the openssl library requires a file descriptor for external communications.
18 so our best effort is to provide any possible kind of un*x file descriptor
19 (not only tcp, but also pipes, stdin, files...)
20 for tcp we want to provide support for socks and proxy.
21 read and write functions must use the openssl crypt versions.
22 but currently only plain tcp4 is implemented.
25 /* Linux: "man 3 ssl" */
27 /* generate a simple openssl server for testing:
28 1) generate a private key
29 openssl genrsa -out server.key 1024
30 2) generate a self signed cert
31 openssl req -new -key server.key -x509 -days 3653 -out server.crt
33 3) generate the pem file
34 cat server.key server.crt >server.pem
35 openssl s_server (listens on 4433/tcp)
38 /* static declaration of ssl's open function */
39 static int xioopen_openssl_connect(int argc
, const char *argv
[], struct opt
*opts
,
40 int xioflags
, xiofile_t
*fd
, unsigned groups
,
41 int dummy1
, int dummy2
, int dummy3
);
43 /* static declaration of ssl's open function */
44 static int xioopen_openssl_listen(int argc
, const char *argv
[], struct opt
*opts
,
45 int xioflags
, xiofile_t
*fd
, unsigned groups
,
46 int dummy1
, int dummy2
, int dummy3
);
47 static int openssl_SSL_ERROR_SSL(int level
, const char *funcname
);
48 static int openssl_handle_peer_certificate(struct single
*xfd
, bool opt_ver
,
50 static int xioSSL_set_fd(struct single
*xfd
, int level
);
51 static int xioSSL_connect(struct single
*xfd
, bool opt_ver
, int level
);
54 /* description record for ssl connect */
55 const struct addrdesc addr_openssl
= {
56 "openssl", /* keyword for selecting this address type in xioopen calls
57 (canonical or main name) */
58 3, /* data flow directions this address supports on API layer:
59 1..read, 2..write, 3..both */
60 xioopen_openssl_connect
, /* a function pointer used to "open" these addresses.*/
61 GROUP_FD
|GROUP_SOCKET
|GROUP_SOCK_IP4
|GROUP_SOCK_IP6
|GROUP_IP_TCP
|GROUP_CHILD
|GROUP_OPENSSL
|GROUP_RETRY
, /* bitwise OR of address groups this address belongs to.
62 You might have to specify a new group in xioopts.h */
63 0, /* an integer passed to xioopen_openssl; makes it possible to
64 use the same xioopen_openssl function for slightly different
66 0, /* like previous argument */
67 0 /* like previous arguments, but pointer type.
68 No trailing comma or semicolon! */
69 HELP(":<host>:<port>") /* a text displayed from xio help function.
70 No trailing comma or semicolon!
71 only generates this text if WITH_HELP is != 0 */
75 /* description record for ssl listen */
76 const struct addrdesc addr_openssl_listen
= {
77 "openssl-listen", /* keyword for selecting this address type in xioopen calls
78 (canonical or main name) */
79 3, /* data flow directions this address supports on API layer:
80 1..read, 2..write, 3..both */
81 xioopen_openssl_listen
, /* a function pointer used to "open" these addresses.*/
82 GROUP_FD
|GROUP_SOCKET
|GROUP_SOCK_IP4
|GROUP_SOCK_IP6
|GROUP_IP_TCP
|GROUP_LISTEN
|GROUP_CHILD
|GROUP_RANGE
|GROUP_OPENSSL
|GROUP_RETRY
, /* bitwise OR of address groups this address belongs to.
83 You might have to specify a new group in xioopts.h */
84 0, /* an integer passed to xioopen_openssl_listen; makes it possible to
85 use the same xioopen_openssl_listen function for slightly different
87 0, /* like previous argument */
88 0 /* like previous arguments, but pointer type.
89 No trailing comma or semicolon! */
90 HELP(":<port>") /* a text displayed from xio help function.
91 No trailing comma or semicolon!
92 only generates this text if WITH_HELP is != 0 */
94 #endif /* WITH_LISTEN */
96 /* both client and server */
97 const struct optdesc opt_openssl_cipherlist
= { "openssl-cipherlist", "ciphers", OPT_OPENSSL_CIPHERLIST
, GROUP_OPENSSL
, PH_SPEC
, TYPE_STRING
, OFUNC_SPEC
};
98 const struct optdesc opt_openssl_method
= { "openssl-method", "method", OPT_OPENSSL_METHOD
, GROUP_OPENSSL
, PH_SPEC
, TYPE_STRING
, OFUNC_SPEC
};
99 const struct optdesc opt_openssl_verify
= { "openssl-verify", "verify", OPT_OPENSSL_VERIFY
, GROUP_OPENSSL
, PH_SPEC
, TYPE_BOOL
, OFUNC_SPEC
};
100 const struct optdesc opt_openssl_certificate
= { "openssl-certificate", "cert", OPT_OPENSSL_CERTIFICATE
, GROUP_OPENSSL
, PH_SPEC
, TYPE_FILENAME
, OFUNC_SPEC
};
101 const struct optdesc opt_openssl_key
= { "openssl-key", "key", OPT_OPENSSL_KEY
, GROUP_OPENSSL
, PH_SPEC
, TYPE_FILENAME
, OFUNC_SPEC
};
102 const struct optdesc opt_openssl_dhparam
= { "openssl-dhparam", "dh", OPT_OPENSSL_DHPARAM
, GROUP_OPENSSL
, PH_SPEC
, TYPE_FILENAME
, OFUNC_SPEC
};
103 const struct optdesc opt_openssl_cafile
= { "openssl-cafile", "cafile", OPT_OPENSSL_CAFILE
, GROUP_OPENSSL
, PH_SPEC
, TYPE_FILENAME
, OFUNC_SPEC
};
104 const struct optdesc opt_openssl_capath
= { "openssl-capath", "capath", OPT_OPENSSL_CAPATH
, GROUP_OPENSSL
, PH_SPEC
, TYPE_FILENAME
, OFUNC_SPEC
};
105 const struct optdesc opt_openssl_egd
= { "openssl-egd", "egd", OPT_OPENSSL_EGD
, GROUP_OPENSSL
, PH_SPEC
, TYPE_FILENAME
, OFUNC_SPEC
};
106 const struct optdesc opt_openssl_pseudo
= { "openssl-pseudo", "pseudo", OPT_OPENSSL_PSEUDO
, GROUP_OPENSSL
, PH_SPEC
, TYPE_BOOL
, OFUNC_SPEC
};
108 const struct optdesc opt_openssl_fips
= { "openssl-fips", "fips", OPT_OPENSSL_FIPS
, GROUP_OPENSSL
, PH_SPEC
, TYPE_BOOL
, OFUNC_SPEC
};
112 /* If FIPS is compiled in, we need to track if the user asked for FIPS mode.
113 * On forks, the FIPS mode must be reset by a disable, then enable since
114 * FIPS tracks the process ID that initializes things.
115 * If FIPS is not compiled in, no tracking variable is needed
116 * and we make the reset code compile out. This keeps the
117 * rest of the code below free of FIPS related #ifs
120 static bool xio_openssl_fips
= false;
121 int xio_reset_fips_mode(void) {
122 if (xio_openssl_fips
) {
123 if(!sycFIPS_mode_set(0) || !sycFIPS_mode_set(1)) {
124 ERR_load_crypto_strings();
125 ERR_print_errors(BIO_new_fp(stderr
,BIO_NOCLOSE
));
126 Error("Failed to reset OpenSSL FIPS mode");
127 xio_openssl_fips
= false;
134 #define xio_reset_fips_mode() 0
137 /* the open function for OpenSSL client */
139 xioopen_openssl_connect(int argc
,
140 const char *argv
[], /* the arguments in the address string */
142 int xioflags
, /* is the open meant for reading (0),
143 writing (1), or both (2) ? */
144 xiofile_t
*xxfd
, /* a xio file descriptor structure,
146 unsigned groups
, /* the matching address groups... */
147 int dummy1
, /* first transparent integer value from
149 int dummy2
, /* second transparent integer value from
151 int dummy3
) /* transparent pointer value from
154 struct single
*xfd
= &xxfd
->stream
;
155 struct opt
*opts0
= NULL
;
156 const char *hostname
, *portname
;
158 int ipproto
= IPPROTO_TCP
;
159 int socktype
= SOCK_STREAM
;
161 union sockaddr_union us_sa
, *us
= &us_sa
;
162 union sockaddr_union them_sa
, *them
= &them_sa
;
163 socklen_t uslen
= sizeof(us_sa
);
164 socklen_t themlen
= sizeof(them_sa
);
165 bool needbind
= false;
166 bool lowport
= false;
169 bool opt_ver
= true; /* verify peer certificate */
170 char *opt_cert
= NULL
; /* file name of client certificate */
173 if (!(xioflags
& XIO_MAYCONVERT
)) {
174 Error("address with data processing not allowed here");
177 xfd
->flags
|= XIO_DOESCONVERT
;
180 Error1("%s: 2 parameters required", argv
[0]);
186 xfd
->howtoend
= END_SHUTDOWN
;
187 if (applyopts_single(xfd
, opts
, PH_INIT
) < 0) return -1;
188 applyopts(-1, opts
, PH_INIT
);
190 retropt_bool(opts
, OPT_FORK
, &dofork
);
192 retropt_string(opts
, OPT_OPENSSL_CERTIFICATE
, &opt_cert
);
195 _xioopen_openssl_prepare(opts
, xfd
, false, &opt_ver
, opt_cert
, &ctx
);
196 if (result
!= STAT_OK
) return STAT_NORETRY
;
199 _xioopen_ipapp_prepare(opts
, &opts0
, hostname
, portname
, &pf
, ipproto
,
200 xfd
->para
.socket
.ip
.res_opts
[1],
201 xfd
->para
.socket
.ip
.res_opts
[0],
202 them
, &themlen
, us
, &uslen
,
203 &needbind
, &lowport
, socktype
);
204 if (result
!= STAT_OK
) return STAT_NORETRY
;
206 if (xioopts
.logopt
== 'm') {
207 Info("starting connect loop, switching to syslog");
208 diag_set('y', xioopts
.syslogfac
); xioopts
.logopt
= 'y';
210 Info("starting connect loop");
213 do { /* loop over failed connect and SSL handshake attempts */
216 if (xfd
->forever
|| xfd
->retry
) {
219 #endif /* WITH_RETRY */
222 /* this cannot fork because we retrieved fork option above */
224 _xioopen_connect(xfd
,
225 needbind
?(struct sockaddr
*)us
:NULL
, sizeof(*us
),
226 (struct sockaddr
*)them
, themlen
,
227 opts
, pf
, socktype
, ipproto
, lowport
, level
);
231 case STAT_RETRYLATER
:
233 if (xfd
->forever
|| xfd
->retry
) {
234 dropopts(opts
, PH_ALL
); opts
= copyopts(opts0
, GROUP_ALL
);
235 if (result
== STAT_RETRYLATER
) {
236 Nanosleep(&xfd
->intervall
, NULL
);
242 #endif /* WITH_RETRY */
247 /*! isn't this too early? */
248 if ((result
= _xio_openlate(xfd
, opts
)) < 0) {
252 result
= _xioopen_openssl_connect(xfd
, opt_ver
, ctx
, level
);
256 case STAT_RETRYLATER
:
258 if (xfd
->forever
|| xfd
->retry
) {
260 dropopts(opts
, PH_ALL
); opts
= copyopts(opts0
, GROUP_ALL
);
261 if (result
== STAT_RETRYLATER
) {
262 Nanosleep(&xfd
->intervall
, NULL
);
267 #endif /* WITH_RETRY */
268 default: return STAT_NORETRY
;
272 xiosetchilddied(); /* set SIGCHLD handler */
279 if (xfd
->forever
|| xfd
->retry
) {
282 while ((pid
= xio_fork(false, level
)) < 0) {
283 if (xfd
->forever
|| --xfd
->retry
) {
284 Nanosleep(&xfd
->intervall
, NULL
); continue;
286 return STAT_RETRYLATER
;
289 if (pid
== 0) { /* child process */
290 xfd
->forever
= false; xfd
->retry
= 0;
296 sycSSL_free(xfd
->para
.openssl
.ssl
);
297 xfd
->para
.openssl
.ssl
= NULL
;
298 /* with and without retry */
299 Nanosleep(&xfd
->intervall
, NULL
);
300 dropopts(opts
, PH_ALL
); opts
= copyopts(opts0
, GROUP_ALL
);
301 continue; /* with next socket() bind() connect() */
303 #endif /* WITH_RETRY */
305 } while (true); /* drop out on success */
307 Notice1("SSL connection using %s", SSL_get_cipher(xfd
->para
.openssl
.ssl
));
309 /* fill in the fd structure */
314 /* this function is typically called within the OpenSSL client fork/retry loop.
315 xfd must be of type DATA_OPENSSL, and its fd must be set with a valid file
316 descriptor. this function then performs all SSL related step to make a valid
317 SSL connection from an FD and a CTX. */
318 int _xioopen_openssl_connect(struct single
*xfd
,
326 /* create a SSL object */
327 if ((ssl
= sycSSL_new(ctx
)) == NULL
) {
328 if (ERR_peek_error() == 0) Msg(level
, "SSL_new() failed");
329 while (err
= ERR_get_error()) {
330 Msg1(level
, "SSL_new(): %s", ERR_error_string(err
, NULL
));
332 /*Error("SSL_new()");*/
333 return STAT_RETRYLATER
;
335 xfd
->para
.openssl
.ssl
= ssl
;
337 result
= xioSSL_set_fd(xfd
, level
);
338 if (result
!= STAT_OK
) {
339 sycSSL_free(xfd
->para
.openssl
.ssl
);
340 xfd
->para
.openssl
.ssl
= NULL
;
344 result
= xioSSL_connect(xfd
, opt_ver
, level
);
345 if (result
!= STAT_OK
) {
346 sycSSL_free(xfd
->para
.openssl
.ssl
);
347 xfd
->para
.openssl
.ssl
= NULL
;
351 result
= openssl_handle_peer_certificate(xfd
, opt_ver
, level
);
352 if (result
!= STAT_OK
) {
353 sycSSL_free(xfd
->para
.openssl
.ssl
);
354 xfd
->para
.openssl
.ssl
= NULL
;
365 xioopen_openssl_listen(int argc
,
366 const char *argv
[], /* the arguments in the address string */
368 int xioflags
, /* is the open meant for reading (0),
369 writing (1), or both (2) ? */
370 xiofile_t
*xxfd
, /* a xio file descriptor structure,
372 unsigned groups
, /* the matching address groups... */
373 int dummy1
, /* first transparent integer value from
375 int dummy2
, /* second transparent integer value from
377 int dummy3
) /* transparent pointer value from
380 struct single
*xfd
= &xxfd
->stream
;
381 const char *portname
;
382 struct opt
*opts0
= NULL
;
383 union sockaddr_union us_sa
, *us
= &us_sa
;
384 socklen_t uslen
= sizeof(us_sa
);
386 int socktype
= SOCK_STREAM
;
387 int ipproto
= IPPROTO_TCP
;
391 bool opt_ver
= true; /* verify peer certificate - changed with 1.6.0 */
392 char *opt_cert
= NULL
; /* file name of server certificate */
395 if (!(xioflags
& XIO_MAYCONVERT
)) {
396 Error("address with data processing not allowed here");
399 xfd
->flags
|= XIO_DOESCONVERT
;
402 Error1("%s: 1 parameter required", argv
[0]);
406 #if WITH_IP4 && WITH_IP6
407 pf
= xioopts
.default_ip
=='6'?PF_INET6
:PF_INET
;
416 xfd
->howtoend
= END_SHUTDOWN
;
417 if (applyopts_single(xfd
, opts
, PH_INIT
) < 0) return -1;
418 applyopts(-1, opts
, PH_INIT
);
420 retropt_string(opts
, OPT_OPENSSL_CERTIFICATE
, &opt_cert
);
421 if (opt_cert
== NULL
) {
422 Warn("no certificate given; consider option \"cert\"");
425 applyopts(-1, opts
, PH_EARLY
);
428 _xioopen_openssl_prepare(opts
, xfd
, true, &opt_ver
, opt_cert
, &ctx
);
429 if (result
!= STAT_OK
) return STAT_NORETRY
;
431 if (_xioopen_ipapp_listen_prepare(opts
, &opts0
, portname
, &pf
, ipproto
,
432 xfd
->para
.socket
.ip
.res_opts
[1],
433 xfd
->para
.socket
.ip
.res_opts
[0],
434 us
, &uslen
, socktype
)
439 xfd
->addr
= &addr_openssl_listen
;
440 xfd
->dtype
= XIODATA_OPENSSL
;
442 while (true) { /* loop over failed attempts */
445 if (xfd
->forever
|| xfd
->retry
) {
448 #endif /* WITH_RETRY */
451 /* tcp listen; this can fork() for us; it only returns on error or on
452 successful establishment of tcp connection */
453 result
= _xioopen_listen(xfd
, xioflags
,
454 (struct sockaddr
*)us
, uslen
,
455 opts
, pf
, socktype
, IPPROTO_TCP
,
457 (xfd
->retry
||xfd
->forever
)?E_INFO
:E_ERROR
460 #endif /* WITH_RETRY */
462 /*! not sure if we should try again on retry/forever */
466 case STAT_RETRYLATER
:
468 if (xfd
->forever
|| xfd
->retry
) {
469 dropopts(opts
, PH_ALL
); opts
= copyopts(opts0
, GROUP_ALL
);
470 if (result
== STAT_RETRYLATER
) {
471 Nanosleep(&xfd
->intervall
, NULL
);
473 dropopts(opts
, PH_ALL
); opts
= copyopts(opts0
, GROUP_ALL
);
478 #endif /* WITH_RETRY */
483 result
= _xioopen_openssl_listen(xfd
, opt_ver
, ctx
, level
);
487 case STAT_RETRYLATER
:
489 if (xfd
->forever
|| xfd
->retry
) {
490 dropopts(opts
, PH_ALL
); opts
= copyopts(opts0
, GROUP_ALL
);
491 if (result
== STAT_RETRYLATER
) {
492 Nanosleep(&xfd
->intervall
, NULL
);
494 dropopts(opts
, PH_ALL
); opts
= copyopts(opts0
, GROUP_ALL
);
499 #endif /* WITH_RETRY */
504 Notice1("SSL connection using %s",
505 SSL_get_cipher(xfd
->para
.openssl
.ssl
));
508 } /* drop out on success */
510 /* fill in the fd structure */
516 int _xioopen_openssl_listen(struct single
*xfd
,
520 char error_string
[120];
524 /* create an SSL object */
525 if ((xfd
->para
.openssl
.ssl
= sycSSL_new(ctx
)) == NULL
) {
526 if (ERR_peek_error() == 0) Msg(level
, "SSL_new() failed");
527 while (err
= ERR_get_error()) {
528 Msg1(level
, "SSL_new(): %s", ERR_error_string(err
, NULL
));
530 /*Error("SSL_new()");*/
534 /* assign the network connection to the SSL object */
535 if (sycSSL_set_fd(xfd
->para
.openssl
.ssl
, xfd
->fd
) <= 0) {
536 if (ERR_peek_error() == 0) Msg(level
, "SSL_set_fd() failed");
537 while (err
= ERR_get_error()) {
538 Msg2(level
, "SSL_set_fd(, %d): %s",
539 xfd
->fd
, ERR_error_string(err
, NULL
));
546 const char *ciphers
= NULL
;
547 Debug("available ciphers:");
549 ciphers
= SSL_get_cipher_list(xfd
->para
.openssl
.ssl
, i
);
550 if (ciphers
== NULL
) break;
551 Debug2("CIPHERS pri=%d: %s", i
, ciphers
);
555 #endif /* WITH_DEBUG */
557 /* connect via SSL by performing handshake */
558 if ((ret
= sycSSL_accept(xfd
->para
.openssl
.ssl
)) <= 0) {
559 /*if (ERR_peek_error() == 0) Msg(level, "SSL_accept() failed");*/
560 errint
= SSL_get_error(xfd
->para
.openssl
.ssl
, ret
);
563 Msg(level
, "ok"); break;
564 case SSL_ERROR_ZERO_RETURN
:
565 Msg(level
, "connection closed (wrong version number?)"); break;
566 case SSL_ERROR_WANT_READ
: case SSL_ERROR_WANT_WRITE
:
567 case SSL_ERROR_WANT_CONNECT
:
568 case SSL_ERROR_WANT_X509_LOOKUP
:
569 Msg(level
, "nonblocking operation did not complete"); break; /*!*/
570 case SSL_ERROR_SYSCALL
:
571 if (ERR_peek_error() == 0) {
573 Msg(level
, "SSL_accept(): socket closed by peer");
574 } else if (ret
== -1) {
575 Msg1(level
, "SSL_accept(): %s", strerror(errno
));
578 Msg(level
, "I/O error"); /*!*/
579 while (err
= ERR_get_error()) {
580 ERR_error_string_n(err
, error_string
, sizeof(error_string
));
581 Msg4(level
, "SSL_accept(): %s / %s / %s / %s", error_string
,
582 ERR_lib_error_string(err
), ERR_func_error_string(err
),
583 ERR_reason_error_string(err
));
585 /* Msg1(level, "SSL_connect(): %s", ERR_error_string(e, buf));*/
589 /*ERR_print_errors_fp(stderr);*/
590 openssl_SSL_ERROR_SSL(level
, "SSL_accept");
593 Msg(level
, "unknown error");
596 return STAT_RETRYLATER
;
599 if (openssl_handle_peer_certificate(xfd
, opt_ver
, E_ERROR
/*!*/) < 0) {
606 #endif /* WITH_LISTEN */
610 _xioopen_openssl_prepare(struct opt
*opts
,
611 struct single
*xfd
,/* a xio file descriptor
612 structure, already allocated
614 bool server
, /* SSL client: false */
616 const char *opt_cert
,
619 bool opt_fips
= false;
621 char *me_str
= NULL
; /* method string */
622 char *ci_str
= NULL
; /* cipher string */
623 char *opt_key
= NULL
; /* file name of client private key */
624 char *opt_dhparam
= NULL
; /* file name of DH params */
625 char *opt_cafile
= NULL
; /* certificate authority file */
626 char *opt_capath
= NULL
; /* certificate authority directory */
627 char *opt_egd
= NULL
; /* entropy gathering daemon socket path */
628 bool opt_pseudo
= false; /* use pseudo entropy if nothing else */
632 xfd
->addr
= &addr_openssl
;
633 xfd
->dtype
= XIODATA_OPENSSL
;
635 retropt_bool(opts
, OPT_OPENSSL_FIPS
, &opt_fips
);
636 retropt_string(opts
, OPT_OPENSSL_METHOD
, &me_str
);
637 retropt_string(opts
, OPT_OPENSSL_CIPHERLIST
, &ci_str
);
638 retropt_bool(opts
, OPT_OPENSSL_VERIFY
, opt_ver
);
639 retropt_string(opts
, OPT_OPENSSL_CAFILE
, &opt_cafile
);
640 retropt_string(opts
, OPT_OPENSSL_CAPATH
, &opt_capath
);
641 retropt_string(opts
, OPT_OPENSSL_KEY
, &opt_key
);
642 retropt_string(opts
, OPT_OPENSSL_DHPARAM
, &opt_dhparam
);
643 retropt_string(opts
, OPT_OPENSSL_EGD
, &opt_egd
);
644 retropt_bool(opts
,OPT_OPENSSL_PSEUDO
, &opt_pseudo
);
648 if (!sycFIPS_mode_set(1)) {
649 ERR_load_crypto_strings();
650 ERR_print_errors(BIO_new_fp(stderr
,BIO_NOCLOSE
));
651 Error("Failed to set FIPS mode");
653 xio_openssl_fips
= true;
658 OpenSSL_add_all_algorithms();
659 OpenSSL_add_all_ciphers();
660 OpenSSL_add_all_digests();
661 sycSSL_load_error_strings();
663 /* OpenSSL preparation */
664 sycSSL_library_init();
666 /*! actions_to_seed_PRNG();*/
670 if (!strcasecmp(me_str
, "SSLv2") || !strcasecmp(me_str
, "SSL2")) {
671 method
= sycSSLv2_client_method();
672 } else if (!strcasecmp(me_str
, "SSLv3") || !strcasecmp(me_str
, "SSL3")) {
673 method
= sycSSLv3_client_method();
674 } else if (!strcasecmp(me_str
, "SSLv23") || !strcasecmp(me_str
, "SSL23") ||
675 !strcasecmp(me_str
, "SSL")) {
676 method
= sycSSLv23_client_method();
677 } else if (!strcasecmp(me_str
, "TLSv1") || !strcasecmp(me_str
, "TLS1") ||
678 !strcasecmp(me_str
, "TLS")) {
679 method
= sycTLSv1_client_method();
681 Error1("openssl-method=\"%s\": unknown method", me_str
);
682 method
= sycSSLv23_client_method()/*!*/;
685 method
= sycSSLv23_client_method()/*!*/;
687 } else /* server */ {
689 if (!strcasecmp(me_str
, "SSLv2") || !strcasecmp(me_str
, "SSL2")) {
690 method
= sycSSLv2_server_method();
691 } else if (!strcasecmp(me_str
, "SSLv3") || !strcasecmp(me_str
, "SSL3")) {
692 method
= sycSSLv3_server_method();
693 } else if (!strcasecmp(me_str
, "SSLv23") || !strcasecmp(me_str
, "SSL23") ||
694 !strcasecmp(me_str
, "SSL")) {
695 method
= sycSSLv23_server_method();
696 } else if (!strcasecmp(me_str
, "TLSv1") || !strcasecmp(me_str
, "TLS1") ||
697 !strcasecmp(me_str
, "TLS")) {
698 method
= sycTLSv1_server_method();
700 Error1("openssl-method=\"%s\": unknown method", me_str
);
701 method
= sycSSLv23_server_method()/*!*/;
704 method
= sycSSLv23_server_method()/*!*/;
709 sycRAND_egd(opt_egd
);
714 /* initialize libc random from actual microseconds */
717 tz
.tz_minuteswest
= 0;
719 if ((result
= Gettimeofday(&tv
, &tz
)) < 0) {
720 Warn2("gettimeofday(%p, {0,0}): %s", &tv
, strerror(errno
));
722 srandom(tv
.tv_sec
*1000000+tv
.tv_usec
);
724 while (!RAND_status()) {
726 Debug2("RAND_seed(0x{%lx}, "F_Zu
")",
727 randdata
, sizeof(randdata
));
728 RAND_seed(&randdata
, sizeof(randdata
));
732 if ((*ctx
= sycSSL_CTX_new(method
)) == NULL
) {
733 if (ERR_peek_error() == 0) Error("SSL_CTX_new()");
734 while (err
= ERR_get_error()) {
735 Error1("SSL_CTX_new(): %s", ERR_error_string(err
, NULL
));
739 return STAT_RETRYLATER
;
742 if (opt_cafile
!= NULL
|| opt_capath
!= NULL
) {
743 if (sycSSL_CTX_load_verify_locations(*ctx
, opt_cafile
, opt_capath
) != 1) {
747 openssl_SSL_ERROR_SSL(E_ERROR
, "SSL_CTX_load_verify_locations"))
750 return STAT_RETRYLATER
;
759 if (sycSSL_CTX_use_certificate_chain_file(*ctx
, opt_cert
) <= 0) {
760 /*! trace functions */
761 /*0 ERR_print_errors_fp(stderr);*/
762 if (ERR_peek_error() == 0)
763 Error2("SSL_CTX_use_certificate_file(%p, \"%s\", SSL_FILETYPE_PEM) failed",
765 while (err
= ERR_get_error()) {
766 Error1("SSL_CTX_use_certificate_file(): %s",
767 ERR_error_string(err
, NULL
));
769 return STAT_RETRYLATER
;
772 if (sycSSL_CTX_use_PrivateKey_file(*ctx
, opt_key
?opt_key
:opt_cert
, SSL_FILETYPE_PEM
) <= 0) {
773 /*ERR_print_errors_fp(stderr);*/
774 openssl_SSL_ERROR_SSL(E_ERROR
/*!*/, "SSL_CTX_use_PrivateKey_file");
775 return STAT_RETRYLATER
;
778 if (opt_dhparam
== NULL
) {
779 opt_dhparam
= (char *)opt_cert
;
781 if ((bio
= sycBIO_new_file(opt_dhparam
, "r")) == NULL
) {
782 Warn2("BIO_new_file(\"%s\", \"r\"): %s",
783 opt_dhparam
, strerror(errno
));
785 if ((dh
= sycPEM_read_bio_DHparams(bio
, NULL
, NULL
, NULL
)) == NULL
) {
786 Info1("PEM_read_bio_DHparams(%p, NULL, NULL, NULL): error", bio
);
789 if (sycSSL_CTX_set_tmp_dh(*ctx
, dh
) == 0) {
790 Error2("SSL_CTX_set_tmp_dh(%p, %p): error", ctx
, dh
);
796 /* set pre ssl-connect options */
798 if (ci_str
!= NULL
) {
799 if (sycSSL_CTX_set_cipher_list(*ctx
, ci_str
) <= 0) {
800 if (ERR_peek_error() == 0)
801 Error1("SSL_set_cipher_list(, \"%s\") failed", ci_str
);
802 while (err
= ERR_get_error()) {
803 Error2("SSL_set_cipher_list(, \"%s\"): %s",
804 ci_str
, ERR_error_string(err
, NULL
));
806 /*Error("SSL_new()");*/
807 return STAT_RETRYLATER
;
812 sycSSL_CTX_set_verify(*ctx
,
813 SSL_VERIFY_PEER
| SSL_VERIFY_FAIL_IF_NO_PEER_CERT
,
816 sycSSL_CTX_set_verify(*ctx
,
825 /* analyses an OpenSSL error condition, prints the appropriate messages with
826 severity 'level' and returns one of STAT_OK, STAT_RETRYLATER, or
828 static int openssl_SSL_ERROR_SSL(int level
, const char *funcname
) {
830 char buf
[120]; /* this value demanded by "man ERR_error_string" */
833 Debug1("ERR_get_error(): %lx", e
);
834 if (e
== ((ERR_LIB_RAND
<<24)|
835 (RAND_F_SSLEAY_RAND_BYTES
<<12)|
836 (RAND_R_PRNG_NOT_SEEDED
)) /*0x24064064*/) {
837 Error("too few entropy; use options \"egd\" or \"pseudo\"");
840 Msg2(level
, "%s(): %s", funcname
, ERR_error_string(e
, buf
));
841 return level
==E_ERROR
? STAT_NORETRY
: STAT_RETRYLATER
;
846 static const char *openssl_verify_messages
[] = {
849 /* 2 */ "unable to get issuer certificate",
850 /* 3 */ "unable to get certificate CRL",
851 /* 4 */ "unable to decrypt certificate's signature",
852 /* 5 */ "unable to decrypt CRL's signature",
853 /* 6 */ "unable to decode issuer public key",
854 /* 7 */ "certificate signature failure",
855 /* 8 */ "CRL signature failure",
856 /* 9 */ "certificate is not yet valid",
857 /* 10 */ "certificate has expired",
858 /* 11 */ "CRL is not yet valid",
859 /* 12 */ "CRL has expired",
860 /* 13 */ "format error in certificate's notBefore field",
861 /* 14 */ "format error in certificate's notAfter field",
862 /* 15 */ "format error in CRL's lastUpdate field",
863 /* 16 */ "format error in CRL's nextUpdate field",
864 /* 17 */ "out of memory",
865 /* 18 */ "self signed certificate",
866 /* 19 */ "self signed certificate in certificate chain",
867 /* 20 */ "unable to get local issuer certificate",
868 /* 21 */ "unable to verify the first certificate",
869 /* 22 */ "certificate chain too long",
870 /* 23 */ "certificate revoked",
871 /* 24 */ "invalid CA certificate",
872 /* 25 */ "path length constraint exceeded",
873 /* 26 */ "unsupported certificate purpose",
874 /* 27 */ "certificate not trusted",
875 /* 28 */ "certificate rejected",
876 /* 29 */ "subject issuer mismatch",
877 /* 30 */ "authority and subject key identifier mismatch",
878 /* 31 */ "authority and issuer serial number mismatch",
879 /* 32 */ "key usage does not include certificate signing",
897 /* 50 */ "application verification failure",
900 static int openssl_handle_peer_certificate(struct single
*xfd
,
901 bool opt_ver
, int level
) {
904 char buff
[2048]; /* hold peer certificate */
907 /* SSL_CTX_add_extra_chain_cert
908 SSL_get_verify_result
910 if ((peer_cert
= SSL_get_peer_certificate(xfd
->para
.openssl
.ssl
)) != NULL
) {
911 Debug("peer certificate:");
912 if ((str
= X509_NAME_oneline(X509_get_subject_name(peer_cert
), buff
, sizeof(buff
))) != NULL
)
913 Debug1("\tsubject: %s", str
); /*free (str); SIGSEGV*/
914 if ((str
= X509_NAME_oneline(X509_get_issuer_name(peer_cert
), buff
, sizeof(buff
))) != NULL
)
915 Debug1("\tissuer: %s", str
); /*free (str); SIGSEGV*/
921 if ((verify_result
= sycSSL_get_verify_result(xfd
->para
.openssl
.ssl
)) == X509_V_OK
) {
922 Info("accepted peer certificate");
925 const char *message
= NULL
;
926 if (verify_result
>= 0 &&
927 (size_t)verify_result
<
928 sizeof(openssl_verify_messages
)/sizeof(char*))
930 message
= openssl_verify_messages
[verify_result
];
933 Msg1(level
, "%s", message
);
935 Msg1(level
, "rejected peer certificate with error %ld", verify_result
);
937 status
= STAT_RETRYLATER
;
940 Notice("no check of certificate");
945 Msg(level
, "no peer certificate");
946 status
= STAT_RETRYLATER
;
948 Notice("no peer certificate and no check");
953 X509_free(peer_cert
);
957 static int xioSSL_set_fd(struct single
*xfd
, int level
) {
960 /* assign a network connection to the SSL object */
961 if (sycSSL_set_fd(xfd
->para
.openssl
.ssl
, xfd
->fd
) <= 0) {
962 Msg(level
, "SSL_set_fd() failed");
963 while (err
= ERR_get_error()) {
964 Msg2(level
, "SSL_set_fd(, %d): %s",
965 xfd
->fd
, ERR_error_string(err
, NULL
));
967 return STAT_RETRYLATER
;
974 in case of an error condition, this function check forever and retry
975 options and ev. sleeps an interval. It returns NORETRY when the caller
976 should not retry for any reason. */
977 static int xioSSL_connect(struct single
*xfd
, bool opt_ver
, int level
) {
978 char error_string
[120];
979 int errint
, status
, ret
;
982 /* connect via SSL by performing handshake */
983 if ((ret
= sycSSL_connect(xfd
->para
.openssl
.ssl
)) <= 0) {
984 /*if (ERR_peek_error() == 0) Msg(level, "SSL_connect() failed");*/
985 errint
= SSL_get_error(xfd
->para
.openssl
.ssl
, ret
);
988 /* this is not an error, but I dare not continue for security reasons*/
990 status
= STAT_RETRYLATER
;
991 case SSL_ERROR_ZERO_RETURN
:
992 Msg(level
, "connection closed (wrong version number?)");
993 status
= STAT_RETRYLATER
;
995 case SSL_ERROR_WANT_READ
:
996 case SSL_ERROR_WANT_WRITE
:
997 case SSL_ERROR_WANT_CONNECT
:
998 case SSL_ERROR_WANT_X509_LOOKUP
:
999 Msg(level
, "nonblocking operation did not complete");
1000 status
= STAT_RETRYLATER
;
1002 case SSL_ERROR_SYSCALL
:
1003 if (ERR_peek_error() == 0) {
1005 Msg(level
, "SSL_connect(): socket closed by peer");
1006 } else if (ret
== -1) {
1007 Msg1(level
, "SSL_connect(): %s", strerror(errno
));
1010 Msg(level
, "I/O error"); /*!*/
1011 while (err
= ERR_get_error()) {
1012 ERR_error_string_n(err
, error_string
, sizeof(error_string
));
1013 Msg4(level
, "SSL_connect(): %s / %s / %s / %s", error_string
,
1014 ERR_lib_error_string(err
), ERR_func_error_string(err
),
1015 ERR_reason_error_string(err
));
1018 status
= STAT_RETRYLATER
;
1021 status
= openssl_SSL_ERROR_SSL(level
, "SSL_connect");
1022 if (openssl_handle_peer_certificate(xfd
, opt_ver
, level
/*!*/) < 0) {
1023 return STAT_RETRYLATER
;
1027 Msg(level
, "unknown error");
1028 status
= STAT_RETRYLATER
;
1036 /* on result < 0: errno is set (at least to EIO) */
1037 ssize_t
xioread_openssl(struct single
*pipe
, void *buff
, size_t bufsiz
) {
1039 char error_string
[120];
1040 int _errno
= EIO
; /* if we have no better idea about nature of error */
1043 ret
= sycSSL_read(pipe
->para
.openssl
.ssl
, buff
, bufsiz
);
1045 errint
= SSL_get_error(pipe
->para
.openssl
.ssl
, ret
);
1047 case SSL_ERROR_NONE
:
1048 /* this is not an error, but I dare not continue for security reasons*/
1050 case SSL_ERROR_ZERO_RETURN
:
1051 Error("connection closed by peer");
1053 case SSL_ERROR_WANT_READ
:
1054 case SSL_ERROR_WANT_WRITE
:
1055 case SSL_ERROR_WANT_CONNECT
:
1056 case SSL_ERROR_WANT_X509_LOOKUP
:
1057 Error("nonblocking operation did not complete");
1059 case SSL_ERROR_SYSCALL
:
1060 if (ERR_peek_error() == 0) {
1062 Error("SSL_read(): socket closed by peer");
1063 } else if (ret
== -1) {
1065 Error1("SSL_read(): %s", strerror(errno
));
1068 Error("I/O error"); /*!*/
1069 while (err
= ERR_get_error()) {
1070 ERR_error_string_n(err
, error_string
, sizeof(error_string
));
1071 Error4("SSL_read(): %s / %s / %s / %s", error_string
,
1072 ERR_lib_error_string(err
), ERR_func_error_string(err
),
1073 ERR_reason_error_string(err
));
1078 openssl_SSL_ERROR_SSL(E_ERROR
, "SSL_connect");
1081 Error("unknown error");
1090 ssize_t
xiopending_openssl(struct single
*pipe
) {
1091 int bytes
= sycSSL_pending(pipe
->para
.openssl
.ssl
);
1095 /* on result < 0: errno is set (at least to EIO) */
1096 ssize_t
xiowrite_openssl(struct single
*pipe
, const void *buff
, size_t bufsiz
) {
1098 char error_string
[120];
1099 int _errno
= EIO
; /* if we have no better idea about nature of error */
1102 ret
= sycSSL_write(pipe
->para
.openssl
.ssl
, buff
, bufsiz
);
1104 errint
= SSL_get_error(pipe
->para
.openssl
.ssl
, ret
);
1106 case SSL_ERROR_NONE
:
1107 /* this is not an error, but I dare not continue for security reasons*/
1109 case SSL_ERROR_ZERO_RETURN
:
1110 Error("connection closed by peer");
1112 case SSL_ERROR_WANT_READ
:
1113 case SSL_ERROR_WANT_WRITE
:
1114 case SSL_ERROR_WANT_CONNECT
:
1115 case SSL_ERROR_WANT_X509_LOOKUP
:
1116 Error("nonblocking operation did not complete");
1118 case SSL_ERROR_SYSCALL
:
1119 if (ERR_peek_error() == 0) {
1121 Error("SSL_write(): socket closed by peer");
1122 } else if (ret
== -1) {
1124 Error1("SSL_write(): %s", strerror(errno
));
1127 Error("I/O error"); /*!*/
1128 while (err
= ERR_get_error()) {
1129 ERR_error_string_n(err
, error_string
, sizeof(error_string
));
1130 Error4("SSL_write(): %s / %s / %s / %s", error_string
,
1131 ERR_lib_error_string(err
), ERR_func_error_string(err
),
1132 ERR_reason_error_string(err
));
1137 openssl_SSL_ERROR_SSL(E_ERROR
, "SSL_connect");
1140 Error("unknown error");
1150 #endif /* WITH_OPENSSL */