30 report_errors(SSL* ssl)
38 DBUG_ENTER(
"report_errors");
40 while ((l= ERR_get_error_line_data(&file,&line,&data,&flags)))
42 DBUG_PRINT(
"error", (
"OpenSSL: %s:%s:%d:%s\n", ERR_error_string(l,buf),
43 file,line,(flags&ERR_TXT_STRING)?data:
"")) ;
47 DBUG_PRINT(
"error", (
"error: %s",
48 ERR_error_string(SSL_get_error(ssl, l), buf)));
50 DBUG_PRINT(
"info", (
"socket_errno: %d", socket_errno));
63 static void ssl_set_sys_error(
int ssl_error)
69 case SSL_ERROR_ZERO_RETURN:
70 error= SOCKET_ECONNRESET;
72 case SSL_ERROR_WANT_READ:
73 case SSL_ERROR_WANT_WRITE:
74 #ifdef SSL_ERROR_WANT_CONNECT
75 case SSL_ERROR_WANT_CONNECT:
77 #ifdef SSL_ERROR_WANT_ACCEPT
78 case SSL_ERROR_WANT_ACCEPT:
80 error= SOCKET_EWOULDBLOCK;
87 error= SOCKET_ECONNRESET;
90 case SSL_ERROR_SYSCALL:
100 WSASetLastError(error);
124 static my_bool ssl_should_retry(
Vio *vio,
int ret,
125 enum enum_vio_io_event *
event,
126 unsigned long *ssl_errno_holder)
129 SSL *ssl= vio->ssl_arg;
130 my_bool should_retry= TRUE;
133 ssl_error= SSL_get_error(ssl, ret);
138 case SSL_ERROR_WANT_READ:
139 *
event= VIO_IO_EVENT_READ;
141 case SSL_ERROR_WANT_WRITE:
142 *
event= VIO_IO_EVENT_WRITE;
155 ssl_set_sys_error(ssl_error);
159 *ssl_errno_holder= ssl_error;
165 size_t vio_ssl_read(
Vio *vio, uchar *buf,
size_t size)
168 SSL *ssl= vio->ssl_arg;
169 unsigned long ssl_errno_not_used;
171 DBUG_ENTER(
"vio_ssl_read");
175 enum enum_vio_io_event event;
183 DBUG_ASSERT(ERR_peek_error() == 0);
186 ret= SSL_read(ssl, buf, size);
192 if (!ssl_should_retry(vio, ret, &event, &ssl_errno_not_used))
196 if (vio_socket_io_wait(vio, event))
200 DBUG_RETURN(ret < 0 ? -1 : ret);
204 size_t vio_ssl_write(
Vio *vio,
const uchar *buf,
size_t size)
207 SSL *ssl= vio->ssl_arg;
208 unsigned long ssl_errno_not_used;
210 DBUG_ENTER(
"vio_ssl_write");
214 enum enum_vio_io_event event;
222 DBUG_ASSERT(ERR_peek_error() == 0);
225 ret= SSL_write(ssl, buf, size);
231 if (!ssl_should_retry(vio, ret, &event, &ssl_errno_not_used))
235 if (vio_socket_io_wait(vio, event))
239 DBUG_RETURN(ret < 0 ? -1 : ret);
245 static long yassl_recv(
void *ptr,
void *buf,
size_t len)
247 return vio_read(ptr, buf, len);
252 static long yassl_send(
void *ptr,
const void *buf,
size_t len)
254 return vio_write(ptr, buf, len);
259 int vio_ssl_shutdown(
Vio *vio)
262 SSL *ssl= (SSL*)vio->ssl_arg;
263 DBUG_ENTER(
"vio_ssl_shutdown");
275 SSL_set_quiet_shutdown(ssl, 1);
277 switch ((r= SSL_shutdown(ssl))) {
289 DBUG_PRINT(
"vio_error", (
"SSL_shutdown() failed, error: %d",
290 SSL_get_error(ssl, r)));
294 DBUG_RETURN(vio_shutdown(vio));
298 void vio_ssl_delete(
Vio *vio)
303 if (vio->inactive == FALSE)
304 vio_ssl_shutdown(vio);
308 SSL_free((SSL*) vio->ssl_arg);
317 typedef int (*ssl_handshake_func_t)(SSL*);
331 static int ssl_handshake_loop(
Vio *vio, SSL *ssl,
332 ssl_handshake_func_t func,
333 unsigned long *ssl_errno_holder)
342 enum enum_vio_io_event event;
350 DBUG_ASSERT(ERR_peek_error() == 0);
359 if (!ssl_should_retry(vio, ret, &event, ssl_errno_holder))
363 if (vio_socket_io_wait(vio, event))
373 static int ssl_do(
struct st_VioSSLFd *ptr,
Vio *vio,
long timeout,
374 ssl_handshake_func_t func,
375 unsigned long *ssl_errno_holder)
379 my_socket sd= mysql_socket_getfd(vio->mysql_socket);
380 DBUG_ENTER(
"ssl_do");
381 DBUG_PRINT(
"enter", (
"ptr: 0x%lx, sd: %d ctx: 0x%lx",
382 (
long) ptr, sd, (
long) ptr->ssl_context));
384 if (!(ssl= SSL_new(ptr->ssl_context)))
386 DBUG_PRINT(
"error", (
"SSL_new failure"));
387 *ssl_errno_holder= ERR_get_error();
390 DBUG_PRINT(
"info", (
"ssl: 0x%lx timeout: %ld", (
long) ssl, timeout));
392 SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
395 SSL_set_options(ssl, SSL_OP_NO_COMPRESSION);
406 yaSSL_transport_set_ptr(ssl, vio);
408 yaSSL_transport_set_recv_function(ssl, yassl_recv);
409 yaSSL_transport_set_send_function(ssl, yassl_send);
412 if ((r= ssl_handshake_loop(vio, ssl, func, ssl_errno_holder)) < 1)
414 DBUG_PRINT(
"error", (
"SSL_connect/accept failure"));
424 if (vio_reset(vio, VIO_TYPE_SSL, SSL_get_fd(ssl), ssl, 0))
433 DBUG_PRINT(
"info",(
"SSL connection succeeded"));
434 DBUG_PRINT(
"info",(
"Using cipher: '%s'" , SSL_get_cipher_name(ssl)));
436 if ((cert= SSL_get_peer_certificate (ssl)))
438 DBUG_PRINT(
"info",(
"Peer certificate:"));
439 X509_NAME_oneline(X509_get_subject_name(cert), buf,
sizeof(buf));
440 DBUG_PRINT(
"info",(
"\t subject: '%s'", buf));
441 X509_NAME_oneline(X509_get_issuer_name(cert), buf,
sizeof(buf));
442 DBUG_PRINT(
"info",(
"\t issuer: '%s'", buf));
446 DBUG_PRINT(
"info",(
"Peer does not have certificate."));
448 if (SSL_get_shared_ciphers(ssl, buf,
sizeof(buf)))
450 DBUG_PRINT(
"info",(
"shared_ciphers: '%s'", buf));
453 DBUG_PRINT(
"info",(
"no shared ciphers!"));
461 int sslaccept(
struct st_VioSSLFd *ptr,
Vio *vio,
long timeout,
462 unsigned long *ssl_errno_holder)
464 DBUG_ENTER(
"sslaccept");
465 DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept, ssl_errno_holder));
469 int sslconnect(
struct st_VioSSLFd *ptr,
Vio *vio,
long timeout,
470 unsigned long *ssl_errno_holder)
472 DBUG_ENTER(
"sslconnect");
473 DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect, ssl_errno_holder));
477 my_bool vio_ssl_has_data(
Vio *vio)
479 return SSL_pending(vio->ssl_arg) > 0 ? TRUE : FALSE;