Esempio n. 1
0
const SSL_METHOD *sycTLSv1_1_server_method(void) {
   const SSL_METHOD *result;
   Debug("TLSv1_1_server_method()");
   result = TLSv1_1_server_method();
   Debug1("TLSv1_1_server_method() -> %p", result);
   return result;
}
Esempio n. 2
0
void ssl_init()
{
	SSL_library_init();
	SSL_load_error_strings();
	BGPTLS_sess_server.psMethod = TLSv1_1_server_method(); //Or client method when putting this code on the client.
	BGPTLS_sess_server.psCTX = SSL_CTX_new(BGPTLS_sess_server.psMethod);
	
}
Esempio n. 3
0
void Context::createSSLContext()
{
	if (SSLManager::isFIPSEnabled())
	{
		_pSSLContext = SSL_CTX_new(TLSv1_method());
	}
	else
	{
		switch (_usage)
		{
		case CLIENT_USE:
			_pSSLContext = SSL_CTX_new(SSLv23_client_method());
			break;
		case SERVER_USE:
			_pSSLContext = SSL_CTX_new(SSLv23_server_method());
			break;
#if defined(SSL_OP_NO_TLSv1) && !defined(OPENSSL_NO_TLS1)
		case TLSV1_CLIENT_USE:
			_pSSLContext = SSL_CTX_new(TLSv1_client_method());
			break;
		case TLSV1_SERVER_USE:
			_pSSLContext = SSL_CTX_new(TLSv1_server_method());
			break;
#endif
#if defined(SSL_OP_NO_TLSv1_1) && !defined(OPENSSL_NO_TLS1)
/* SSL_OP_NO_TLSv1_1 is defined in ssl.h if the library version supports TLSv1.1.
 * OPENSSL_NO_TLS1 is defined in opensslconf.h or on the compiler command line
 * if TLS1.x was removed at OpenSSL library build time via Configure options.
 */
        case TLSV1_1_CLIENT_USE:
            _pSSLContext = SSL_CTX_new(TLSv1_1_client_method());
            break;
        case TLSV1_1_SERVER_USE:
            _pSSLContext = SSL_CTX_new(TLSv1_1_server_method());
            break;
#endif
#if defined(SSL_OP_NO_TLSv1_2) && !defined(OPENSSL_NO_TLS1)
        case TLSV1_2_CLIENT_USE:
            _pSSLContext = SSL_CTX_new(TLSv1_2_client_method());
            break;
        case TLSV1_2_SERVER_USE:
            _pSSLContext = SSL_CTX_new(TLSv1_2_server_method());
            break;
#endif
		default:
			throw Poco::InvalidArgumentException("Invalid or unsupported usage");
		}
	}
	if (!_pSSLContext) 
	{
		unsigned long err = ERR_get_error();
		throw SSLException("Cannot create SSL_CTX object", ERR_error_string(err, 0));
	}

	SSL_CTX_set_default_passwd_cb(_pSSLContext, &SSLManager::privateKeyPassphraseCallback);
	Utility::clearErrorStack();
	SSL_CTX_set_options(_pSSLContext, SSL_OP_ALL);
}
Esempio n. 4
0
static const SSL_METHOD *tls1_get_server_method(int ver)
{
    if (ver == TLS1_2_VERSION)
        return TLSv1_2_server_method();
    if (ver == TLS1_1_VERSION)
        return TLSv1_1_server_method();
    if (ver == TLS1_VERSION)
        return TLSv1_server_method();
    return NULL;
}
Esempio n. 5
0
bool VSslServer::doOpen()
{
  VLock lock(stateOpenCs); // gilgil temp 2014.03.14

  //
  // Set server method
  //
  LOG_DEBUG("method=%s", qPrintable(methodType.str()));
  switch (methodType)
  {
    #ifdef _WIN32 // Linux openssl does not support SSLv2_server_method
    case VSslMethodType::mtSSLv2   : m_meth = (SSL_METHOD*)SSLv2_server_method();   break;
    #endif // _WIN32
    case VSslMethodType::mtSSLv3   : m_meth = (SSL_METHOD*)SSLv3_server_method();   break;
    case VSslMethodType::mtSSLv23  : m_meth = (SSL_METHOD*)SSLv23_server_method();  break;
    case VSslMethodType::mtTLSv1   : m_meth = (SSL_METHOD*)TLSv1_server_method();   break;
    case VSslMethodType::mtTLSv1_1 : m_meth = (SSL_METHOD*)TLSv1_1_server_method(); break;
    case VSslMethodType::mtTLSv1_2 : m_meth = (SSL_METHOD*)TLSv1_2_server_method(); break;
    case VSslMethodType::mtDTLSv1  : m_meth = (SSL_METHOD*)DTLSv1_server_method();  break;
    case VSslMethodType::mtNone    :
    default                        :
      SET_ERROR(VSslError, QString("client method error(%1)").arg(methodType.str()), VSslError::INVALID_SSL_METHOD);
      return false;
  }

  m_ctx = SSL_CTX_new(m_meth);
  if (!SSL_CTX_set_tlsext_servername_callback(m_ctx, ssl_servername_cb))
  {
    LOG_ERROR("SSL_CTX_set_tlsext_servername_callback return false");
  }
  if (!SSL_CTX_set_tlsext_servername_arg(m_ctx, this))
  {
    LOG_ERROR("SSL_CTX_set_tlsext_servername_arg return false");
  }

  if (defaultKeyCrtFileName != "")
  {
    QString fileName = certificatePath;
    QFileInfo fi(fileName);
    // if (!fi.isAbsolute()) fileName = VApp::_filePath() + fileName; // gilgil temp 2014.12.25
    if (!fi.isAbsolute()) fileName = QCoreApplication::applicationDirPath() + QDir::separator() + fileName; // gilgil temp 2014.12.25
    if (!fileName.endsWith('/') && !fileName.endsWith('\\'))
    {
      fileName += QDir::separator();
    }
    fileName += defaultKeyCrtFileName;
    if (!setup(fileName)) return false;
  }

  if (!VTcpServer::doOpen()) return false;

  return true;
}
const SSL_METHOD *anubis_string_to_SSL_METOHD(const char *method, int role) {
    if(!method)
        return NULL;
    
    if(!strcasecmp(method, "SSLv23"))
        return role == ANUBIS_ROLE_SERVER ?
        SSLv23_server_method() :
        role == ANUBIS_ROLE_CLIENT ? SSLv23_client_method() : NULL;
#ifndef OPENSSL_NO_SSL2_METHOD
    if(!strcasecmp(method, "SSLv2"))
        return role == ANUBIS_ROLE_SERVER ?
        SSLv3_server_method() :
        role == ANUBIS_ROLE_CLIENT ? SSLv3_client_method() : NULL;
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
    if(!strcasecmp(method, "SSLv3"))
        return role == ANUBIS_ROLE_SERVER ?
        SSLv3_server_method() :
        role == ANUBIS_ROLE_CLIENT ? SSLv3_client_method() : NULL;
#endif
    if(!strcasecmp(method, "TLSv1.0"))
        return role == ANUBIS_ROLE_SERVER ?
        TLSv1_server_method() :
        role == ANUBIS_ROLE_CLIENT ? TLSv1_client_method() : NULL;
#if OPENSSL_VERSION_NUMBER >= 0x10001000L
    if(!strcasecmp(method, "TLSv1.1"))
        return role == ANUBIS_ROLE_SERVER ?
        TLSv1_1_server_method() :
        role == ANUBIS_ROLE_CLIENT ? TLSv1_1_client_method() : NULL;
    if(!strcasecmp(method, "TLSv1.2"))
        return role == ANUBIS_ROLE_SERVER ?
        TLSv1_2_server_method() :
        role == ANUBIS_ROLE_CLIENT ? TLSv1_2_client_method() : NULL;
#endif
    
    /*
    if(!strcasecmp(method, "DTLS1.0"))
        return role == ANUBIS_ROLE_SERVER ?
        DTLSv1_server_method() :
        role == ANUBIS_ROLE_CLIENT ? DTLSv1_client_method() : NULL;
    if(!strcasecmp(method, "DTLS1.2"))
        return role == ANUBIS_ROLE_SERVER ?
        DTLSv1_2_server_method() :
        role == ANUBIS_ROLE_CLIENT ? DTLSv1_2_client_method() : NULL;
    if(!strcasecmp(method, "DTLS"))
        return role == ANUBIS_ROLE_SERVER ?
        DTLS_server_method() :
        role == ANUBIS_ROLE_CLIENT ? DTLS_client_method() : NULL;
     */
    
    return NULL;
}//end anubis_string_to_SSL_METOHD
Esempio n. 7
0
static const SSL_METHOD *swSSL_get_method(int method)
{
    switch (method)
    {
#ifndef OPENSSL_NO_SSL3_METHOD
    case SW_SSLv3_METHOD:
        return SSLv3_method();
    case SW_SSLv3_SERVER_METHOD:
        return SSLv3_server_method();
    case SW_SSLv3_CLIENT_METHOD:
        return SSLv3_client_method();
#endif
    case SW_SSLv23_SERVER_METHOD:
        return SSLv23_server_method();
    case SW_SSLv23_CLIENT_METHOD:
        return SSLv23_client_method();
    case SW_TLSv1_METHOD:
        return TLSv1_method();
    case SW_TLSv1_SERVER_METHOD:
        return TLSv1_server_method();
    case SW_TLSv1_CLIENT_METHOD:
        return TLSv1_client_method();
#ifdef TLS1_1_VERSION
    case SW_TLSv1_1_METHOD:
        return TLSv1_1_method();
    case SW_TLSv1_1_SERVER_METHOD:
        return TLSv1_1_server_method();
    case SW_TLSv1_1_CLIENT_METHOD:
        return TLSv1_1_client_method();
#endif
#ifdef TLS1_2_VERSION
    case SW_TLSv1_2_METHOD:
        return TLSv1_2_method();
    case SW_TLSv1_2_SERVER_METHOD:
        return TLSv1_2_server_method();
    case SW_TLSv1_2_CLIENT_METHOD:
        return TLSv1_2_client_method();
#endif
    case SW_DTLSv1_METHOD:
        return DTLSv1_method();
    case SW_DTLSv1_SERVER_METHOD:
        return DTLSv1_server_method();
    case SW_DTLSv1_CLIENT_METHOD:
        return DTLSv1_client_method();
    case SW_SSLv23_METHOD:
    default:
        return SSLv23_method();
    }
    return SSLv23_method();
}
Esempio n. 8
0
static const SSL_METHOD *
ssl23_get_server_method(int ver)
{
	if (ver == SSL3_VERSION)
		return (SSLv3_server_method());
	else if (ver == TLS1_VERSION)
		return (TLSv1_server_method());
	else if (ver == TLS1_1_VERSION)
		return (TLSv1_1_server_method());
	else if (ver == TLS1_2_VERSION)
		return (TLSv1_2_server_method());
	else
		return (NULL);
}
Esempio n. 9
0
static const SSL_METHOD *ssl23_get_server_method(int ver)
	{
#ifndef OPENSSL_NO_SSL3
	if (ver == SSL3_VERSION)
		return(SSLv3_server_method());
#endif
	if (ver == TLS1_VERSION)
		return(TLSv1_server_method());
	else if (ver == TLS1_1_VERSION)
		return(TLSv1_1_server_method());
	else if (ver == TLS1_2_VERSION)
		return(TLSv1_2_server_method());
	else
		return(NULL);
	}
Esempio n. 10
0
static const SSL_METHOD *tls1_get_server_method(int ver)
{
    if (ver == TLS_ANY_VERSION)
        return TLS_server_method();
    if (ver == TLS1_2_VERSION)
        return TLSv1_2_server_method();
    if (ver == TLS1_1_VERSION)
        return TLSv1_1_server_method();
    if (ver == TLS1_VERSION)
        return TLSv1_server_method();
#ifndef OPENSSL_NO_SSL3
    if (ver == SSL3_VERSION)
        return (SSLv3_server_method());
#endif
    return NULL;
}
Esempio n. 11
0
SSL_CTX* EdSSLContext::buildServerCtx(int sslmethod, const char* certfile, const char* privkeyfile)
{
	const SSL_METHOD *method;
	switch (sslmethod)
	{
	case SSL_VER_TLSV1:
		method = TLSv1_server_method();
		break;
	case SSL_VER_TLSV11:
		method = TLSv1_1_server_method();
		break;
	case SSL_VER_V23:
		method = SSLv23_server_method();
		break;
	case SSL_VER_V3:
		method = SSLv3_server_method();
		break;
	case SSL_VER_DTLSV1:
		method = DTLSv1_server_method();
		break;
	default:
		method = NULL;
		break;
	}

	if (method == NULL)
		return NULL;

	SSL_CTX* pctx = SSL_CTX_new(method);

	int ret;
	ret = SSL_CTX_use_certificate_file(pctx, certfile, SSL_FILETYPE_PEM);
	dbgd("set cert file, ret=%d", ret);
	ret = SSL_CTX_use_PrivateKey_file(pctx, privkeyfile, SSL_FILETYPE_PEM);
	dbgd("set key file, ret=%d", ret);

	if (!SSL_CTX_check_private_key(pctx))
	{
		dbge("### private key check error......");
		SSL_CTX_free(pctx);
		return NULL;
	}
	return pctx;
}
Esempio n. 12
0
static const SSL_METHOD *swSSL_get_method(int method)
{
    switch (method)
    {
    case SW_SSLv3_METHOD:
        return SSLv3_method();
    case SW_SSLv3_SERVER_METHOD:
        return SSLv3_server_method();
    case SW_SSLv3_CLIENT_METHOD:
        return SSLv3_client_method();
    case SW_SSLv23_SERVER_METHOD:
        return SSLv23_server_method();
    case SW_SSLv23_CLIENT_METHOD:
        return SSLv23_client_method();
    case SW_TLSv1_METHOD:
        return TLSv1_method();
    case SW_TLSv1_SERVER_METHOD:
        return TLSv1_server_method();
    case SW_TLSv1_CLIENT_METHOD:
        return TLSv1_client_method();
    case SW_TLSv1_1_METHOD:
        return TLSv1_1_method();
    case SW_TLSv1_1_SERVER_METHOD:
        return TLSv1_1_server_method();
    case SW_TLSv1_1_CLIENT_METHOD:
        return TLSv1_1_client_method();
    case SW_TLSv1_2_METHOD:
        return TLSv1_2_method();
    case SW_TLSv1_2_SERVER_METHOD:
        return TLSv1_2_server_method();
    case SW_TLSv1_2_CLIENT_METHOD:
        return TLSv1_2_client_method();
    case SW_DTLSv1_METHOD:
        return DTLSv1_method();
    case SW_DTLSv1_SERVER_METHOD:
        return DTLSv1_server_method();
    case SW_DTLSv1_CLIENT_METHOD:
        return DTLSv1_client_method();
    case SW_SSLv23_METHOD:
    default:
        return SSLv23_method();
    }
    return SSLv23_method();
}
Esempio n. 13
0
bud_error_t bud_config_new_ssl_ctx(bud_config_t* config,
                                   bud_context_t* context) {
  SSL_CTX* ctx;
  int ecdh_nid;
  EC_KEY* ecdh;
  bud_error_t err;
  int options;
  int r;
  const char* ticket_key;
  size_t max_len;

  if (context->backend != NULL) {
    if (context->backend->keepalive == -1)
      context->backend->keepalive = kBudDefaultKeepalive;
    r = bud_config_str_to_addr(context->backend->host,
                               context->backend->port,
                               &context->backend->addr);
    if (r != 0)
      return bud_error_num(kBudErrPton, r);
  }

  /* Decode ticket_key */
  ticket_key = context->ticket_key == NULL ? config->frontend.ticket_key :
                                             context->ticket_key;
  if (ticket_key != NULL) {
    max_len = sizeof(context->ticket_key_storage);
    if (bud_base64_decode(context->ticket_key_storage,
                          max_len,
                          ticket_key,
                          strlen(ticket_key)) < max_len) {
      return bud_error(kBudErrSmallTicketKey);
    }
  }

  /* Choose method, tlsv1_2 by default */
  if (config->frontend.method == NULL) {
    if (strcmp(config->frontend.security, "tls1.1") == 0)
      config->frontend.method = TLSv1_1_server_method();
    else if (strcmp(config->frontend.security, "tls1.0") == 0)
      config->frontend.method = TLSv1_server_method();
    else if (strcmp(config->frontend.security, "tls1.2") == 0)
      config->frontend.method = TLSv1_2_server_method();
    else if (strcmp(config->frontend.security, "ssl3") == 0)
      config->frontend.method = SSLv3_server_method();
    else
      config->frontend.method = SSLv23_server_method();
  }

  ctx = SSL_CTX_new(config->frontend.method);
  if (ctx == NULL)
    return bud_error_str(kBudErrNoMem, "SSL_CTX");

  /* Disable sessions, they won't work with cluster anyway */
  SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);

  if (config->frontend.max_send_fragment)
    SSL_CTX_set_max_send_fragment(ctx, config->frontend.max_send_fragment);

  if (ticket_key != NULL) {
    SSL_CTX_set_tlsext_ticket_keys(ctx,
                                   context->ticket_key_storage,
                                   sizeof(context->ticket_key_storage));
  }

  /* ECDH curve selection */
  if (context->ecdh != NULL || config->frontend.ecdh != NULL) {
    if (context->ecdh != NULL)
      ecdh_nid = OBJ_sn2nid(context->ecdh);
    else
      ecdh_nid = OBJ_sn2nid(config->frontend.ecdh);

    if (ecdh_nid == NID_undef) {
      ecdh = NULL;
      err = bud_error_str(kBudErrECDHNotFound,
                          context->ecdh == NULL ? config->frontend.ecdh :
                                                  context->ecdh);
      goto fatal;
    }

    ecdh = EC_KEY_new_by_curve_name(ecdh_nid);
    if (ecdh == NULL) {
      err = bud_error_str(kBudErrNoMem, "EC_KEY");
      goto fatal;
    }

    SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE);
    SSL_CTX_set_tmp_ecdh(ctx, ecdh);
    EC_KEY_free(ecdh);
  }
  ecdh = NULL;

  /* Cipher suites */
  if (context->ciphers != NULL)
    SSL_CTX_set_cipher_list(ctx, context->ciphers);
  else if (config->frontend.ciphers != NULL)
    SSL_CTX_set_cipher_list(ctx, config->frontend.ciphers);

  /* Disable SSL2 */
  options = SSL_OP_NO_SSLv2 | SSL_OP_ALL;
  if (!config->frontend.ssl3)
    options |= SSL_OP_NO_SSLv3;

  if (config->frontend.server_preference)
    options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
  SSL_CTX_set_options(ctx, options);

#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
  if (config->context_count != 0) {
    SSL_CTX_set_tlsext_servername_callback(ctx,
                                           bud_config_select_sni_context);
    SSL_CTX_set_tlsext_servername_arg(ctx, config);
  }
#endif  /* SSL_CTRL_SET_TLSEXT_SERVERNAME_CB */

#ifdef OPENSSL_NPN_NEGOTIATED
  context->npn_line = bud_config_encode_npn(config,
                                            context->npn,
                                            &context->npn_line_len,
                                            &err);
  if (!bud_is_ok(err))
    goto fatal;

  if (context->npn_line != NULL) {
    SSL_CTX_set_next_protos_advertised_cb(ctx,
                                          bud_config_advertise_next_proto,
                                          context);
  }
#else  /* !OPENSSL_NPN_NEGOTIATED */
  err = bud_error(kBudErrNPNNotSupported);
  goto fatal;
#endif  /* OPENSSL_NPN_NEGOTIATED */

  SSL_CTX_set_tlsext_status_cb(ctx, bud_client_stapling_cb);

  context->ctx = ctx;
  return bud_ok();

fatal:
  if (ecdh != NULL)
    EC_KEY_free(ecdh);

  SSL_CTX_free(ctx);
  return err;
}
Esempio n. 14
0
static int openssl_ssl_ctx_new(lua_State*L)
{
  const char* meth = luaL_optstring(L, 1, "TLSv1");
#if OPENSSL_VERSION_NUMBER >= 0x01000000L
  const
#endif
  SSL_METHOD* method = NULL;
  const char* ciphers;
  SSL_CTX* ctx;
  if (strcmp(meth, "SSLv3") == 0)
    method = SSLv3_method();    /* SSLv3 */
  else if (strcmp(meth, "SSLv3_server") == 0)
    method = SSLv3_server_method(); /* SSLv3 */
  else if (strcmp(meth, "SSLv3_client") == 0)
    method = SSLv3_client_method(); /* SSLv3 */
  else if (strcmp(meth, "SSLv23") == 0)
    method = SSLv23_method();   /* SSLv3 but can rollback to v2 */
  else if (strcmp(meth, "SSLv23_server") == 0)
    method = SSLv23_server_method();  /* SSLv3 but can rollback to v2 */
  else if (strcmp(meth, "SSLv23_client") == 0)
    method = SSLv23_client_method();  /* SSLv3 but can rollback to v2 */

  else if (strcmp(meth, "TLSv1_1") == 0)
    method = TLSv1_1_method();    /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_1_server") == 0)
    method = TLSv1_1_server_method(); /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_1_client") == 0)
    method = TLSv1_1_client_method(); /* TLSv1.0 */

  else if (strcmp(meth, "TLSv1_2") == 0)
    method = TLSv1_2_method();    /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_2_server") == 0)
    method = TLSv1_2_server_method(); /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_2_client") == 0)
    method = TLSv1_2_client_method(); /* TLSv1.0 */

  else if (strcmp(meth, "TLSv1") == 0)
    method = TLSv1_method();    /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_server") == 0)
    method = TLSv1_server_method(); /* TLSv1.0 */
  else if (strcmp(meth, "TLSv1_client") == 0)
    method = TLSv1_client_method(); /* TLSv1.0 */

  else if (strcmp(meth, "DTLSv1") == 0)
    method = DTLSv1_method();   /* DTLSv1.0 */
  else if (strcmp(meth, "DTLSv1_server") == 0)
    method = DTLSv1_server_method();  /* DTLSv1.0 */
  else if (strcmp(meth, "DTLSv1_client") == 0)
    method = DTLSv1_client_method();  /* DTLSv1.0 */
#ifndef OPENSSL_NO_SSL2
#if OPENSSL_VERSION_NUMBER < 0x10100000L
  else if (strcmp(meth, "SSLv2") == 0)
    method = SSLv2_method();    /* SSLv2 */
  else if (strcmp(meth, "SSLv2_server") == 0)
    method = SSLv2_server_method(); /* SSLv2 */
  else if (strcmp(meth, "SSLv2_client") == 0)
    method = SSLv2_client_method();
#endif
#ifdef LOAD_SSL_CUSTOM
  LOAD_SSL_CUSTOM
#endif

#endif
  else
    luaL_error(L, "#1:%s not supported\n"
               "Maybe SSLv3 SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n",
               "default is SSLv3",
               meth);
  ciphers = luaL_optstring(L, 2, SSL_DEFAULT_CIPHER_LIST);
  ctx = SSL_CTX_new(method);
  if (!ctx)
    luaL_error(L, "#1:%s not supported\n"
               "Maybe SSLv3 SSLv23 TLSv1 TLSv1_1 TLSv1_2 DTLSv1 [SSLv2], option followed by _client or _server\n",
               "default is SSLv3",
               meth);
  openssl_newvalue(L, ctx);
  SSL_CTX_set_cipher_list(ctx, ciphers);
  PUSH_OBJECT(ctx, "openssl.ssl_ctx");
  SSL_CTX_set_app_data(ctx, L);

  return 1;
}
Esempio n. 15
0
bud_error_t bud_config_new_ssl_ctx(bud_config_t* config,
                                   bud_context_t* context) {
  SSL_CTX* ctx;
  bud_error_t err;
  int options;

  /* Choose method, tlsv1_2 by default */
  if (config->frontend.method == NULL) {
    if (strcmp(config->frontend.security, "tls1.1") == 0)
      config->frontend.method = TLSv1_1_server_method();
    else if (strcmp(config->frontend.security, "tls1.0") == 0)
      config->frontend.method = TLSv1_server_method();
    else if (strcmp(config->frontend.security, "tls1.2") == 0)
      config->frontend.method = TLSv1_2_server_method();
    else if (strcmp(config->frontend.security, "ssl3") == 0)
      config->frontend.method = SSLv3_server_method();
    else
      config->frontend.method = SSLv23_server_method();
  }

  ctx = SSL_CTX_new(config->frontend.method);
  if (ctx == NULL)
    return bud_error_str(kBudErrNoMem, "SSL_CTX");
  SSL_CTX_set_session_cache_mode(ctx,
                                 SSL_SESS_CACHE_SERVER |
                                 SSL_SESS_CACHE_NO_INTERNAL |
                                 SSL_SESS_CACHE_NO_AUTO_CLEAR);
  if (context->ciphers != NULL)
    SSL_CTX_set_cipher_list(ctx, context->ciphers);
  else if (config->frontend.ciphers != NULL)
    SSL_CTX_set_cipher_list(ctx, config->frontend.ciphers);

  /* Disable SSL2 */
  options = SSL_OP_NO_SSLv2 | SSL_OP_ALL;
  if (!config->frontend.ssl3)
    options |= SSL_OP_NO_SSLv3;

  if (config->frontend.server_preference)
    options |= SSL_OP_CIPHER_SERVER_PREFERENCE;
  SSL_CTX_set_options(ctx, options);

#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
  if (config->context_count != 0) {
    SSL_CTX_set_tlsext_servername_callback(ctx,
                                           bud_config_select_sni_context);
    SSL_CTX_set_tlsext_servername_arg(ctx, config);
  }
#endif  /* SSL_CTRL_SET_TLSEXT_SERVERNAME_CB */

#ifdef OPENSSL_NPN_NEGOTIATED
  context->npn_line = bud_config_encode_npn(config,
                                            context->npn,
                                            &context->npn_line_len,
                                            &err);
  if (!bud_is_ok(err))
    goto fatal;

  if (context->npn_line != NULL) {
    SSL_CTX_set_next_protos_advertised_cb(ctx,
                                          bud_config_advertise_next_proto,
                                          context);
  }
#else  /* !OPENSSL_NPN_NEGOTIATED */
  err = bud_error(kBudErrNPNNotSupported);
  goto fatal;
#endif  /* OPENSSL_NPN_NEGOTIATED */

  SSL_CTX_set_tlsext_status_cb(ctx, bud_client_stapling_cb);

  context->ctx = ctx;
  return bud_ok();

fatal:
  SSL_CTX_free(ctx);
  return err;
}
Esempio n. 16
0
static const SSL_METHOD *get_method(int protocol, int type)
{
  const SSL_METHOD *method = NULL;

  caml_enter_blocking_section();
  switch (protocol)
  {
    case 0:
      switch (type)
      {
        case 0:
          method = SSLv23_client_method();
          break;

        case 1:
          method = SSLv23_server_method();
          break;

        case 2:
          method = SSLv23_method();
          break;
      }
      break;

    case 1:
      switch (type)
      {
        case 0:
          method = SSLv3_client_method();
          break;

        case 1:
          method = SSLv3_server_method();
          break;

        case 2:
          method = SSLv3_method();
          break;
      }
      break;

    case 2:
      switch (type)
      {
        case 0:
          method = TLSv1_client_method();
          break;

        case 1:
          method = TLSv1_server_method();
          break;

        case 2:
          method = TLSv1_method();
          break;
      }
      break;

    case 3:
#ifdef HAVE_TLS11
      switch (type)
      {
        case 0:
          method = TLSv1_1_client_method();
          break;

        case 1:
          method = TLSv1_1_server_method();
          break;

        case 2:
          method = TLSv1_1_method();
          break;
      }
#endif
      break;

    case 4:
#ifdef HAVE_TLS12
      switch (type)
      {
        case 0:
          method = TLSv1_2_client_method();
          break;

        case 1:
          method = TLSv1_2_server_method();
          break;

        case 2:
          method = TLSv1_2_method();
          break;
      }
#endif
      break;

    default:
      caml_leave_blocking_section();
      caml_invalid_argument("Unknown method (this should not have happened, please report).");
      break;
  }
  caml_leave_blocking_section();

  if (method == NULL)
    caml_raise_constant(*caml_named_value("ssl_exn_method_error"));

  return method;
}
Esempio n. 17
0
int
ssl23_get_client_hello(SSL *s)
{
	char buf_space[11]; /* Request this many bytes in initial read.
	* We can detect SSL 3.0/TLS 1.0 Client Hellos
	* ('type == 3') correctly only when the following
	* is in a single record, which is not guaranteed by
	* the protocol specification:
	* Byte  Content
	*  0     type            \
	                     *  1/2   version          > record header
	*  3/4   length          /
	*  5     msg_type        \
	                     *  6-8   length           > Client Hello message
	*  9/10  client_version  /
	                     */
	char *buf = &(buf_space[0]);
	unsigned char *p, *d, *d_len, *dd;
	unsigned int i;
	unsigned int csl, sil, cl;
	int n = 0, j;
	int type = 0;
	int v[2];

	if (s->state ==	SSL23_ST_SR_CLNT_HELLO_A) {
		/* read the initial header */
		v[0] = v[1] = 0;

		if (!ssl3_setup_buffers(s))
			goto err;

		n = ssl23_read_bytes(s, sizeof buf_space);
		if (n != sizeof buf_space)
			return(n); /* n == -1 || n == 0 */

		p = s->packet;

		memcpy(buf, p, n);

		if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) {
			/*
			 * SSLv2 header
			 */
			if ((p[3] == 0x00) && (p[4] == 0x02)) {
				v[0] = p[3];
				v[1] = p[4];
				/* SSLv2 */
				if (!(s->options & SSL_OP_NO_SSLv2))
					type = 1;
			} else if (p[3] == SSL3_VERSION_MAJOR) {
				v[0] = p[3];
				v[1] = p[4];
				/* SSLv3/TLSv1 */
				if (p[4] >= TLS1_VERSION_MINOR) {
					if (p[4] >= TLS1_2_VERSION_MINOR &&
					    !(s->options & SSL_OP_NO_TLSv1_2)) {
						s->version = TLS1_2_VERSION;
						s->state = SSL23_ST_SR_CLNT_HELLO_B;
					} else if (p[4] >= TLS1_1_VERSION_MINOR &&
					    !(s->options & SSL_OP_NO_TLSv1_1)) {
						s->version = TLS1_1_VERSION;
						/* type=2; */ /* done later to survive restarts */
						s->state = SSL23_ST_SR_CLNT_HELLO_B;
					} else if (!(s->options & SSL_OP_NO_TLSv1)) {
						s->version = TLS1_VERSION;
						/* type=2; */ /* done later to survive restarts */
						s->state = SSL23_ST_SR_CLNT_HELLO_B;
					} else if (!(s->options & SSL_OP_NO_SSLv3)) {
						s->version = SSL3_VERSION;
						/* type=2; */
						s->state = SSL23_ST_SR_CLNT_HELLO_B;
					} else if (!(s->options & SSL_OP_NO_SSLv2)) {
						type = 1;
					}
				} else if (!(s->options & SSL_OP_NO_SSLv3)) {
					s->version = SSL3_VERSION;
					/* type=2; */
					s->state = SSL23_ST_SR_CLNT_HELLO_B;
				} else if (!(s->options & SSL_OP_NO_SSLv2))
					type = 1;

			}
		} else if ((p[0] == SSL3_RT_HANDSHAKE) &&
		    (p[1] == SSL3_VERSION_MAJOR) &&
		    (p[5] == SSL3_MT_CLIENT_HELLO) &&
		    ((p[3] == 0 && p[4] < 5 /* silly record length? */)
		    || (p[9] >= p[1]))) {
			/*
			 * SSLv3 or tls1 header
			 */

			v[0] = p[1]; /* major version (= SSL3_VERSION_MAJOR) */
			/* We must look at client_version inside the Client Hello message
			 * to get the correct minor version.
			 * However if we have only a pathologically small fragment of the
			 * Client Hello message, this would be difficult, and we'd have
			 * to read more records to find out.
			 * No known SSL 3.0 client fragments ClientHello like this,
			 * so we simply assume TLS 1.0 to avoid protocol version downgrade
			 * attacks. */
			if (p[3] == 0 && p[4] < 6) {
#if 0
				SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_SMALL);
				goto err;
#else
				v[1] = TLS1_VERSION_MINOR;
#endif
			}
			/* if major version number > 3 set minor to a value
			 * which will use the highest version 3 we support.
			 * If TLS 2.0 ever appears we will need to revise
			 * this....
			 */
			else if (p[9] > SSL3_VERSION_MAJOR)
				v[1] = 0xff;
			else
				v[1] = p[10]; /* minor version according to client_version */
			if (v[1] >= TLS1_VERSION_MINOR) {
				if (v[1] >= TLS1_2_VERSION_MINOR &&
				    !(s->options & SSL_OP_NO_TLSv1_2)) {
					s->version = TLS1_2_VERSION;
					type = 3;
				} else if (v[1] >= TLS1_1_VERSION_MINOR &&
				    !(s->options & SSL_OP_NO_TLSv1_1)) {
					s->version = TLS1_1_VERSION;
					type = 3;
				} else if (!(s->options & SSL_OP_NO_TLSv1)) {
					s->version = TLS1_VERSION;
					type = 3;
				} else if (!(s->options & SSL_OP_NO_SSLv3)) {
					s->version = SSL3_VERSION;
					type = 3;
				}
			} else {
				/* client requests SSL 3.0 */
				if (!(s->options & SSL_OP_NO_SSLv3)) {
					s->version = SSL3_VERSION;
					type = 3;
				} else if (!(s->options & SSL_OP_NO_TLSv1)) {
					/* we won't be able to use TLS of course,
					 * but this will send an appropriate alert */
					s->version = TLS1_VERSION;
					type = 3;
				}
			}
		}
		else if ((strncmp("GET ", (char *)p, 4) == 0) ||
		    (strncmp("POST ",(char *)p, 5) == 0) ||
		    (strncmp("HEAD ",(char *)p, 5) == 0) ||
		    (strncmp("PUT ", (char *)p, 4) == 0)) {
			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTP_REQUEST);
			goto err;
		} else if (strncmp("CONNECT", (char *)p, 7) == 0) {
			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTPS_PROXY_REQUEST);
			goto err;
		}
	}

	if (s->state == SSL23_ST_SR_CLNT_HELLO_B) {
		/* we have SSLv3/TLSv1 in an SSLv2 header
		 * (other cases skip this state) */

		type = 2;
		p = s->packet;
		v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
		v[1] = p[4];

		n = ((p[0] & 0x7f) << 8) | p[1];
		if (n > (1024 * 4)) {
			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_LARGE);
			goto err;
		}

		j = ssl23_read_bytes(s, n + 2);
		if (j <= 0)
			return (j);

		ssl3_finish_mac(s, s->packet + 2, s->packet_length - 2);
		if (s->msg_callback)
			s->msg_callback(0, SSL2_VERSION, 0, s->packet + 2,
			    s->packet_length-2, s, s->msg_callback_arg);

		p = s->packet;
		p += 5;
		n2s(p, csl);
		n2s(p, sil);
		n2s(p, cl);
		d = (unsigned char *)s->init_buf->data;
		if ((csl + sil + cl + 11) != s->packet_length)
		{
			/*
			 * We can't have TLS extensions in SSL 2.0 format
			 * Client Hello, can we ? Error condition should be
			 * '>' otherwise
			 */
			SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,
			    SSL_R_RECORD_LENGTH_MISMATCH);
			goto err;
		}

		/* record header: msg_type ... */
		*(d++) = SSL3_MT_CLIENT_HELLO;
		/* ... and length (actual value will be written later) */
		d_len = d;
		d += 3;

		/* client_version */
		*(d++) = SSL3_VERSION_MAJOR; /* == v[0] */
		*(d++) = v[1];

		/* lets populate the random area */
		/* get the challenge_length */
		i = (cl > SSL3_RANDOM_SIZE) ? SSL3_RANDOM_SIZE : cl;
		memset(d, 0, SSL3_RANDOM_SIZE);
		memcpy(&(d[SSL3_RANDOM_SIZE - i]), &(p[csl + sil]), i);
		d += SSL3_RANDOM_SIZE;

		/* no session-id reuse */
		*(d++) = 0;

		/* ciphers */
		j = 0;
		dd = d;
		d += 2;
		for (i = 0; i < csl; i += 3) {
			if (p[i] != 0)
				continue;
			*(d++) = p[i + 1];
			*(d++) = p[i + 2];
			j += 2;
		}
		s2n(j, dd);

		/* COMPRESSION */
		*(d++) = 1;
		*(d++) = 0;

#if 0
		/* copy any remaining data with may be extensions */
		p = p + csl + sil + cl;
		while (p <  s->packet + s->packet_length) {
			*(d++)=*(p++);
		}
#endif

		i = (d - (unsigned char *)s->init_buf->data) - 4;
		l2n3((long)i, d_len);

		/* get the data reused from the init_buf */
		s->s3->tmp.reuse_message = 1;
		s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO;
		s->s3->tmp.message_size = i;
	}

	/* imaginary new state (for program structure): */
	/* s->state = SSL23_SR_CLNT_HELLO_C */

	if (type == 1) {
		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL);
		goto err;
	}

	if ((type == 2) || (type == 3)) {
		/* we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) */

		if (!ssl_init_wbio_buffer(s, 1)) goto err;

		/* we are in this state */
		s->state = SSL3_ST_SR_CLNT_HELLO_A;

		if (type == 3) {
			/* put the 'n' bytes we have read into the input buffer
			 * for SSLv3 */
			s->rstate = SSL_ST_READ_HEADER;
			s->packet_length = n;
			if (s->s3->rbuf.buf == NULL)
				if (!ssl3_setup_read_buffer(s))
					goto err;

			s->packet = &(s->s3->rbuf.buf[0]);
			memcpy(s->packet, buf, n);
			s->s3->rbuf.left = n;
			s->s3->rbuf.offset = 0;
		} else {
			s->packet_length = 0;
			s->s3->rbuf.left = 0;
			s->s3->rbuf.offset = 0;
		}
		if (s->version == TLS1_2_VERSION)
			s->method = TLSv1_2_server_method();
		else if (s->version == TLS1_1_VERSION)
			s->method = TLSv1_1_server_method();
		else if (s->version == TLS1_VERSION)
			s->method = TLSv1_server_method();
		else
			s->method = SSLv3_server_method();
#if 0 /* ssl3_get_client_hello does this */
		s->client_version = (v[0]<<8)|v[1];
#endif
		s->handshake_func = s->method->ssl_accept;
	}

	if ((type < 1) || (type > 3)) {
		/* bad, very bad */
		SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL);
		goto err;
	}
	s->init_num = 0;

	if (buf != buf_space)
		OPENSSL_free(buf);
	return (SSL_accept(s));
err:
	if (buf != buf_space)
		OPENSSL_free(buf);
	return (-1);
}
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = 0;
    int      clientfd = 0;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    char   msg[] = "I hear you fa shizzle!";
    char   input[1024];
    int    idx;
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    int    port = yasslPort;
    int    usePsk = 0;
    int    doDTLS = 0;
    int    useNtruKey = 0;
    char*  cipherList = NULL;
    char*  verifyCert = (char*)cliCert;
    char*  ourCert    = (char*)svrCert;
    char*  ourKey     = (char*)svrKey;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

    ((func_args*)args)->return_code = -1; /* error state */

    while ((ch = mygetopt(argc, argv, "?dbsnup:v:l:A:c:k:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                version = -1;  /* DTLS flag */
                break;

            case 'p' :
                port = atoi(myoptarg);
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                if (doDTLS)
                    version = -1;  /* stay with DTLS */
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    argc -= myoptind;
    argv += myoptind;
    myoptind = 0;      /* reset for test cases */

    switch (version) {
        case 0:
            method = SSLv3_server_method();
            break;

        case 1:
            method = TLSv1_server_method();
            break;

        case 2:
            method = TLSv1_1_server_method();
            break;

        case 3:
            method = TLSv1_2_server_method();
            break;

#ifdef CYASSL_DTLS
        case -1:
            method = DTLSv1_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("can't set cipher list");

    if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                     != SSL_SUCCESS)
        err_sys("can't load server cert file, check file and run from"
                " CyaSSL home dir");


#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                               != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from CyaSSL home dir");
    }
#endif

    if (!useNtruKey) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                " CyaSSL home dir");
    }

#ifndef NO_PSK
    if (usePsk) {
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
        SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
        if (cipherList == NULL)
            if (SSL_CTX_set_cipher_list(ctx,"PSK-AES256-CBC-SHA") !=SSL_SUCCESS)
                err_sys("can't set cipher list");
    }
#endif

    /* if not using PSK, verify peer with certs */
    if (doCliCertCheck && usePsk == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    }

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA") != SSL_SUCCESS)
        err_sys("can't set cipher list");
#endif

    ssl = SSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL");

#ifdef HAVE_CRL
    CyaSSL_EnableCRL(ssl, 0);
    CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
                                                     CYASSL_CRL_START_MON);
    CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS);
    if (!doDTLS) 
        CloseSocket(sockfd);

    SSL_set_fd(ssl, clientfd);
#ifdef NO_PSK
    #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
        CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
    #else
        SetDH(ssl);  /* will repick suites with DHE, higher priority than PSK */
    #endif
#endif

#ifdef NON_BLOCKING
    tcp_set_nonblocking(&clientfd);
    NonBlockingSSL_Accept(ssl);
#else
    #ifndef CYASSL_CALLBACKS
        if (SSL_accept(ssl) != SSL_SUCCESS) {
            int err = SSL_get_error(ssl, 0);
            char buffer[80];
            printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
            err_sys("SSL_accept failed");
        }
    #else
        NonBlockingSSL_Accept(ssl);
    #endif
#endif
    showPeer(ssl);

    idx = SSL_read(ssl, input, sizeof(input));
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);
    }
    
    if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
        err_sys("SSL_write failed");

    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    
    CloseSocket(clientfd);
    ((func_args*)args)->return_code = 0;
    return 0;
}
Esempio n. 19
0
eventer_ssl_ctx_t *
eventer_ssl_ctx_new(eventer_ssl_orientation_t type,
                    const char *layer,
                    const char *certificate, const char *key,
                    const char *ca, const char *ciphers) {
  char ssl_ctx_key[SSL_CTX_KEYLEN];
  eventer_ssl_ctx_t *ctx;
  const char *layer_str;
  char *ctx_layer, *opts;
  char *opts_fallback = DEFAULT_OPTS_STRING;
  time_t now;
  ctx = calloc(1, sizeof(*ctx));
  if(!ctx) return NULL;

  layer_str = layer ? layer : DEFAULT_LAYER_STRING;
  ctx_layer = alloca(strlen(layer_str)+1);
  memcpy(ctx_layer, layer_str, strlen(layer_str)+1);
  opts = strchr(ctx_layer,':');
  if(opts) *opts++ = '\0';
  else {
    opts = alloca(strlen(opts_fallback)+1);
    memcpy(opts, opts_fallback, strlen(opts_fallback)+1);
  }

  now = time(NULL);
  ssl_ctx_key_write(ssl_ctx_key, sizeof(ssl_ctx_key),
                    type, layer, certificate, key, ca, ciphers);
  ctx->ssl_ctx_cn = ssl_ctx_cache_get(ssl_ctx_key);
  if(ctx->ssl_ctx_cn) {
    if(now - ctx->ssl_ctx_cn->creation_time > ssl_ctx_cache_expiry ||
       (now - ctx->ssl_ctx_cn->last_stat_time > ssl_ctx_cache_finfo_expiry &&
           (validate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate) ||
            validate_finfo(&ctx->ssl_ctx_cn->key_finfo, key) ||
            validate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca) || 
            (ctx->ssl_ctx_cn->last_stat_time = now) == 0))) { /* assignment */
      ssl_ctx_cache_remove(ssl_ctx_key);
      ssl_ctx_cache_node_free(ctx->ssl_ctx_cn);
      ctx->ssl_ctx_cn = NULL;
    }
  }

  if(!ctx->ssl_ctx_cn) {
    char *part = NULL, *brkt = NULL;
    long ctx_options = 0;
    ssl_ctx_cache_node *existing_ctx_cn;
    ctx->ssl_ctx_cn = calloc(1, sizeof(*ctx->ssl_ctx_cn));
    ctx->ssl_ctx_cn->key = strdup(ssl_ctx_key);
    ctx->ssl_ctx_cn->refcnt = 1;
    ctx->ssl_ctx_cn->creation_time = now;
    ctx->ssl_ctx_cn->last_stat_time = now;
    populate_finfo(&ctx->ssl_ctx_cn->cert_finfo, certificate);
    populate_finfo(&ctx->ssl_ctx_cn->key_finfo, key);
    populate_finfo(&ctx->ssl_ctx_cn->ca_finfo, ca);
    ctx->ssl_ctx = NULL;
    if(0)
      ;
#if defined(SSL_TXT_SSLV3) && defined(HAVE_SSLV3_SERVER) && defined(HAVE_SSLV3_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_SSLV3))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 SSLv3_server_method() : SSLv3_client_method());
#endif
#if defined(SSL_TXT_SSLV2) && defined(HAVE_SSLV2_SERVER) && defined(HAVE_SSLV2_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_SSLV2))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 SSLv2_server_method() : SSLv2_client_method());
#endif
#if defined(SSL_TXT_TLSV1) && defined(HAVE_TLSV1_SERVER) && defined(HAVE_TLSV1_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 TLSv1_server_method() : TLSv1_client_method());
#endif
#if defined(SSL_TXT_TLSV1_1) && defined(HAVE_TLSV1_1_SERVER) && defined(HAVE_TLSV1_1_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_1))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 TLSv1_1_server_method() : TLSv1_1_client_method());
#endif
#if defined(SSL_TXT_TLSV1_2) && defined(HAVE_TLSV1_2_SERVER) && defined(HAVE_TLSV1_2_CLIENT)
    else if(layer && !strcasecmp(layer, SSL_TXT_TLSV1_2))
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 TLSv1_2_server_method() : TLSv1_2_client_method());
#endif
    if(ctx->ssl_ctx == NULL)
      ctx->ssl_ctx = SSL_CTX_new(type == SSL_SERVER ?
                                 SSLv23_server_method() : SSLv23_client_method());
    if(!ctx->ssl_ctx) goto bail;

    for(part = strtok_r(opts, ",", &brkt);
        part;
        part = strtok_r(NULL, ",", &brkt)) {
      char *optname = part;
      int neg = 0;
      if(*optname == '!') neg = 1, optname++;

#define SETBITOPT(name, neg, opt) \
  if(!strcasecmp(optname, name)) { \
    if(neg) ctx_options &= ~(opt); \
    else    ctx_options |= (opt); \
  }

      SETBITOPT("all", neg, SSL_OP_ALL)
#ifdef SSL_TXT_SSLV2
      else SETBITOPT(SSL_TXT_SSLV2, !neg, SSL_OP_NO_SSLv2)
#endif
#ifdef SSL_TXT_SSLV3
      else SETBITOPT(SSL_TXT_SSLV3, !neg, SSL_OP_NO_SSLv3)
#endif
#ifdef SSL_TXT_TLSV1
      else SETBITOPT(SSL_TXT_TLSV1, !neg, SSL_OP_NO_TLSv1)
#endif
#ifdef SSL_TXT_TLSV1_1
      else SETBITOPT(SSL_TXT_TLSV1_1, !neg, SSL_OP_NO_TLSv1_1)
#endif
#ifdef SSL_TXT_TLSV1_2
      else SETBITOPT(SSL_TXT_TLSV1_2, !neg, SSL_OP_NO_TLSv1_2)
#endif
#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
      else SETBITOPT("cipher_server_preference", neg, SSL_OP_CIPHER_SERVER_PREFERENCE)
#endif
      else {
        mtevL(mtev_error, "SSL layer part '%s' not understood.\n", optname);
      }
    }

    if (type == SSL_SERVER)
      SSL_CTX_set_session_id_context(ctx->ssl_ctx,
              (unsigned char *)EVENTER_SSL_DATANAME,
              sizeof(EVENTER_SSL_DATANAME)-1);
#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
    ctx_options &= ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
#endif
#ifdef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
    ctx_options &= ~SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG;
#endif
#ifdef SSL_OP_NO_COMPRESSION
    ctx_options |= SSL_OP_NO_COMPRESSION;
#endif
#ifdef SSL_OP_NO_TICKET
    ctx_options |= SSL_OP_NO_TICKET;
#endif
#ifdef SSL_OP_SINGLE_DH_USE
    ctx_options |= SSL_OP_SINGLE_DH_USE;
#endif
#ifdef SSL_OP_SINGLE_ECDH_USE
    ctx_options |= SSL_OP_SINGLE_ECDH_USE;
#endif
    SSL_CTX_set_options(ctx->ssl_ctx, ctx_options);
#ifdef SSL_MODE_RELEASE_BUFFERS
    SSL_CTX_set_mode(ctx->ssl_ctx, SSL_MODE_RELEASE_BUFFERS);
#endif
    if(certificate &&
       SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, certificate) != 1)
      goto bail;
    if(key &&
       SSL_CTX_use_RSAPrivateKey_file(ctx->ssl_ctx,key,
                                      SSL_FILETYPE_PEM) != 1)
      goto bail;
    if(ca) {
      STACK_OF(X509_NAME) *cert_stack;
      if(!SSL_CTX_load_verify_locations(ctx->ssl_ctx,ca,NULL) ||
         (cert_stack = SSL_load_client_CA_file(ca)) == NULL)
        goto bail;
      SSL_CTX_set_client_CA_list(ctx->ssl_ctx, cert_stack);
    }
    SSL_CTX_set_cipher_list(ctx->ssl_ctx, ciphers ? ciphers : "DEFAULT");
    SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, verify_cb);
#ifndef OPENSSL_NO_EC
#if defined(SSL_CTX_set_ecdh_auto)
    SSL_CTX_set_ecdh_auto(ctx->ssl_ctx, 1);
#elif defined(NID_X9_62_prime256v1)
    EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    SSL_CTX_set_tmp_ecdh(ctx->ssl_ctx, ec_key);
    EC_KEY_free(ec_key);
#endif
#endif
    existing_ctx_cn = ssl_ctx_cache_set(ctx->ssl_ctx_cn);
    if(existing_ctx_cn != ctx->ssl_ctx_cn) {
      ssl_ctx_cache_node_free(ctx->ssl_ctx_cn);
      ctx->ssl_ctx_cn = existing_ctx_cn;
    }
  }
Esempio n. 20
0
/* -------------------------------------------------------------------- */
SSL_CTX* evssl_init(const echossl_t *options, int isserver) {
    /*-*/ SSL_CTX    *context = NULL;
    /*-*/ char       *crtfile = NULL;
    /*-*/ char       *keyfile = NULL;
    /*-*/ char       *dhfile  = NULL;
    /*-*/ char       *CApath  = NULL;
    const SSL_METHOD *method  = NULL;

    if (options->sname != NULL) {
        crtfile = xjoin(options->pki, "/certificates/", options->sname, ".crt", NULL);
        keyfile = xjoin(options->pki, "/certificates/", options->sname, ".key", NULL);
    }

    dhfile  = xjoin(options->pki, "/certificates/dh.pem", NULL);
    CApath  = xjoin(options->pki, "/db/ca.db.certs", NULL);

    SSL_load_error_strings();
    SSL_library_init();

    if (!RAND_poll()) {
        elog(LOG_FATAL, "cannot initialize entropy");
        goto bailout;
    }

    if (isserver) {
        switch (options->tlsver) {
        case SSL_3p0: method = SSLv3_server_method  (); break ;
        case TLS_1p0: method = TLSv1_server_method  (); break ;
        case TLS_1p1: method = TLSv1_1_server_method(); break ;
        case TLS_1p2: method = TLSv1_2_server_method(); break ;
    
        default:
            abort();
        }
    } else {
        switch (options->tlsver) {
        case SSL_3p0: method = SSLv3_client_method  (); break ;
        case TLS_1p0: method = TLSv1_client_method  (); break ;
        case TLS_1p1: method = TLSv1_1_client_method(); break ;
        case TLS_1p2: method = TLSv1_2_client_method(); break ;
    
        default:
            abort();
        }
    }

    if ((context = SSL_CTX_new(method)) == NULL) {
        elog(LOG_FATAL, "cannot create SSL context");
        goto bailout;
    }

    if (options->ciphers != NULL) {
        if (!SSL_CTX_set_cipher_list(context, options->ciphers)) {
            elog(LOG_FATAL, "cannot set ciphers list `%s'", options->ciphers);
            goto bailout;
        }
    }

    if (!SSL_CTX_use_tmp_dh_file(context, dhfile)) {
        elog(LOG_FATAL, "cannot load/set DH parameters from file `%s'", dhfile);
        goto bailout;
    }

    if (!SSL_CTX_load_verify_locations(context, NULL, CApath)) {
        elog(LOG_FATAL, "cannot load trusted hashed CA path");
        goto bailout;
    }

    (void) SSL_CTX_set_default_verify_paths(context);

    if (isserver) {
        if (options->sname != NULL) {
            if (!SSL_CTX_use_certificate_chain_file(context, crtfile)) {
                elog(LOG_FATAL, "cannot load certificate `%s'", crtfile);
                goto bailout;
            }
    
            if (!SSL_CTX_use_PrivateKey_file(context, keyfile, SSL_FILETYPE_PEM)) {
                elog(LOG_FATAL, "cannot load certificate key `%s'", keyfile);
                goto bailout;
            }
        }
    }

    (void) SSL_CTX_set_options(context, SSL_OP_NO_COMPRESSION); 

    if (options->sname != NULL) {
        free(keyfile);
        free(crtfile);
    }

    free(dhfile);
    free(CApath);

    return context;

 bailout:
    if (context != NULL)
        SSL_CTX_free(context);

    if (keyfile != NULL) free(keyfile);
    if (crtfile != NULL) free(crtfile);
    if (dhfile  != NULL) free(dhfile);
    if (CApath  != NULL) free(CApath);

    return NULL;
}
Esempio n. 21
0
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = 0;
    SOCKET_T clientfd = 0;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    char   msg[] = "I hear you fa shizzle!";
    char   input[80];
    int    idx;
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    word16 port = yasslPort;
    int    usePsk = 0;
    int    useAnon = 0;
    int    doDTLS = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    int    pkCallbacks  = 0;
    int    serverReadyFile = 0;
    char*  cipherList = NULL;
    const char* verifyCert = cliCert;
    const char* ourCert    = svrCert;
    const char* ourKey     = svrKey;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)trackMemory;
    (void)pkCallbacks;

#ifdef CYASSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    while ((ch = mygetopt(argc, argv, "?dbstnNufraPp:v:l:A:c:k:S:oO:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 't' :
            #ifdef USE_CYASSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'r' :
                serverReadyFile = 1;
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS 
                pkCallbacks = 1;
            #endif
                break;

            case 'p' :
                port = (word16)atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            case 'a' :
                #ifdef HAVE_ANON
                    useAnon = 1;
                #endif
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker(); 
#endif

    switch (version) {
#ifndef NO_OLD_TLS
        case 0:
            method = SSLv3_server_method();
            break;

    #ifndef NO_TLS
        case 1:
            method = TLSv1_server_method();
            break;


        case 2:
            method = TLSv1_1_server_method();
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = TLSv1_2_server_method();
            break;
#endif
                
#ifdef CYASSL_DTLS
        case -1:
            method = DTLSv1_server_method();
            break;

        case -2:
            method = DTLSv1_2_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    usePsk = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    usePsk = 1;
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!usePsk && !useAnon) {
        if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " CyaSSL home dir");
    }
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                               != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from CyaSSL home dir");
    }
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && !usePsk && !useAnon) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server private key file, check file and run "
                "from CyaSSL home dir");
    }
#endif

    if (usePsk) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
        SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
        if (cipherList == NULL) {
            const char *defaultCipherList;
            #ifdef HAVE_NULL_CIPHER
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

    if (useAnon) {
#ifdef HAVE_ANON
        CyaSSL_CTX_allow_anon_cipher(ctx);
        if (cipherList == NULL) {
            if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS)
                err_sys("server can't set cipher list 4");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs */
    if (doCliCertCheck && usePsk == 0 && useAnon == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    }
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                           XSTRLEN(sniHostName)) != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif

    ssl = SSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL");

#ifdef HAVE_CRL
    CyaSSL_EnableCRL(ssl, 0);
    CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
                                                     CYASSL_CRL_START_MON);
    CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
#ifdef HAVE_OCSP
    if (useOcsp) {
        if (ocspUrl != NULL) {
            CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
            CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE
                                                    | CYASSL_OCSP_URL_OVERRIDE);
        }
        else
            CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
    }
#endif
#ifdef HAVE_PK_CALLBACKS
    if (pkCallbacks)
        SetupPkCallbacks(ctx, ssl);
#endif

    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS,
               serverReadyFile);
    if (!doDTLS) 
        CloseSocket(sockfd);

    SSL_set_fd(ssl, clientfd);
    if (usePsk == 0 || useAnon == 1 || cipherList != NULL) {
        #if !defined(NO_FILESYSTEM) && !defined(NO_DH)
            CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
        #elif !defined(NO_DH)
            SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
        #endif
    }

#ifndef CYASSL_CALLBACKS
    if (nonBlocking) {
        CyaSSL_set_using_nonblock(ssl, 1);
        tcp_set_nonblocking(&clientfd);
        NonBlockingSSL_Accept(ssl);
    } else if (SSL_accept(ssl) != SSL_SUCCESS) {
        int err = SSL_get_error(ssl, 0);
        char buffer[CYASSL_MAX_ERROR_SZ];
        printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
        err_sys("SSL_accept failed");
    }
#else
    NonBlockingSSL_Accept(ssl);
#endif
    showPeer(ssl);

    idx = SSL_read(ssl, input, sizeof(input)-1);
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);

    }
    else if (idx < 0) {
        int readErr = SSL_get_error(ssl, 0);
        if (readErr != SSL_ERROR_WANT_READ)
            err_sys("SSL_read failed");
    }

    if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
        err_sys("SSL_write failed");
        
    #if defined(CYASSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
        os_dly_wait(500) ;
    #elif defined (CYASSL_TIRTOS)
        Task_yield();
    #endif

    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    
    CloseSocket(clientfd);
    ((func_args*)args)->return_code = 0;


#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    ecc_fp_free();  /* free per thread cache */
#endif

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif

#ifdef CYASSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#ifndef CYASSL_TIRTOS
    return 0;
#endif
}
Esempio n. 22
0
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = WOLFSSL_SOCKET_INVALID;
    SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    const char msg[] = "I hear you fa shizzle!";
    char   input[80];
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    word16 port = wolfSSLPort;
    int    usePsk = 0;
    int    usePskPlus = 0;
    int    useAnon = 0;
    int    doDTLS = 0;
    int    needDH = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    int    pkCallbacks  = 0;
    int    wc_shutdown     = 0;
    int    resume = 0;
    int    resumeCount = 0;
    int    loopIndefinitely = 0;
    int    echoData = 0;
    int    throughput = 0;
    int    minDhKeyBits  = DEFAULT_MIN_DHKEY_BITS;
    short  minRsaKeyBits = DEFAULT_MIN_RSAKEY_BITS;
    short  minEccKeyBits = DEFAULT_MIN_ECCKEY_BITS;
    int    doListen = 1;
    int    crlFlags = 0;
    int    ret;
    int    err = 0;
    char*  serverReadyFile = NULL;
    char*  alpnList = NULL;
    unsigned char alpn_opt = 0;
    char*  cipherList = NULL;
    const char* verifyCert = cliCert;
    const char* ourCert    = svrCert;
    const char* ourKey     = svrKey;
    const char* ourDhParam = dhParam;
    tcp_ready*  readySignal = NULL;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifdef WOLFSSL_TRUST_PEER_CERT
    const char* trustCert  = NULL;
#endif

#ifndef NO_PSK
    int sendPskIdentityHint = 1;
#endif

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)trackMemory;
    (void)pkCallbacks;
    (void)needDH;
    (void)ourKey;
    (void)ourCert;
    (void)ourDhParam;
    (void)verifyCert;
    (void)useNtruKey;
    (void)doCliCertCheck;
    (void)minDhKeyBits;
    (void)minRsaKeyBits;
    (void)minEccKeyBits;
    (void)alpnList;
    (void)alpn_opt;
    (void)crlFlags;
    (void)readySignal;

#ifdef CYASSL_TIRTOS
    fdOpenSession(Task_self());
#endif

#ifdef WOLFSSL_VXWORKS
    useAnyAddr = 1;
#else
    while ((ch = mygetopt(argc, argv, "?jdbstnNufrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:"))
                         != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 'j' :
                usePskPlus = 1;
                break;

            case 't' :
            #ifdef USE_WOLFSSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'R' :
                serverReadyFile = myoptarg;
                break;

            case 'r' :
                #ifndef NO_SESSION_CACHE
                    resume = 1;
                #endif
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS
                pkCallbacks = 1;
            #endif
                break;

            case 'p' :
                port = (word16)atoi(myoptarg);
                break;

            case 'w' :
                wc_shutdown = 1;
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'D' :
                #ifndef NO_DH
                    ourDhParam = myoptarg;
                #endif
                break;

            case 'Z' :
                #ifndef NO_DH
                    minDhKeyBits = atoi(myoptarg);
                    if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
                        Usage();
                        exit(MY_EX_USAGE);
                    }
                #endif
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            case 'a' :
                #ifdef HAVE_ANON
                    useAnon = 1;
                #endif
                break;
            case 'I':
                #ifndef NO_PSK
                    sendPskIdentityHint = 0;
                #endif
                break;

            case 'L' :
                #ifdef HAVE_ALPN
                    alpnList = myoptarg;

                    if (alpnList[0] == 'C' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
                    else if (alpnList[0] == 'F' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
                    else {
                        Usage();
                        exit(MY_EX_USAGE);
                    }

                    alpnList += 2;

                #endif
                break;

            case 'i' :
                loopIndefinitely = 1;
                break;

            case 'e' :
                echoData = 1;
                break;

            case 'B':
                throughput = atoi(myoptarg);
                if (throughput <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            #ifdef WOLFSSL_TRUST_PEER_CERT
            case 'E' :
                 trustCert = myoptarg;
                break;
            #endif

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */
#endif /* !WOLFSSL_VXWORKS */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker();
#endif

    switch (version) {
#ifndef NO_OLD_TLS
    #ifdef WOLFSSL_ALLOW_SSLV3
        case 0:
            method = SSLv3_server_method();
            break;
    #endif

    #ifndef NO_TLS
        case 1:
            method = TLSv1_server_method();
            break;


        case 2:
            method = TLSv1_1_server_method();
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = TLSv1_2_server_method();
            break;
#endif

#ifdef CYASSL_DTLS
    #ifndef NO_OLD_TLS
        case -1:
            method = DTLSv1_server_method();
            break;
    #endif

        case -2:
            method = DTLSv1_2_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
                                    defined(HAVE_POLY1305)
    if (TicketInit() != 0)
        err_sys("unable to setup Session Ticket Key context");
    wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
#endif

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    if (!usePsk) {
        usePsk = 1;
    }
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    if (!usePsk) {
        usePsk = 1;
    }
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if ((!usePsk || usePskPlus) && !useAnon) {
        if (SSL_CTX_use_certificate_chain_file(ctx, ourCert)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " wolfSSL home dir");
    }
#endif

#ifndef NO_DH
    if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits) != SSL_SUCCESS) {
        err_sys("Error setting minimum DH key size");
    }
#endif
#ifndef NO_RSA
    if (wolfSSL_CTX_SetMinRsaKey_Sz(ctx, minRsaKeyBits) != SSL_SUCCESS){
        err_sys("Error setting minimum RSA key size");
    }
#endif
#ifdef HAVE_ECC
    if (wolfSSL_CTX_SetMinEccKey_Sz(ctx, minEccKeyBits) != SSL_SUCCESS){
        err_sys("Error setting minimum ECC key size");
    }
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from wolfSSL home dir");
    }
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server private key file, check file and run "
                "from wolfSSL home dir");
    }
#endif

    if (usePsk || usePskPlus) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);

        if (sendPskIdentityHint == 1)
            SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");

        if (cipherList == NULL && !usePskPlus) {
            const char *defaultCipherList;
            #if defined(HAVE_AESGCM) && !defined(NO_DH)
                defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
                needDH = 1;
            #elif defined(HAVE_NULL_CIPHER)
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

    if (useAnon) {
#ifdef HAVE_ANON
        CyaSSL_CTX_allow_anon_cipher(ctx);
        if (cipherList == NULL) {
            if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS)
                err_sys("server can't set cipher list 4");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs
       if using PSK Plus then verify peer certs except PSK suites */
    if (doCliCertCheck && (usePsk == 0 || usePskPlus) && useAnon == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                ((usePskPlus)? SSL_VERIFY_FAIL_EXCEPT_PSK :
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT),0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        #ifdef WOLFSSL_TRUST_PEER_CERT
        if (trustCert) {
            if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert,
                                            SSL_FILETYPE_PEM)) != SSL_SUCCESS) {
                err_sys("can't load trusted peer cert file");
            }
        }
        #endif /* WOLFSSL_TRUST_PEER_CERT */
   }
#endif

#if defined(CYASSL_SNIFFER)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES128-SHA") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                           XSTRLEN(sniHostName)) != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif

#ifdef USE_WINDOWS_API
    if (port == 0) {
        /* Generate random port for testing */
        port = GetRandomPort();
    }
#endif /* USE_WINDOWS_API */

    while (1) {
        /* allow resume option */
        if(resumeCount > 1) {
            if (doDTLS == 0) {
                SOCKADDR_IN_T client;
                socklen_t client_len = sizeof(client);
                clientfd = accept(sockfd, (struct sockaddr*)&client,
                                 (ACCEPT_THIRD_T)&client_len);
            } else {
                tcp_listen(&sockfd, &port, useAnyAddr, doDTLS);
                clientfd = sockfd;
            }
            if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) {
                err_sys("tcp accept failed");
            }
        }

        ssl = SSL_new(ctx);
        if (ssl == NULL)
            err_sys("unable to get SSL");

#ifndef NO_HANDSHAKE_DONE_CB
        wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL);
#endif
#ifdef HAVE_CRL
#ifdef HAVE_CRL_MONITOR
        crlFlags = CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON;
#endif
        if (CyaSSL_EnableCRL(ssl, 0) != SSL_SUCCESS)
            err_sys("unable to enable CRL");
        if (CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, crlFlags)
                                                                 != SSL_SUCCESS)
            err_sys("unable to load CRL");
        if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
            err_sys("unable to set CRL callback url");
#endif
#ifdef HAVE_OCSP
        if (useOcsp) {
            if (ocspUrl != NULL) {
                CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
                CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE
                                                        | CYASSL_OCSP_URL_OVERRIDE);
            }
            else
                CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
        }
#endif
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
        if (wolfSSL_CTX_EnableOCSPStapling(ctx) != SSL_SUCCESS)
            err_sys("can't enable OCSP Stapling Certificate Manager");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate1-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate2-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate3-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
#endif
#ifdef HAVE_PK_CALLBACKS
        if (pkCallbacks)
            SetupPkCallbacks(ctx, ssl);
#endif

        /* do accept */
        readySignal = ((func_args*)args)->signal;
        if (readySignal) {
            readySignal->srfName = serverReadyFile;
        }
        tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr,
                       doDTLS, serverReadyFile ? 1 : 0, doListen);
        doListen = 0; /* Don't listen next time */

        if (SSL_set_fd(ssl, clientfd) != SSL_SUCCESS) {
            err_sys("error in setting fd");
        }

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            printf("ALPN accepted protocols list : %s\n", alpnList);
            wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
        }
#endif

#ifdef WOLFSSL_DTLS
        if (doDTLS) {
            SOCKADDR_IN_T cliaddr;
            byte          b[1500];
            int           n;
            socklen_t     len = sizeof(cliaddr);

            /* For DTLS, peek at the next datagram so we can get the client's
             * address and set it into the ssl object later to generate the
             * cookie. */
            n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
                              (struct sockaddr*)&cliaddr, &len);
            if (n <= 0)
                err_sys("recvfrom failed");

            wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
        }
#endif
        if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL
                                                               || needDH == 1) {
            #if !defined(NO_FILESYSTEM) && !defined(NO_DH) && !defined(NO_ASN)
                CyaSSL_SetTmpDH_file(ssl, ourDhParam, SSL_FILETYPE_PEM);
            #elif !defined(NO_DH)
                SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
            #endif
        }

#ifndef CYASSL_CALLBACKS
        if (nonBlocking) {
            CyaSSL_set_using_nonblock(ssl, 1);
            tcp_set_nonblocking(&clientfd);
        }
#endif

        do {
#ifdef WOLFSSL_ASYNC_CRYPT
            if (err == WC_PENDING_E) {
                ret = AsyncCryptPoll(ssl);
                if (ret < 0) { break; } else if (ret == 0) { continue; }
            }
#endif

            err = 0; /* Reset error */
#ifndef CYASSL_CALLBACKS
            if (nonBlocking) {
                ret = NonBlockingSSL_Accept(ssl);
            }
            else {
                ret = SSL_accept(ssl);
            }
#else
            ret = NonBlockingSSL_Accept(ssl);
#endif
            if (ret != SSL_SUCCESS) {
                err = SSL_get_error(ssl, 0);
            }
        } while (ret != SSL_SUCCESS && err == WC_PENDING_E);

        if (ret != SSL_SUCCESS) {
            char buffer[CYASSL_MAX_ERROR_SZ];
            err = SSL_get_error(ssl, 0);
            printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
            err_sys("SSL_accept failed");
        }

        showPeer(ssl);

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            char *protocol_name = NULL, *list = NULL;
            word16 protocol_nameSz = 0, listSz = 0;

            err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
            if (err == SSL_SUCCESS)
                printf("Sent ALPN protocol : %s (%d)\n",
                       protocol_name, protocol_nameSz);
            else if (err == SSL_ALPN_NOT_FOUND)
                printf("No ALPN response sent (no match)\n");
            else
                printf("Getting ALPN protocol name failed\n");

            err = wolfSSL_ALPN_GetPeerProtocol(ssl, &list, &listSz);
            if (err == SSL_SUCCESS)
                printf("List of protocol names sent by Client: %s (%d)\n",
                       list, listSz);
            else
                printf("Get list of client's protocol name failed\n");

            free(list);
        }
#endif
        if(echoData == 0 && throughput == 0) {
            ret = SSL_read(ssl, input, sizeof(input)-1);
            if (ret > 0) {
                input[ret] = 0;
                printf("Client message: %s\n", input);

            }
            else if (ret < 0) {
                int readErr = SSL_get_error(ssl, 0);
                if (readErr != SSL_ERROR_WANT_READ)
                    err_sys("SSL_read failed");
            }

            if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
                err_sys("SSL_write failed");
        }
        else {
            ServerEchoData(ssl, clientfd, echoData, throughput);
        }

#if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
        os_dly_wait(500) ;
#elif defined (CYASSL_TIRTOS)
        Task_yield();
#endif

        if (doDTLS == 0) {
            ret = SSL_shutdown(ssl);
            if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
                SSL_shutdown(ssl);    /* bidirectional shutdown */
        }
        SSL_free(ssl);

        CloseSocket(clientfd);

        if (resume == 1 && resumeCount == 0) {
            resumeCount++;           /* only do one resume for testing */
            continue;
        }
        resumeCount = 0;

        if(!loopIndefinitely) {
            break;  /* out of while loop, done with normal and resume option */
        }
    } /* while(1) */

    CloseSocket(sockfd);
    SSL_CTX_free(ctx);

    ((func_args*)args)->return_code = 0;


#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    ecc_fp_free();  /* free per thread cache */
#endif

#ifdef USE_WOLFSSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif

#ifdef CYASSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
                                    defined(HAVE_POLY1305)
    TicketCleanup();
#endif

    /* There are use cases  when these assignments are not read. To avoid
     * potential confusion those warnings have been handled here.
     */
    (void) ourKey;
    (void) verifyCert;
    (void) doCliCertCheck;
    (void) useNtruKey;
    (void) ourDhParam;
    (void) ourCert;
#ifndef CYASSL_TIRTOS
    return 0;
#endif
}
Esempio n. 23
0
int anetSSLAccept( char *err, int fd, struct redisServer server, anetSSLConnection *ctn) {

  ctn->sd = -1;
  ctn->ctx = NULL;
  ctn->ssl = NULL;
  ctn->bio = NULL;
  ctn->conn_str = NULL;

  if( fd == -1 ) {
    return ANET_ERR;
  }
  ctn->sd = fd;

  // Create the SSL Context ( server method )
  SSL_CTX* ctx = SSL_CTX_new(TLSv1_1_server_method());
  ctn->ctx = ctx;

   /*
     You will need to generate certificates, the root certificate authority file, the private key file, and the random file yourself.
     Google will help. The openssl executable created when you compiled OpenSSL can do all this.
   */

    // Load trusted root authorities
    SSL_CTX_load_verify_locations(ctx, server.ssl_root_file, server.ssl_root_dir);

    // Sets the default certificate password callback function. Read more under the Certificate Verification section.
    if( NULL != server.ssl_srvr_cert_passwd ) {
      global_ssl_cert_password = server.ssl_srvr_cert_passwd;
      SSL_CTX_set_default_passwd_cb(ctx, password_callback);
    }

    // Sets the certificate file to be used.
    SSL_CTX_use_certificate_file(ctx, server.ssl_cert_file, SSL_FILETYPE_PEM);

    // Sets the private key file to be used.
    SSL_CTX_use_PrivateKey_file(ctx, server.ssl_pk_file, SSL_FILETYPE_PEM);

    // Set the maximum depth to be used verifying certificates
    // Due to a bug, this is not enforced. The verify callback must enforce it.
    SSL_CTX_set_verify_depth(ctx, 1);

    // Set the certificate verification callback.
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER /* | SSL_VERIFY_FAIL_IF_NO_PEER_CERT */, verify_callback);

    /*
      End certificate verification setup.
    */

    // We need to load the Diffie-Hellman key exchange parameters.
    // First load dh1024.pem (you DID create it, didn't you?)
    BIO* bio = BIO_new_file(server.ssl_dhk_file, "r");

    // Did we get a handle to the file?
    if (bio == NULL) {
      anetSetError(err, "SSL Accept: Couldn't open DH param file");
      anetCleanupSSL( ctn);
      return ANET_ERR;
    }

    // Read in the DH params.
    DH* ret = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);

    // Free up the BIO object.
    BIO_free(bio);

    // Set up our SSL_CTX to use the DH parameters.
    if (SSL_CTX_set_tmp_dh(ctx, ret) < 0) {
      anetSetError(err, "SSL Accept: Couldn't set DH parameters");
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    // Now we need to generate a RSA key for use.
    // 1024-bit key. If you want to use something stronger, go ahead but it must be a power of 2. Upper limit should be 4096.
    RSA* rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);

    // Set up our SSL_CTX to use the generated RSA key.
    if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
      anetSetError(err, "SSL Accept: Couldn't set RSA Key");
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    // Free up the RSA structure.
    RSA_free(rsa);

    /*
      For some reason many tutorials don't include this...

      Servers must specify the ciphers they can use, to verify that both the client and the server can use the same cipher.
      If you don't do this, you'll get errors relating to "no shared ciphers" or "no common ciphers".

      Use all ciphers with the exception of: ones with anonymous Diffie-Hellman, low-strength ciphers, export ciphers, md5 hashing. Ordered from strongest to weakest.
      Note that as ciphers become broken, it will be necessary to change the available cipher list to remain secure.
    */

    if( NULL == server.ssl_srvr_cipher_list || 0 == strlen(server.ssl_srvr_cipher_list) )
        SSL_CTX_set_cipher_list(ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
    else
    	SSL_CTX_set_cipher_list(ctx, server.ssl_srvr_cipher_list);

    // Set up our SSL object as before
    SSL* ssl = SSL_new(ctx);
    ctn->ssl = ssl;
    
    // Set up our BIO object to use the client socket
    BIO* sslclient = BIO_new_socket(fd, BIO_NOCLOSE);
    ctn->bio = sslclient;

    // Set up our SSL object to use the BIO.
    SSL_set_bio(ssl, sslclient, sslclient);

    // Do SSL handshaking.
    int r = SSL_accept(ssl);

    // Something failed. Print out all the error information, since all of it may be relevant to the problem.
    if (r != 1) {
      char error[65535];

      ERR_error_string_n(ERR_get_error(), error, 65535);

      anetSetError(err, "SSL Accept: Error %d - %s ", SSL_get_error(ssl, r), error );

      // We failed to accept this client connection.
      // Ideally here you'll drop the connection and continue on.
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    /* Verify certificate */
    if (SSL_get_verify_result(ssl) != X509_V_OK) {
      anetSetError(err, "SSL Accept: Certificate failed verification!");
      // Ideally here you'll close this connection and continue on.
      anetCleanupSSL( ctn );
      return ANET_ERR;
    }

    return ANET_OK;
}
Esempio n. 24
0
/* caller == ssl client, !client == ssl server */
int ssl_init(int caller, int fd, int iscontrol)
{
  const SSL_METHOD *method;
  int ret;
  SSL_CTX **curctx;
  SSL **curssl;
  if (!_use_ssl)
    return 0;

  SSL_library_init ();
  SSL_load_error_strings ();

  if (iscontrol) {
    curctx = &control_ctx;
    curssl = &control_ssl;
  }
  else {
    curctx = &ctx;
    curssl = &ssl;
  }
#if 0
  if (caller)
    //    method = SSLv23_client_method();
    method = TLSv1_1_client_method();
  else
    //method = SSLv23_method();
    method = TLSv1_1_server_method();
#endif
  method = SSLv23_method();
  *curctx = SSL_CTX_new (method);

  if (*curctx == NULL) {
    ERR_print_errors_fp(stderr);
    return -1;
  }

  /* Load cert */
  if(!(SSL_CTX_use_certificate_file(*curctx, certfile, SSL_FILETYPE_PEM))) {
    ERR_print_errors_fp(stderr);
    return -1;
  }

  /* Load private key */
  if(!(SSL_CTX_use_PrivateKey_file(*curctx, keyfile, SSL_FILETYPE_PEM))) {
    ERR_print_errors_fp(stderr);
    return -1;
  }
  
  /* Load the CAs we trust*/
  if(!(SSL_CTX_load_verify_locations(*curctx, cafile, 0))) {
    ERR_print_errors_fp(stderr);
    return -1;
  }

  /* if in server role request peer's cert */
  //if (!caller)
  SSL_CTX_set_verify(*curctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT|SSL_VERIFY_CLIENT_ONCE, 0);
  
  SSL_CTX_set_verify_depth(*curctx, 1);

  STACK_OF(X509_NAME) *cert_names;

  cert_names = SSL_load_client_CA_file(cafile);
  if (cert_names != NULL) {
    printf("loaded client ca list\n");
    SSL_CTX_set_client_CA_list(*curctx, cert_names);
  } else
    printf("not loaded client ca list\n");
  SSL_CTX_set_mode(*curctx, SSL_MODE_AUTO_RETRY);
  *curssl = SSL_new(*curctx);
  if (*curssl == NULL) {
      ERR_print_errors_fp(stderr);
      return -1;
  }

  if (!SSL_set_fd (*curssl, fd)) {
    ERR_print_errors_fp(stderr);
    return -1;
  }

  if (caller) {
    if (SSL_connect (*curssl) != 1) {
      ERR_print_errors_fp(stderr);
      printf("ssl error %d\n", SSL_get_error(*curssl, ret));
      return -1;
    }
  } else {
    if((ret = SSL_accept(*curssl)) <=0 ) {
      ERR_print_errors_fp(stderr);
      printf("ssl error %d\n", SSL_get_error(*curssl, ret));
      return -1;
    }        
  }

  return check_cert(*curssl);
    
}