Commit b2d5243e authored by unknown's avatar unknown

Cleanup SSL implementation

Remove duplicate code
Merge common functions
Enforce MySQL coding standard


include/violite.h:
  Cleanup SSL implementation
sql-common/client.c:
  Cleanup SSL implementation
sql/mysql_priv.h:
  Cleanup SSL implementation
sql/mysqld.cc:
  Cleanup SSL implementation
sql/sql_acl.cc:
  Cleanup SSL implementation
vio/vio.c:
  Cleanup SSL implementation
vio/vio_priv.h:
  Cleanup SSL implementation
vio/viossl.c:
  Cleanup SSL implementation
vio/viosslfactories.c:
  Cleanup SSL implementation
parent 91b3447c
...@@ -105,33 +105,22 @@ void vio_timeout(Vio *vio,uint which, uint timeout); ...@@ -105,33 +105,22 @@ void vio_timeout(Vio *vio,uint which, uint timeout);
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
struct st_VioSSLAcceptorFd struct st_VioSSLFd
{ {
SSL_CTX *ssl_context; SSL_CTX *ssl_context;
SSL_METHOD *ssl_method;
struct st_VioSSLAcceptorFd *session_id_context;
}; };
/* One copy for client */ int sslaccept(struct st_VioSSLFd*, Vio *, long timeout);
struct st_VioSSLConnectorFd int sslconnect(struct st_VioSSLFd*, Vio *, long timeout);
{
SSL_CTX *ssl_context;
/* function pointers which are only once for SSL client */
SSL_METHOD *ssl_method;
};
int sslaccept(struct st_VioSSLAcceptorFd*, Vio *, long timeout);
int sslconnect(struct st_VioSSLConnectorFd*, Vio *, long timeout);
struct st_VioSSLConnectorFd struct st_VioSSLFd
*new_VioSSLConnectorFd(const char *key_file, const char *cert_file, *new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
const char *ca_file, const char *ca_path, const char *ca_file, const char *ca_path,
const char *cipher); const char *cipher);
struct st_VioSSLAcceptorFd struct st_VioSSLFd
*new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
const char *ca_file,const char *ca_path, const char *ca_file,const char *ca_path,
const char *cipher); const char *cipher);
Vio *new_VioSSL(struct st_VioSSLAcceptorFd *fd, Vio *sd, int state);
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
#ifdef HAVE_SMEM #ifdef HAVE_SMEM
......
...@@ -1514,8 +1514,7 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) , ...@@ -1514,8 +1514,7 @@ mysql_ssl_set(MYSQL *mysql __attribute__((unused)) ,
static void static void
mysql_ssl_free(MYSQL *mysql __attribute__((unused))) mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
{ {
struct st_VioSSLConnectorFd *st= struct st_VioSSLFd *ssl_fd= (struct st_VioSSLFd*) mysql->connector_fd;
(struct st_VioSSLConnectorFd*) mysql->connector_fd;
DBUG_ENTER("mysql_ssl_free"); DBUG_ENTER("mysql_ssl_free");
my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_key, MYF(MY_ALLOW_ZERO_PTR));
...@@ -1523,8 +1522,8 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused))) ...@@ -1523,8 +1522,8 @@ mysql_ssl_free(MYSQL *mysql __attribute__((unused)))
my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_ca, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_capath, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->options.ssl_cipher, MYF(MY_ALLOW_ZERO_PTR));
if (st) if (ssl_fd)
SSL_CTX_free(st->ssl_context); SSL_CTX_free(ssl_fd->ssl_context);
my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR)); my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
mysql->options.ssl_key = 0; mysql->options.ssl_key = 0;
mysql->options.ssl_cert = 0; mysql->options.ssl_cert = 0;
...@@ -1568,6 +1567,63 @@ static MYSQL_METHODS client_methods= ...@@ -1568,6 +1567,63 @@ static MYSQL_METHODS client_methods=
#endif #endif
}; };
int ssl_verify_server_cert(Vio *vio, const char* server_host)
{
SSL *ssl;
X509 *server_cert;
char *cp1, *cp2;
char buf[256];
DBUG_ENTER("ssl_verify_server_cert");
DBUG_PRINT("enter", ("server_host: %s", server_host));
if (!(ssl= (SSL*)vio->ssl_arg))
{
DBUG_PRINT("error", ("No SSL pointer found"));
return 1;
}
if (!server_host)
{
DBUG_PRINT("error", ("No server hostname supplied"));
return 1;
}
if (!(server_cert= SSL_get_peer_certificate(ssl)))
{
DBUG_PRINT("error", ("Could not get server certificate"));
return 1;
}
/*
We already know that the certificate exchanged was valid; the SSL library
handled that. Now we need to verify that the contents of the certificate
are what we expect.
*/
X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf));
X509_free (server_cert);
// X509_NAME_get_text_by_NID(x509_get_subject_name(server_cert), NID_commonName, buf, sizeof(buf));... does the same thing
DBUG_PRINT("info", ("hostname in cert: %s", buf));
cp1 = strstr(buf, "/CN=");
if (cp1)
{
cp1 += 4; // Skip the "/CN=" that we found
cp2 = strchr(cp1, '/');
if (cp2)
*cp2 = '\0';
DBUG_PRINT("info", ("Server hostname in cert: ", cp1));
if (!strcmp(cp1, server_host))
{
/* Success */
DBUG_RETURN(0);
}
}
DBUG_PRINT("error", ("SSL certificate validation failure"));
DBUG_RETURN(1);
}
MYSQL * MYSQL *
CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
...@@ -2013,37 +2069,53 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, ...@@ -2013,37 +2069,53 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
mysql->client_flag=client_flag; mysql->client_flag=client_flag;
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
/*
Oops.. are we careful enough to not send ANY information without
encryption?
*/
if (client_flag & CLIENT_SSL) if (client_flag & CLIENT_SSL)
{ {
/* Do the SSL layering. */
struct st_mysql_options *options= &mysql->options; struct st_mysql_options *options= &mysql->options;
struct st_VioSSLFd *ssl_fd;
/*
Send client_flag, max_packet_size - unencrypted otherwise
the server does not know we want to do SSL
*/
if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net)) if (my_net_write(net,buff,(uint) (end-buff)) || net_flush(net))
{ {
set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate); set_mysql_error(mysql, CR_SERVER_LOST, unknown_sqlstate);
goto error; goto error;
} }
/* Do the SSL layering. */
if (!(mysql->connector_fd= /* Create the VioSSLConnectorFd - init SSL and load certs */
(gptr) new_VioSSLConnectorFd(options->ssl_key, if (!(ssl_fd= new_VioSSLConnectorFd(options->ssl_key,
options->ssl_cert, options->ssl_cert,
options->ssl_ca, options->ssl_ca,
options->ssl_capath, options->ssl_capath,
options->ssl_cipher))) options->ssl_cipher)))
{ {
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
goto error; goto error;
} }
mysql->connector_fd= (void*)ssl_fd;
/* Connect to the server */
DBUG_PRINT("info", ("IO layer change in progress...")); DBUG_PRINT("info", ("IO layer change in progress..."));
if (sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd), if (sslconnect(ssl_fd, mysql->net.vio,
mysql->net.vio, (long) (mysql->options.connect_timeout))) (long) (mysql->options.connect_timeout)))
{ {
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
goto error; goto error;
} }
DBUG_PRINT("info", ("IO layer change done!")); DBUG_PRINT("info", ("IO layer change done!"));
#if 0
/* Verify server cert */
if (mysql->options.ssl_verify_cert &&
ssl_verify_server_cert(mysql->net.vio, mysql->host))
{
set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
goto error;
}
#endif
} }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
......
...@@ -1258,7 +1258,7 @@ extern pthread_t signal_thread; ...@@ -1258,7 +1258,7 @@ extern pthread_t signal_thread;
#endif #endif
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd; extern struct st_VioSSLFd * ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count, MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
......
...@@ -599,7 +599,7 @@ static void openssl_lock(int, openssl_lock_t *, const char *, int); ...@@ -599,7 +599,7 @@ static void openssl_lock(int, openssl_lock_t *, const char *, int);
static unsigned long openssl_id_function(); static unsigned long openssl_id_function();
#endif #endif
char *des_key_file; char *des_key_file;
struct st_VioSSLAcceptorFd *ssl_acceptor_fd; struct st_VioSSLFd *ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
...@@ -1110,7 +1110,10 @@ void clean_up(bool print_message) ...@@ -1110,7 +1110,10 @@ void clean_up(bool print_message)
#endif #endif
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
if (ssl_acceptor_fd) if (ssl_acceptor_fd)
my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR)); {
SSL_CTX_free(ssl_acceptor_fd->ssl_context);
my_free((gptr) ssl_acceptor_fd, MYF(0));
}
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
#ifdef USE_REGEX #ifdef USE_REGEX
my_regex_end(); my_regex_end();
......
...@@ -858,8 +858,8 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh, ...@@ -858,8 +858,8 @@ int acl_getroot(THD *thd, USER_RESOURCES *mqh,
if (acl_user->x509_issuer) if (acl_user->x509_issuer)
{ {
DBUG_PRINT("info",("checkpoint 3")); DBUG_PRINT("info",("checkpoint 3"));
char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); char *ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
DBUG_PRINT("info",("comparing issuers: '%s' and '%s'", DBUG_PRINT("info",("comparing issuers: '%s' and '%s'",
acl_user->x509_issuer, ptr)); acl_user->x509_issuer, ptr));
if (strcmp(acl_user->x509_issuer, ptr)) if (strcmp(acl_user->x509_issuer, ptr))
{ {
......
...@@ -88,19 +88,19 @@ static void vio_init(Vio* vio, enum enum_vio_type type, ...@@ -88,19 +88,19 @@ static void vio_init(Vio* vio, enum enum_vio_type type,
if (type == VIO_TYPE_SSL) if (type == VIO_TYPE_SSL)
{ {
vio->viodelete =vio_delete; vio->viodelete =vio_delete;
vio->vioerrno =vio_ssl_errno; vio->vioerrno =vio_errno;
vio->read =vio_ssl_read; vio->read =vio_ssl_read;
vio->write =vio_ssl_write; vio->write =vio_ssl_write;
vio->fastsend =vio_ssl_fastsend; vio->fastsend =vio_fastsend;
vio->viokeepalive =vio_ssl_keepalive; vio->viokeepalive =vio_keepalive;
vio->should_retry =vio_ssl_should_retry; vio->should_retry =vio_should_retry;
vio->was_interrupted=vio_ssl_was_interrupted; vio->was_interrupted=vio_was_interrupted;
vio->vioclose =vio_ssl_close; vio->vioclose =vio_ssl_close;
vio->peer_addr =vio_ssl_peer_addr; vio->peer_addr =vio_peer_addr;
vio->in_addr =vio_ssl_in_addr; vio->in_addr =vio_in_addr;
vio->vioblocking =vio_ssl_blocking; vio->vioblocking =vio_ssl_blocking;
vio->is_blocking =vio_is_blocking; vio->is_blocking =vio_is_blocking;
vio->timeout =vio_ssl_timeout; vio->timeout =vio_timeout;
} }
else /* default is VIO_TYPE_TCPIP */ else /* default is VIO_TYPE_TCPIP */
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
......
...@@ -30,28 +30,10 @@ void vio_ignore_timeout(Vio *vio, uint which, uint timeout); ...@@ -30,28 +30,10 @@ void vio_ignore_timeout(Vio *vio, uint which, uint timeout);
int vio_ssl_read(Vio *vio,gptr buf, int size); int vio_ssl_read(Vio *vio,gptr buf, int size);
int vio_ssl_write(Vio *vio,const gptr buf,int size); int vio_ssl_write(Vio *vio,const gptr buf,int size);
void vio_ssl_timeout(Vio *vio, uint which, uint timeout);
/* setsockopt TCP_NODELAY at IPPROTO_TCP level, when possible. */
int vio_ssl_fastsend(Vio *vio);
/* setsockopt SO_KEEPALIVE at SOL_SOCKET level, when possible. */
int vio_ssl_keepalive(Vio *vio, my_bool onoff);
/* Whenever we should retry the last read/write operation. */
my_bool vio_ssl_should_retry(Vio *vio);
/* Check that operation was timed out */
my_bool vio_ssl_was_interrupted(Vio *vio);
/* When the workday is over... */ /* When the workday is over... */
int vio_ssl_close(Vio *vio); int vio_ssl_close(Vio *vio);
/* Return last error number */
int vio_ssl_errno(Vio *vio);
my_bool vio_ssl_peer_addr(Vio *vio, char *buf, uint16 *port);
void vio_ssl_in_addr(Vio *vio, struct in_addr *in);
int vio_ssl_blocking(Vio *vio, my_bool set_blocking_mode, my_bool *old_mode); int vio_ssl_blocking(Vio *vio, my_bool set_blocking_mode, my_bool *old_mode);
/* Single copy for server */
enum vio_ssl_acceptorfd_state
{
state_connect = 1,
state_accept = 2
};
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
...@@ -70,12 +70,6 @@ report_errors() ...@@ -70,12 +70,6 @@ report_errors()
} }
int vio_ssl_errno(Vio *vio __attribute__((unused)))
{
return socket_errno; /* On Win32 this mapped to WSAGetLastError() */
}
int vio_ssl_read(Vio * vio, gptr buf, int size) int vio_ssl_read(Vio * vio, gptr buf, int size)
{ {
int r; int r;
...@@ -107,183 +101,51 @@ int vio_ssl_write(Vio * vio, const gptr buf, int size) ...@@ -107,183 +101,51 @@ int vio_ssl_write(Vio * vio, const gptr buf, int size)
} }
int vio_ssl_fastsend(Vio * vio __attribute__((unused)))
{
int r=0;
DBUG_ENTER("vio_ssl_fastsend");
#if defined(IPTOS_THROUGHPUT) && !defined(__EMX__)
{
int tos= IPTOS_THROUGHPUT;
r= setsockopt(vio->sd, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(tos));
}
#endif /* IPTOS_THROUGHPUT && !__EMX__ */
if (!r)
{
#ifdef __WIN__
BOOL nodelay= 1;
r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (const char*) &nodelay,
sizeof(nodelay));
#else
int nodelay= 1;
r= setsockopt(vio->sd, IPPROTO_TCP, TCP_NODELAY, (void*) &nodelay,
sizeof(nodelay));
#endif /* __WIN__ */
}
if (r)
{
DBUG_PRINT("warning", ("Couldn't set socket option for fast send"));
r= -1;
}
DBUG_PRINT("exit", ("%d", r));
DBUG_RETURN(r);
}
int vio_ssl_keepalive(Vio* vio, my_bool set_keep_alive)
{
int r=0;
DBUG_ENTER("vio_ssl_keepalive");
DBUG_PRINT("enter", ("sd: %d, set_keep_alive: %d", vio->sd, (int)
set_keep_alive));
if (vio->type != VIO_TYPE_NAMEDPIPE)
{
uint opt = (set_keep_alive) ? 1 : 0;
r= setsockopt(vio->sd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt,
sizeof(opt));
}
DBUG_RETURN(r);
}
my_bool
vio_ssl_should_retry(Vio * vio __attribute__((unused)))
{
int en = socket_errno;
return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
en == SOCKET_EWOULDBLOCK);
}
my_bool
vio_ssl_was_interrupted(Vio *vio __attribute__((unused)))
{
int en= socket_errno;
return (en == SOCKET_EAGAIN || en == SOCKET_EINTR ||
en == SOCKET_EWOULDBLOCK || en == SOCKET_ETIMEDOUT);
}
int vio_ssl_close(Vio * vio) int vio_ssl_close(Vio * vio)
{ {
int r; int r= 0;
SSL* ssl= (SSL*)vio->ssl_arg;
DBUG_ENTER("vio_ssl_close"); DBUG_ENTER("vio_ssl_close");
r=0;
if ((SSL*) vio->ssl_arg)
{
r = SSL_shutdown((SSL*) vio->ssl_arg);
SSL_free((SSL*) vio->ssl_arg);
vio->ssl_arg= 0;
}
if (vio->sd >= 0)
{
if (shutdown(vio->sd, 2))
r= -1;
if (closesocket(vio->sd))
r= -1;
}
if (r)
{
DBUG_PRINT("error", ("close() failed, error: %d",socket_errno));
report_errors();
/* FIXME: error handling (not critical for MySQL) */
}
vio->type= VIO_CLOSED;
vio->sd= -1;
DBUG_RETURN(r);
}
const char *vio_ssl_description(Vio * vio)
{
return vio->desc;
}
enum enum_vio_type vio_ssl_type(Vio* vio)
{
return vio->type;
}
my_socket vio_ssl_fd(Vio* vio)
{
return vio->sd;
}
my_bool vio_ssl_peer_addr(Vio * vio, char *buf, uint16 *port) if (ssl)
{
DBUG_ENTER("vio_ssl_peer_addr");
DBUG_PRINT("enter", ("sd: %d", vio->sd));
if (vio->localhost)
{
strmov(buf,"127.0.0.1");
*port=0;
}
else
{ {
size_socket addrLen = sizeof(struct sockaddr); switch ((r= SSL_shutdown(ssl)))
if (getpeername(vio->sd, (struct sockaddr *) (& (vio->remote)),
&addrLen) != 0)
{ {
DBUG_PRINT("exit", ("getpeername, error: %d", socket_errno)); case 1: /* Shutdown successful */
DBUG_RETURN(1); break;
case 0: /* Shutdown not yet finished, call it again */
if ((r= SSL_shutdown(ssl) >= 0))
break;
/* Fallthrough */
default: /* Shutdown failed */
DBUG_PRINT("vio_error", ("SSL_shutdown() failed, error: %s",
SSL_get_error(ssl, r)));
break;
} }
#ifdef TO_BE_FIXED SSL_free(ssl);
my_inet_ntoa(vio->remote.sin_addr,buf); vio->ssl_arg= 0;
*port= 0;
#else
strmov(buf, "unknown");
*port= 0;
#endif
} }
DBUG_PRINT("exit", ("addr: %s", buf)); DBUG_RETURN(vio_close(vio));
DBUG_RETURN(0);
}
void vio_ssl_in_addr(Vio *vio, struct in_addr *in)
{
DBUG_ENTER("vio_ssl_in_addr");
if (vio->localhost)
bzero((char*) in, sizeof(*in));
else
*in=vio->remote.sin_addr;
DBUG_VOID_RETURN;
} }
/* int sslaccept(struct st_VioSSLFd* ptr, Vio* vio, long timeout)
TODO: Add documentation
*/
int sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout)
{ {
char *str; SSL *ssl;
char buf[1024];
X509* client_cert; X509* client_cert;
my_bool unused; my_bool unused;
my_bool net_blocking; my_bool net_blocking;
enum enum_vio_type old_type; enum enum_vio_type old_type;
DBUG_ENTER("sslaccept"); DBUG_ENTER("sslaccept");
DBUG_PRINT("enter", ("sd: %d ptr: Ox%p, timeout: %d", DBUG_PRINT("enter", ("sd: %d ptr: %p, timeout: %d",
vio->sd, ptr, timeout)); vio->sd, ptr, timeout));
old_type= vio->type; old_type= vio->type;
net_blocking = vio_is_blocking(vio); net_blocking= vio_is_blocking(vio);
vio_blocking(vio, 1, &unused); /* Must be called before reset */ vio_blocking(vio, 1, &unused); /* Must be called before reset */
vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); vio_reset(vio, VIO_TYPE_SSL, vio->sd, 0, FALSE);
vio->ssl_arg= 0;
if (!(vio->ssl_arg= (void*) SSL_new(ptr->ssl_context))) if (!(ssl= SSL_new(ptr->ssl_context)))
{ {
DBUG_PRINT("error", ("SSL_new failure")); DBUG_PRINT("error", ("SSL_new failure"));
report_errors(); report_errors();
...@@ -291,121 +153,114 @@ int sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) ...@@ -291,121 +153,114 @@ int sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout)
vio_blocking(vio, net_blocking, &unused); vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_PRINT("info", ("ssl_: Ox%p timeout: %ld", vio->ssl_arg= (void*)ssl;
(SSL*) vio->ssl_arg, timeout)); DBUG_PRINT("info", ("ssl_: %p timeout: %ld", ssl, timeout));
SSL_clear((SSL*) vio->ssl_arg); SSL_clear(ssl);
SSL_SESSION_set_timeout(SSL_get_session((SSL*) vio->ssl_arg), timeout); SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
SSL_set_fd((SSL*) vio->ssl_arg,vio->sd); SSL_set_fd(ssl, vio->sd);
SSL_set_accept_state((SSL*) vio->ssl_arg); SSL_set_accept_state(ssl);
if (SSL_do_handshake((SSL*) vio->ssl_arg) < 1) if (SSL_do_handshake(ssl) < 1)
{ {
DBUG_PRINT("error", ("SSL_do_handshake failure")); DBUG_PRINT("error", ("SSL_do_handshake failure"));
report_errors(); report_errors();
SSL_free((SSL*) vio->ssl_arg); SSL_free(ssl);
vio->ssl_arg= 0; vio->ssl_arg= 0;
vio_reset(vio, old_type,vio->sd,0,FALSE); vio_reset(vio, old_type,vio->sd,0,FALSE);
vio_blocking(vio, net_blocking, &unused); vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#ifndef DBUG_OFF #ifndef DBUG_OFF
DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'"
,SSL_get_cipher_name((SSL*) vio->ssl_arg)));
client_cert = SSL_get_peer_certificate ((SSL*) vio->ssl_arg);
if (client_cert != NULL)
{ {
DBUG_PRINT("info",("Client certificate:")); char buf[1024];
str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0); DBUG_PRINT("info",("cipher_name= '%s'", SSL_get_cipher_name(ssl)));
DBUG_PRINT("info",("\t subject: %s", str));
free (str);
str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0); if ((client_cert= SSL_get_peer_certificate (ssl)))
DBUG_PRINT("info",("\t issuer: %s", str)); {
free (str); DBUG_PRINT("info",("Client certificate:"));
X509_NAME_oneline (X509_get_subject_name (client_cert),
buf, sizeof(buf));
DBUG_PRINT("info",("\t subject: %s", buf));
X509_free (client_cert); X509_NAME_oneline (X509_get_issuer_name (client_cert),
} buf, sizeof(buf));
else DBUG_PRINT("info",("\t issuer: %s", buf));
DBUG_PRINT("info",("Client does not have certificate."));
str=SSL_get_shared_ciphers((SSL*) vio->ssl_arg, buf, sizeof(buf)); X509_free (client_cert);
if (str) }
{ else
DBUG_PRINT("info",("SSL_get_shared_ciphers() returned '%s'",str)); DBUG_PRINT("info",("Client does not have certificate."));
}
else
{
DBUG_PRINT("info",("no shared ciphers!"));
}
if (SSL_get_shared_ciphers(ssl, buf, sizeof(buf)))
{
DBUG_PRINT("info",("shared_ciphers: '%s'", buf));
}
else
DBUG_PRINT("info",("no shared ciphers!"));
}
#endif #endif
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) int sslconnect(struct st_VioSSLFd* ptr, Vio* vio, long timeout)
{ {
char *str; SSL *ssl;
X509* server_cert; X509 *server_cert;
my_bool unused; my_bool unused;
my_bool net_blocking; my_bool net_blocking;
enum enum_vio_type old_type; enum enum_vio_type old_type;
DBUG_ENTER("sslconnect"); DBUG_ENTER("sslconnect");
DBUG_PRINT("enter", ("sd: %d ptr: 0x%p ctx: 0x%p", DBUG_PRINT("enter", ("sd: %d, ptr: %p, ctx: %p",
vio->sd,ptr,ptr->ssl_context)); vio->sd, ptr, ptr->ssl_context));
old_type= vio->type; old_type= vio->type;
net_blocking = vio_is_blocking(vio); net_blocking= vio_is_blocking(vio);
vio_blocking(vio, 1, &unused); /* Must be called before reset */ vio_blocking(vio, 1, &unused); /* Must be called before reset */
vio_reset(vio,VIO_TYPE_SSL,vio->sd,0,FALSE); vio_reset(vio, VIO_TYPE_SSL, vio->sd, 0, FALSE);
vio->ssl_arg= 0; if (!(ssl= SSL_new(ptr->ssl_context)))
if (!(vio->ssl_arg = SSL_new(ptr->ssl_context)))
{ {
DBUG_PRINT("error", ("SSL_new failure")); DBUG_PRINT("error", ("SSL_new failure"));
report_errors(); report_errors();
vio_reset(vio, old_type,vio->sd,0,FALSE); vio_reset(vio, old_type, vio->sd, 0, FALSE);
vio_blocking(vio, net_blocking, &unused); vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_PRINT("info", ("ssl_: 0x%p timeout: %ld", vio->ssl_arg= (void*)ssl;
(SSL*) vio->ssl_arg, timeout)); DBUG_PRINT("info", ("ssl: %p, timeout: %ld", ssl, timeout));
SSL_clear((SSL*) vio->ssl_arg); SSL_clear(ssl);
SSL_SESSION_set_timeout(SSL_get_session((SSL*) vio->ssl_arg), timeout); SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout);
SSL_set_fd ((SSL*) vio->ssl_arg, vio_ssl_fd(vio)); SSL_set_fd(ssl, vio->sd);
SSL_set_connect_state((SSL*) vio->ssl_arg); SSL_set_connect_state(ssl);
if (SSL_do_handshake((SSL*) vio->ssl_arg) < 1) if (SSL_do_handshake(ssl) < 1)
{ {
DBUG_PRINT("error", ("SSL_do_handshake failure")); DBUG_PRINT("error", ("SSL_do_handshake failure"));
report_errors(); report_errors();
SSL_free((SSL*) vio->ssl_arg); SSL_free(ssl);
vio->ssl_arg= 0; vio->ssl_arg= 0;
vio_reset(vio, old_type,vio->sd,0,FALSE); vio_reset(vio, old_type, vio->sd, 0, FALSE);
vio_blocking(vio, net_blocking, &unused); vio_blocking(vio, net_blocking, &unused);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
#ifndef DBUG_OFF #ifndef DBUG_OFF
DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'" DBUG_PRINT("info",("cipher_name: '%s'" , SSL_get_cipher_name(ssl)));
,SSL_get_cipher_name((SSL*) vio->ssl_arg)));
server_cert = SSL_get_peer_certificate ((SSL*) vio->ssl_arg); if ((server_cert= SSL_get_peer_certificate (ssl)))
if (server_cert != NULL)
{ {
char buf[256];
DBUG_PRINT("info",("Server certificate:")); DBUG_PRINT("info",("Server certificate:"));
str = X509_NAME_oneline (X509_get_subject_name (server_cert), 0, 0); X509_NAME_oneline(X509_get_subject_name(server_cert), buf, sizeof(buf));
DBUG_PRINT("info",("\t subject: %s", str)); DBUG_PRINT("info",("\t subject: %s", buf));
free(str); X509_NAME_oneline (X509_get_issuer_name(server_cert), buf, sizeof(buf));
DBUG_PRINT("info",("\t issuer: %s", buf));
str = X509_NAME_oneline (X509_get_issuer_name (server_cert), 0, 0);
DBUG_PRINT("info",("\t issuer: %s", str));
free(str);
/*
We could do all sorts of certificate verification stuff here before
deallocating the certificate.
*/
X509_free (server_cert); X509_free (server_cert);
} }
else else
DBUG_PRINT("info",("Server does not have certificate.")); DBUG_PRINT("info",("Server does not have certificate."));
#endif #endif
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -414,21 +269,10 @@ int vio_ssl_blocking(Vio * vio __attribute__((unused)), ...@@ -414,21 +269,10 @@ int vio_ssl_blocking(Vio * vio __attribute__((unused)),
my_bool set_blocking_mode, my_bool set_blocking_mode,
my_bool *old_mode) my_bool *old_mode)
{ {
/* Mode is always blocking */
*old_mode= 1;
/* Return error if we try to change to non_blocking mode */ /* Return error if we try to change to non_blocking mode */
*old_mode=1; /* Mode is always blocking */ return (set_blocking_mode ? 0 : 1);
return set_blocking_mode ? 0 : 1;
} }
void vio_ssl_timeout(Vio *vio __attribute__((unused)),
uint which __attribute__((unused)),
uint timeout __attribute__((unused)))
{
#ifdef __WIN__
ulong wait_timeout= (ulong) timeout * 1000;
(void) setsockopt(vio->sd, SOL_SOCKET,
which ? SO_SNDTIMEO : SO_RCVTIMEO, (char*) &wait_timeout,
sizeof(wait_timeout));
#endif /* __WIN__ */
}
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
static bool ssl_algorithms_added = FALSE; static bool ssl_algorithms_added = FALSE;
static bool ssl_error_strings_loaded= FALSE; static bool ssl_error_strings_loaded= FALSE;
static int verify_depth = 0; static int verify_depth = 0;
static int verify_error = X509_V_OK;
static unsigned char dh512_p[]= static unsigned char dh512_p[]=
{ {
...@@ -82,30 +81,31 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) ...@@ -82,30 +81,31 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
DBUG_ENTER("vio_set_cert_stuff"); DBUG_ENTER("vio_set_cert_stuff");
DBUG_PRINT("enter", ("ctx: %p, cert_file: %s, key_file: %s", DBUG_PRINT("enter", ("ctx: %p, cert_file: %s, key_file: %s",
ctx, cert_file, key_file)); ctx, cert_file, key_file));
if (cert_file != NULL) if (cert_file)
{ {
if (SSL_CTX_use_certificate_file(ctx,cert_file,SSL_FILETYPE_PEM) <= 0) if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0)
{ {
DBUG_PRINT("error",("unable to get certificate from '%s'\n",cert_file)); DBUG_PRINT("error",("unable to get certificate from '%s'\n", cert_file));
/* FIX stderr */ /* FIX stderr */
fprintf(stderr,"Error when connection to server using SSL:"); fprintf(stderr,"Error when connection to server using SSL:");
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
fprintf(stderr,"Unable to get certificate from '%s'\n", cert_file); fprintf(stderr,"Unable to get certificate from '%s'\n", cert_file);
fflush(stderr); fflush(stderr);
DBUG_RETURN(0); DBUG_RETURN(1);
} }
if (key_file == NULL)
key_file = cert_file; if (!key_file)
if (SSL_CTX_use_PrivateKey_file(ctx,key_file, key_file= cert_file;
SSL_FILETYPE_PEM) <= 0)
if (SSL_CTX_use_PrivateKey_file(ctx, key_file, SSL_FILETYPE_PEM) <= 0)
{ {
DBUG_PRINT("error", ("unable to get private key from '%s'\n",key_file)); DBUG_PRINT("error", ("unable to get private key from '%s'\n", key_file));
/* FIX stderr */ /* FIX stderr */
fprintf(stderr,"Error when connection to server using SSL:"); fprintf(stderr,"Error when connection to server using SSL:");
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
fprintf(stderr,"Unable to get private key from '%s'\n", cert_file); fprintf(stderr,"Unable to get private key from '%s'\n", cert_file);
fflush(stderr); fflush(stderr);
DBUG_RETURN(0); DBUG_RETURN(1);
} }
/* /*
...@@ -116,45 +116,45 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file) ...@@ -116,45 +116,45 @@ vio_set_cert_stuff(SSL_CTX *ctx, const char *cert_file, const char *key_file)
{ {
DBUG_PRINT("error", DBUG_PRINT("error",
("Private key does not match the certificate public key\n")); ("Private key does not match the certificate public key\n"));
DBUG_RETURN(0); DBUG_RETURN(1);
} }
} }
DBUG_RETURN(1); DBUG_RETURN(0);
} }
static int static int
vio_verify_callback(int ok, X509_STORE_CTX *ctx) vio_verify_callback(int ok, X509_STORE_CTX *ctx)
{ {
char buf[256]; char buf[256];
X509* err_cert; X509 *err_cert;
int err,depth;
DBUG_ENTER("vio_verify_callback"); DBUG_ENTER("vio_verify_callback");
DBUG_PRINT("enter", ("ok: %d, ctx: 0x%p", ok, ctx)); DBUG_PRINT("enter", ("ok: %d, ctx: %p", ok, ctx));
err_cert=X509_STORE_CTX_get_current_cert(ctx);
err= X509_STORE_CTX_get_error(ctx);
depth= X509_STORE_CTX_get_error_depth(ctx);
X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf)); err_cert= X509_STORE_CTX_get_current_cert(ctx);
X509_NAME_oneline(X509_get_subject_name(err_cert), buf, sizeof(buf));
DBUG_PRINT("info", ("cert: %s", buf));
if (!ok) if (!ok)
{ {
DBUG_PRINT("error",("verify error: num: %d : '%s'\n",err, int err, depth;
err= X509_STORE_CTX_get_error(ctx);
depth= X509_STORE_CTX_get_error_depth(ctx);
DBUG_PRINT("error",("verify error: %d, '%s'",err,
X509_verify_cert_error_string(err))); X509_verify_cert_error_string(err)));
/*
Approve cert if depth is greater then "verify_depth", currently
verify_depth is always 0 and there is no way to increase it.
*/
if (verify_depth >= depth) if (verify_depth >= depth)
{ ok= 1;
ok=1;
verify_error=X509_V_OK;
}
else
{
verify_error=X509_V_ERR_CERT_CHAIN_TOO_LONG;
}
} }
switch (ctx->error) { switch (ctx->error)
{
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256); X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
DBUG_PRINT("info",("issuer= %s\n",buf)); DBUG_PRINT("info",("issuer= %s\n", buf));
break; break;
case X509_V_ERR_CERT_NOT_YET_VALID: case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
...@@ -198,193 +198,150 @@ static void netware_ssl_init() ...@@ -198,193 +198,150 @@ static void netware_ssl_init()
#endif /* __NETWARE__ */ #endif /* __NETWARE__ */
/************************ VioSSLConnectorFd **********************************/ static void check_ssl_init()
/*
TODO:
Add option --verify to mysql to be able to change verification mode
*/
struct st_VioSSLConnectorFd *
new_VioSSLConnectorFd(const char* key_file,
const char* cert_file,
const char* ca_file,
const char* ca_path,
const char* cipher)
{ {
int verify = SSL_VERIFY_NONE;
struct st_VioSSLConnectorFd* ptr;
int result;
DH *dh;
DBUG_ENTER("new_VioSSLConnectorFd");
if (!(ptr=((struct st_VioSSLConnectorFd*)
my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0)))))
DBUG_RETURN(0);
ptr->ssl_context= 0;
ptr->ssl_method= 0;
/* FIXME: constants! */
if (!ssl_algorithms_added) if (!ssl_algorithms_added)
{ {
DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()")); ssl_algorithms_added= TRUE;
ssl_algorithms_added = TRUE;
SSL_library_init(); SSL_library_init();
OpenSSL_add_all_algorithms(); OpenSSL_add_all_algorithms();
} }
#ifdef __NETWARE__ #ifdef __NETWARE__
/* MASV, should it be done everytime? */
netware_ssl_init(); netware_ssl_init();
#endif #endif
if (!ssl_error_strings_loaded) if (!ssl_error_strings_loaded)
{ {
DBUG_PRINT("info", ("todo:SSL_load_error_strings()")); ssl_error_strings_loaded= TRUE;
ssl_error_strings_loaded = TRUE;
SSL_load_error_strings(); SSL_load_error_strings();
} }
ptr->ssl_method = TLSv1_client_method(); }
ptr->ssl_context = SSL_CTX_new(ptr->ssl_method);
DBUG_PRINT("info", ("ssl_context: %p",ptr->ssl_context)); /************************ VioSSLFd **********************************/
if (ptr->ssl_context == 0) struct st_VioSSLFd *
new_VioSSLFd(const char *key_file, const char *cert_file,
const char *ca_file, const char *ca_path,
const char *cipher, SSL_METHOD *method)
{
DH *dh;
struct st_VioSSLFd *ssl_fd;
DBUG_ENTER("new_VioSSLFd");
check_ssl_init();
if (!(ssl_fd= ((struct st_VioSSLFd*)
my_malloc(sizeof(struct st_VioSSLFd),MYF(0)))))
DBUG_RETURN(0);
if (!(ssl_fd->ssl_context= SSL_CTX_new(method)))
{ {
DBUG_PRINT("error", ("SSL_CTX_new failed")); DBUG_PRINT("error", ("SSL_CTX_new failed"));
report_errors(); report_errors();
goto ctor_failure; my_free((void*)ssl_fd,MYF(0));
DBUG_RETURN(0);
} }
/*
SSL_CTX_set_options /* Set the ciphers that can be used */
SSL_CTX_set_info_callback if (cipher && SSL_CTX_set_cipher_list(ssl_fd->ssl_context, cipher))
*/
if (cipher)
{ {
result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher); DBUG_PRINT("error", ("failed to set ciphers to use"));
DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result)); report_errors();
my_free((void*)ssl_fd,MYF(0));
DBUG_RETURN(0);
} }
SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback);
if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1) if (vio_set_cert_stuff(ssl_fd->ssl_context, cert_file, key_file))
{ {
DBUG_PRINT("error", ("vio_set_cert_stuff failed")); DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
report_errors(); report_errors();
goto ctor_failure; my_free((void*)ssl_fd,MYF(0));
DBUG_RETURN(0);
} }
if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file,ca_path) == 0)
if (SSL_CTX_load_verify_locations(ssl_fd->ssl_context, ca_file, ca_path) == 0)
{ {
DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed")); DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
if (SSL_CTX_set_default_verify_paths(ptr->ssl_context) == 0) if (SSL_CTX_set_default_verify_paths(ssl_fd->ssl_context) == 0)
{ {
DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed")); DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
report_errors(); report_errors();
goto ctor_failure; my_free((void*)ssl_fd,MYF(0));
DBUG_RETURN(0);
} }
} }
/* DH stuff */ /* DH stuff */
dh=get_dh512(); dh=get_dh512();
SSL_CTX_set_tmp_dh(ptr->ssl_context,dh); SSL_CTX_set_tmp_dh(ssl_fd->ssl_context, dh);
DH_free(dh); DH_free(dh);
DBUG_RETURN(ptr); DBUG_PRINT("exit", ("OK 1"));
ctor_failure:
DBUG_PRINT("exit", ("there was an error")); DBUG_RETURN(ssl_fd);
my_free((gptr)ptr,MYF(0));
DBUG_RETURN(0);
} }
/************************ VioSSLAcceptorFd **********************************/ /************************ VioSSLConnectorFd **********************************/
/* struct st_VioSSLFd *
TODO: new_VioSSLConnectorFd(const char *key_file, const char *cert_file,
Add option --verify to mysqld to be able to change verification mode const char *ca_file, const char *ca_path,
*/ const char *cipher)
struct st_VioSSLAcceptorFd*
new_VioSSLAcceptorFd(const char *key_file,
const char *cert_file,
const char *ca_file,
const char *ca_path,
const char *cipher)
{ {
int verify = (SSL_VERIFY_PEER | struct st_VioSSLFd *ssl_fd;
SSL_VERIFY_CLIENT_ONCE); int verify= SSL_VERIFY_NONE;
struct st_VioSSLAcceptorFd* ptr; if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
int result; ca_path, cipher, TLSv1_client_method())))
DH *dh; {
DBUG_ENTER("new_VioSSLAcceptorFd"); return 0;
}
/* Init the the VioSSLFd as a "connector" ie. the client side */
ptr= ((struct st_VioSSLAcceptorFd*) /*
my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0))); The verify_callback function is used to control the behaviour
ptr->ssl_context=0; when the SSL_VERIFY_PEER flag is set. Here it is SSL_VERIFY_NONE
ptr->ssl_method=0; and thus callback is set to NULL
/* FIXME: constants! */ */
ptr->session_id_context= ptr; SSL_CTX_set_verify(ssl_fd->ssl_context, verify, NULL);
if (!ssl_algorithms_added) return ssl_fd;
{ }
DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
ssl_algorithms_added = TRUE;
SSL_library_init();
OpenSSL_add_all_algorithms();
}
#ifdef __NETWARE__
netware_ssl_init();
#endif
if (!ssl_error_strings_loaded) /************************ VioSSLAcceptorFd **********************************/
{ struct st_VioSSLFd*
DBUG_PRINT("info", ("todo: SSL_load_error_strings()")); new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
ssl_error_strings_loaded = TRUE; const char *ca_file, const char *ca_path,
SSL_load_error_strings(); const char *cipher)
} {
ptr->ssl_method= TLSv1_server_method(); struct st_VioSSLFd *ssl_fd;
ptr->ssl_context= SSL_CTX_new(ptr->ssl_method); int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
if (ptr->ssl_context == 0) if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
{ ca_path, cipher, TLSv1_server_method())))
DBUG_PRINT("error", ("SSL_CTX_new failed"));
report_errors();
goto ctor_failure;
}
if (cipher)
{ {
result=SSL_CTX_set_cipher_list(ptr->ssl_context, cipher); return 0;
DBUG_PRINT("info",("SSL_set_cipher_list() returned %d",result));
} }
/* SSL_CTX_set_quiet_shutdown(ctx,1); */ /* Init the the VioSSLFd as a "acceptor" ie. the server side */
SSL_CTX_sess_set_cache_size(ptr->ssl_context,128);
/* DH? */ /* Set max number of cached sessions, returns the previous size */
SSL_CTX_set_verify(ptr->ssl_context, verify, vio_verify_callback); SSL_CTX_sess_set_cache_size(ssl_fd->ssl_context, 128);
SSL_CTX_set_session_id_context(ptr->ssl_context,
(const uchar*) &(ptr->session_id_context),
sizeof(ptr->session_id_context));
/* /*
SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(CAfile)); The verify_callback function is used to control the behaviour
when the SSL_VERIFY_PEER flag is set.
*/ */
if (vio_set_cert_stuff(ptr->ssl_context, cert_file, key_file) == -1) SSL_CTX_set_verify(ssl_fd->ssl_context, verify, vio_verify_callback);
{
DBUG_PRINT("error", ("vio_set_cert_stuff failed"));
report_errors();
goto ctor_failure;
}
if (SSL_CTX_load_verify_locations( ptr->ssl_context, ca_file, ca_path) == 0)
{
DBUG_PRINT("warning", ("SSL_CTX_load_verify_locations failed"));
if (SSL_CTX_set_default_verify_paths(ptr->ssl_context)==0)
{
DBUG_PRINT("error", ("SSL_CTX_set_default_verify_paths failed"));
report_errors();
goto ctor_failure;
}
}
/* DH stuff */
dh=get_dh512();
SSL_CTX_set_tmp_dh(ptr->ssl_context,dh);
DH_free(dh);
DBUG_RETURN(ptr);
ctor_failure: /*
DBUG_PRINT("exit", ("there was an error")); Set session_id - an identifier for this server session
my_free((gptr) ptr,MYF(0)); Use the ssl_fd pointer
DBUG_RETURN(0); */
SSL_CTX_set_session_id_context(ssl_fd->ssl_context,
ssl_fd,
sizeof(ssl_fd));
return ssl_fd;
} }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment