/*
 * ----------------------------------------------------------------
 * Night Light IRC Proxy - SSL Functions
 * ----------------------------------------------------------------
 * Copyright (C) 2006-2007 Jonas Kvinge <jonas@night-light.net>
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Last modified by:
 * Jonas Kvinge (15.11.2006)
 *
 */

#define SSL_C_

#define NEED_SYS_TYPES_H 1		/* Extra types */
#define NEED_SYS_PARAM_H 1		/* Some systems need this */
#define NEED_LIMITS_H 0			/* Kernel limits */
#define NEED_STDARG_H 1			/* va_list, etc */
#define NEED_ERRNO_H 1			/* errno */
#define NEED_CTYPE_H 1			/* isdigit(), etc */
#define NEED_NETINET_IN_H 0		/* in_addr, sockaddr_in, etc */
#define NEED_ARPA_INET_H 0		/* inet_ntoa(), inet_aton(), etc */
#define NEED_STDIO_H 1			/* Standard C UNIX functions */
#define NEED_STDLIB_H 1			/* malloc(), exit(), atoi(), etc */
#define NEED_TIME_H 1			/* time(), etc */
#define NEED_SYSCTL_H 0			/* sysctl(), etc */
#define NEED_SYS_STAT_H 0		/* chmod(), mkdir(), etc */
#define NEED_SYS_UIO_H 0		/* iovec, etc */
#define NEED_FCNTL_H 1			/* open(), creat(), fcntl(), etc */
#define NEED_SYS_IOCTL_H 0		/* ioctl(), etc */
#define NEED_SYS_FILIO_H 0		/* Solaris need this for ioctl(), etc */
#define NEED_UNISTD_H 1			/* Unix standard functions */
#define NEED_STRING_H 1			/* C string functions */
#define NEED_SIGNAL_H 0			/* Signal functions */
#define NEED_SYS_SOCKET_H 0		/* Socket functions */
#define NEED_NETDB_H 0			/* Network database functions */
#define NEED_ARPA_NAMESER_H 0		/* Nameserver definitions */
#define NEED_GETUSERPW_HEADERS 0 	/* Functions to retrive system passwords */
#define NEED_ARES 0			/* Functions needed for ares */
#define NEED_SSL 1			/* Needed for SSL support */

#include "includes.h"

#include "ssl.h"
#include "main.h"
#include "conf.h"

/* VARIABLES - JONAS (15.11.2006) */

extern struct Conf_Struct ConfS;

SSL_CTX *IRCPROXY_SSL_SERVER_CTX = NULL;
SSL_CTX *IRCPROXY_SSL_CLIENT_CTX = NULL;

/* SSL_INIT FUNCTION - JONAS (16.11.2006) */

void ssl_init(void) {

  signed long int Result;

  SSL_METHOD *SSL_Server_Method = NULL;
  SSL_METHOD *SSL_Client_Method = NULL;
#if 0
  long CTX_Options = 0;
#endif

  SSL_library_init();
  SSL_load_error_strings();

  SSL_Server_Method = SSLv23_server_method();
  if (SSL_Server_Method == NULL) {
    sysprint(BITMASK_ERROR, "SSL: Failed to create SSL Method object.");
    main_exit("Failed to initialize the SSL library.");
  }

  SSL_Client_Method = SSLv23_client_method();
  if (SSL_Client_Method == NULL) {
    sysprint(BITMASK_ERROR, "SSL: Failed to create SSL Method object.");
    main_exit("Failed to initialize the SSL library.");
  }


  IRCPROXY_SSL_SERVER_CTX = SSL_CTX_new(SSL_Server_Method);
  if (IRCPROXY_SSL_SERVER_CTX == NULL) {
    sysprint(BITMASK_ERROR, "SSL: Failed to create SSL CTX object.");
    main_exit("Failed to initialize the SSL library.");
  }

  IRCPROXY_SSL_CLIENT_CTX = SSL_CTX_new(SSL_Client_Method);
  if (IRCPROXY_SSL_CLIENT_CTX == NULL) {
    sysprint(BITMASK_ERROR, "SSL: Failed to create SSL CTX object.");
    main_exit("Failed to initialize the SSL library.");
  }

#if 0

  CTX_Options = SSL_CTX_get_options(IRCPROXY_SSL_SERVER_CTX);
  CTX_Options |= SSL_OP_NO_TLSv1;
#ifdef SSL_OP_NO_SSLv1
  CTX_Options |= SSL_OP_NO_SSLv1;
#endif
  CTX_Options |= SSL_OP_NO_SSLv2;
  CTX_Options |= SSL_OP_NO_SSLv3;
  SSL_CTX_set_options(IRCPROXY_SSL_SERVER_CTX, CTX_Options);

  CTX_Options = SSL_CTX_get_options(IRCPROXY_SSL_CLIENT_CTX);
  CTX_Options |= SSL_OP_NO_TLSv1;
#ifdef SSL_OP_NO_SSLv1
  CTX_Options |= SSL_OP_NO_SSLv1;
#endif
  CTX_Options |= SSL_OP_NO_SSLv2;
  CTX_Options |= SSL_OP_NO_SSLv3;
  SSL_CTX_set_options(IRCPROXY_SSL_CLIENT_CTX, CTX_Options);

#endif

  Result = SSL_CTX_use_certificate_file(IRCPROXY_SSL_SERVER_CTX, ConfS.SSLServerCertificate, SSL_FILETYPE_PEM);
  if (Result != 1) {
    sysprint(BITMASK_ERROR, "SSL: Failed to load SSL Server Certificate \"%s\".", ConfS.SSLServerCertificate);
    main_exit("Failed to initialize the SSL library.");
  }

  Result = SSL_CTX_use_certificate_file(IRCPROXY_SSL_CLIENT_CTX, ConfS.SSLClientCertificate, SSL_FILETYPE_PEM);
  if (Result != 1) {
    sysprint(BITMASK_ERROR, "SSL: Failed to load SSL Client Certificate \"%s\".", ConfS.SSLClientCertificate);
    main_exit("Failed to initialize the SSL library.");
  }
  Result = SSL_CTX_use_PrivateKey_file(IRCPROXY_SSL_SERVER_CTX, ConfS.SSLServerPrivateKey, SSL_FILETYPE_PEM);
  if (Result != 1) {
    sysprint(BITMASK_ERROR, "SSL: Failed to load SSL Server Private Key \"%s\".", ConfS.SSLServerPrivateKey);
    main_exit("Failed to initialize the SSL library.");
  }
  Result = SSL_CTX_use_PrivateKey_file(IRCPROXY_SSL_CLIENT_CTX, ConfS.SSLClientPrivateKey, SSL_FILETYPE_PEM);
  if (Result != 1) {
    sysprint(BITMASK_ERROR, "SSL: Failed to load SSL Client Private Key \"%s\".", ConfS.SSLClientPrivateKey);
    main_exit("Failed to initialize the SSL library.");
  }
  Result = SSL_CTX_check_private_key(IRCPROXY_SSL_SERVER_CTX);
  if (Result != 1) {
    sysprint(BITMASK_ERROR, "SSL: Private key does not match the certificate public key.");
    main_exit("Failed to initialize the SSL library.");
  }
  Result = SSL_CTX_check_private_key(IRCPROXY_SSL_CLIENT_CTX);
  if (Result != 1) {
    sysprint(BITMASK_ERROR, "SSL: Private key does not match the certificate public key.");
    main_exit("Failed to initialize the SSL library.");
  }

  if (strcmp(ConfS.SSLServerCiphers, SSLSERVERCIPHERS) != FALSE) {
    Result = SSL_CTX_set_cipher_list(IRCPROXY_SSL_SERVER_CTX, ConfS.SSLServerCiphers);
    if (Result != 1) {
      sysprint(BITMASK_ERROR, "SSL: Failed to set SSL server cipher list to \"%s\".",  ConfS.SSLServerCiphers);
      main_exit("Failed to initialize the SSL library.");
    }
  }
  if (strcmp(ConfS.SSLClientCiphers, SSLCLIENTCIPHERS) != FALSE) {
    Result = SSL_CTX_set_cipher_list(IRCPROXY_SSL_CLIENT_CTX, ConfS.SSLClientCiphers);
    if (Result != 1) {
      sysprint(BITMASK_ERROR, "SSL: Failed to set SSL client cipher list to \"%s\".",  ConfS.SSLClientCiphers);
      main_exit("Failed to initialize the SSL library.");
    }
  }


  sysprint(BITMASK_MAIN, "SSL Library initialized.");

}

/* SSL_CLEANUP FUNCTION - JONAS (16.11.2006) */

void ssl_cleanup(void) {

  SSL_CTX_free(IRCPROXY_SSL_SERVER_CTX);
  SSL_CTX_free(IRCPROXY_SSL_CLIENT_CTX);
  IRCPROXY_SSL_SERVER_CTX = NULL;
  IRCPROXY_SSL_CLIENT_CTX = NULL;

}


syntax highlighted by Code2HTML, v. 0.9.1