示例#1
0
文件: tls.c 项目: jedisct1/pure-ftpd
static int tls_init_ecdh_curve(void)
{
#ifdef SSL_CTRL_SET_ECDH_AUTO
    SSL_CTX_ctrl(tls_ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL);
    return 0;
#else
# ifndef SSL_OP_SINGLE_ECDH_USE
    errno = ENOTSUP;
    return -1;
# else
    const char *curve_name;
    EC_KEY     *curve;
    int         nid;

    curve_name = TLS_DEFAULT_ECDH_CURVE;
    if ((nid = OBJ_sn2nid(curve_name)) == NID_undef) {
        logfile(LOG_INFO, "Curve [%s] not supported", curve_name);
        errno = ENOTSUP;
        return -1;
    }
    if ((curve = EC_KEY_new_by_curve_name(nid)) == NULL) {
        logfile(LOG_INFO, "Curve [%s] is not usable", curve_name);
        errno = ENOTSUP;
        return -1;
    }
    SSL_CTX_set_options(tls_ctx, SSL_OP_SINGLE_ECDH_USE);
    SSL_CTX_set_tmp_ecdh(tls_ctx, curve);
    EC_KEY_free(curve);

    return 0;
# endif
#endif
}
示例#2
0
文件: tls.c 项目: jedisct1/pure-ftpd
static void tls_init_dhparams(void)
{
# ifdef SSL_CTRL_SET_DH_AUTO
    SSL_CTX_ctrl(tls_ctx, SSL_CTRL_SET_DH_AUTO, 1, NULL);
# else
    tls_load_dhparams_default();
# endif
}
示例#3
0
int initSSL(void) {

        long ctx_options;

        /* if(ssl) SSL_free(ssl);
        if(ctx) SSL_CTX_free(ctx);
        */

        if(init_hepsocket_blocking()) {
                LERR("capture: couldn't init hep socket\r\n");
                return 1;
        }

        ctx = initCTX();

        /* workaround bug openssl */
        ctx_options = SSL_OP_ALL;   
        ctx_options |= SSL_OP_NO_SSLv2;
        ctx_options |= SSL_OP_NO_SSLv3;
        SSL_CTX_set_options(ctx, ctx_options);
                
        /*extra*/
        SSL_CTX_ctrl(ctx, BIO_C_SET_NBIO, 1, NULL);

        /* create new SSL connection state */
        ssl = SSL_new(ctx);

        SSL_set_connect_state(ssl);

        /* attach socket */
        SSL_set_fd(ssl, sock);    /* attach the socket descriptor */
                
        /* perform the connection */
        if ( SSL_connect(ssl) == -1 )  {
              ERR_print_errors_fp(stderr);
              return 1;
        }                 
                          
        showCerts(ssl);   

        return 0;
}
示例#4
0
int initSSL(unsigned int idx) {

        long ctx_options;

        /* if(ssl) SSL_free(ssl);
        if(ctx) SSL_CTX_free(ctx);
        */

        if(init_jsonsocket_blocking(idx)) {
                LERR("capture: couldn't init hep socket");
                return 1;
        }

        profile_transport[idx].ctx = initCTX();

        /* workaround bug openssl */
        ctx_options = SSL_OP_ALL;
        ctx_options |= SSL_OP_NO_SSLv2;
        SSL_CTX_set_options(profile_transport[idx].ctx, ctx_options);

        /*extra*/
        SSL_CTX_ctrl(profile_transport[idx].ctx, BIO_C_SET_NBIO, 1, NULL);

        /* create new SSL connection state */
        profile_transport[idx].ssl = SSL_new(profile_transport[idx].ctx);

        SSL_set_connect_state(profile_transport[idx].ssl);

        /* attach socket */
        SSL_set_fd(profile_transport[idx].ssl, profile_transport[index].socket);    /* attach the socket descriptor */

        /* perform the connection */
        if ( SSL_connect(profile_transport[idx].ssl) == -1 )  {
              ERR_print_errors_fp(stderr);
              return 1;
        }

        showCerts(profile_transport[idx].ssl);

        return 0;
}
示例#5
0
/* ====================================================== */
CURLcode
Curl_SSLConnect(struct connectdata *conn,
                int sockindex)
{
  CURLcode retcode = CURLE_OK;

#ifdef USE_SSLEAY
  struct SessionHandle *data = conn->data;
  int err;
  long lerr;
  int what;
  char * str;
  SSL_METHOD *req_method;
  SSL_SESSION *ssl_sessionid=NULL;
  ASN1_TIME *certdate;
  curl_socket_t sockfd = conn->sock[sockindex];
  struct ssl_connect_data *connssl = &conn->ssl[sockindex];

  /* mark this is being ssl enabled from here on out. */
  connssl->use = TRUE;

  if(!ssl_seeded || data->set.ssl.random_file || data->set.ssl.egdsocket) {
    /* Make funny stuff to get random input */
    random_the_seed(data);

    ssl_seeded = TRUE;
  }

  /* check to see if we've been told to use an explicit SSL/TLS version */
  switch(data->set.ssl.version) {
  default:
  case CURL_SSLVERSION_DEFAULT:
    /* we try to figure out version */
    req_method = SSLv23_client_method();
    break;
  case CURL_SSLVERSION_TLSv1:
    req_method = TLSv1_client_method();
    break;
  case CURL_SSLVERSION_SSLv2:
    req_method = SSLv2_client_method();
    break;
  case CURL_SSLVERSION_SSLv3:
    req_method = SSLv3_client_method();
    break;
  }

  connssl->ctx = SSL_CTX_new(req_method);

  if(!connssl->ctx) {
    failf(data, "SSL: couldn't create a context!");
    return CURLE_OUT_OF_MEMORY;
  }

#ifdef SSL_CTRL_SET_MSG_CALLBACK
  if (data->set.fdebug) {
    SSL_CTX_callback_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK,
                          ssl_tls_trace);
    SSL_CTX_ctrl(connssl->ctx, SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, conn);
  }
#endif

  /* OpenSSL contains code to work-around lots of bugs and flaws in various
     SSL-implementations. SSL_CTX_set_options() is used to enabled those
     work-arounds. The man page for this option states that SSL_OP_ALL enables
     ll the work-arounds and that "It is usually safe to use SSL_OP_ALL to
     enable the bug workaround options if compatibility with somewhat broken
     implementations is desired."

  */
  SSL_CTX_set_options(connssl->ctx, SSL_OP_ALL);

#if 0
  /*
   * Not sure it's needed to tell SSL_connect() that socket is
   * non-blocking. It doesn't seem to care, but just return with
   * SSL_ERROR_WANT_x.
   */
  if (data->state.used_interface == Curl_if_multi)
    SSL_CTX_ctrl(connssl->ctx, BIO_C_SET_NBIO, 1, NULL);
#endif

  if(data->set.cert) {
    if(!cert_stuff(conn,
                   connssl->ctx,
                   data->set.cert,
                   data->set.cert_type,
                   data->set.key,
                   data->set.key_type)) {
      /* failf() is already done in cert_stuff() */
      return CURLE_SSL_CERTPROBLEM;
    }
  }

  if(data->set.ssl.cipher_list) {
    if(!SSL_CTX_set_cipher_list(connssl->ctx,
                                data->set.ssl.cipher_list)) {
      failf(data, "failed setting cipher list");
      return CURLE_SSL_CIPHER;
    }
  }

  if (data->set.ssl.CAfile || data->set.ssl.CApath) {
    /* tell SSL where to find CA certificates that are used to verify
       the servers certificate. */
    if (!SSL_CTX_load_verify_locations(connssl->ctx, data->set.ssl.CAfile,
                                       data->set.ssl.CApath)) {
      if (data->set.ssl.verifypeer) {
        /* Fail if we insist on successfully verifying the server. */
        failf(data,"error setting certificate verify locations:\n"
              "  CAfile: %s\n  CApath: %s\n",
              data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
              data->set.ssl.CApath ? data->set.ssl.CApath : "none");
        return CURLE_SSL_CACERT;
      }
      else {
        /* Just continue with a warning if no strict  certificate verification
           is required. */
        infof(data, "error setting certificate verify locations,"
              " continuing anyway:\n");
      }
    }
    else {
      /* Everything is fine. */
      infof(data, "successfully set certificate verify locations:\n");
    }
    infof(data,
          "  CAfile: %s\n"
          "  CApath: %s\n",
          data->set.ssl.CAfile ? data->set.ssl.CAfile : "none",
          data->set.ssl.CApath ? data->set.ssl.CApath : "none");
  }
  /* SSL always tries to verify the peer, this only says whether it should
   * fail to connect if the verification fails, or if it should continue
   * anyway. In the latter case the result of the verification is checked with
   * SSL_get_verify_result() below. */
  SSL_CTX_set_verify(connssl->ctx,
                     data->set.ssl.verifypeer?SSL_VERIFY_PEER:SSL_VERIFY_NONE,
                     cert_verify_callback);

  /* give application a chance to interfere with SSL set up. */
  if(data->set.ssl.fsslctx) {
    retcode = (*data->set.ssl.fsslctx)(data, connssl->ctx,
                                       data->set.ssl.fsslctxp);
    if(retcode) {
      failf(data,"error signaled by ssl ctx callback");
      return retcode;
    }
  }

  /* Lets make an SSL structure */
  connssl->handle = SSL_new(connssl->ctx);
  SSL_set_connect_state(connssl->handle);

  connssl->server_cert = 0x0;

  if(!conn->bits.reuse) {
    /* We're not re-using a connection, check if there's a cached ID we
       can/should use here! */
    if(!Get_SSL_Session(conn, &ssl_sessionid)) {
      /* we got a session id, use it! */
      SSL_set_session(connssl->handle, ssl_sessionid);
      /* Informational message */
      infof (data, "SSL re-using session ID\n");
    }
  }

  /* pass the raw socket into the SSL layers */
  SSL_set_fd(connssl->handle, sockfd);

  while(1) {
    fd_set writefd;
    fd_set readfd;
    struct timeval interval;
    long timeout_ms;

    /* Find out if any timeout is set. If not, use 300 seconds.
       Otherwise, figure out the most strict timeout of the two possible one
       and then how much time that has elapsed to know how much time we
       allow for the connect call */
    if(data->set.timeout || data->set.connecttimeout) {
      long has_passed;

      /* Evaluate in milliseconds how much time that has passed */
      has_passed = Curl_tvdiff(Curl_tvnow(), data->progress.start);

      /* get the most strict timeout of the ones converted to milliseconds */
      if(data->set.timeout &&
         (data->set.timeout>data->set.connecttimeout))
        timeout_ms = data->set.timeout*1000;
      else
        timeout_ms = data->set.connecttimeout*1000;

      /* subtract the passed time */
      timeout_ms -= has_passed;

      if(timeout_ms < 0) {
        /* a precaution, no need to continue if time already is up */
        failf(data, "SSL connection timeout");
        return CURLE_OPERATION_TIMEOUTED;
      }
    }
    else
      /* no particular time-out has been set */
      timeout_ms= DEFAULT_CONNECT_TIMEOUT;


    FD_ZERO(&writefd);
    FD_ZERO(&readfd);

    err = SSL_connect(connssl->handle);

    /* 1  is fine
       0  is "not successful but was shut down controlled"
       <0 is "handshake was not successful, because a fatal error occurred" */
    if(1 != err) {
      int detail = SSL_get_error(connssl->handle, err);

      if(SSL_ERROR_WANT_READ == detail)
        FD_SET(sockfd, &readfd);
      else if(SSL_ERROR_WANT_WRITE == detail)
        FD_SET(sockfd, &writefd);
      else {
        /* untreated error */
        unsigned long errdetail;
        char error_buffer[120]; /* OpenSSL documents that this must be at least
                                   120 bytes long. */
        CURLcode rc;
        const char *cert_problem = NULL;

        errdetail = ERR_get_error(); /* Gets the earliest error code from the
                                        thread's error queue and removes the
                                        entry. */

        switch(errdetail) {
        case 0x1407E086:
          /* 1407E086:
             SSL routines:
             SSL2_SET_CERTIFICATE:
             certificate verify failed */
          /* fall-through */
        case 0x14090086:
          /* 14090086:
             SSL routines:
             SSL3_GET_SERVER_CERTIFICATE:
             certificate verify failed */
          cert_problem = "SSL certificate problem, verify that the CA cert is"
                         " OK. Details:\n";
          rc = CURLE_SSL_CACERT;
          break;
        default:
          rc = CURLE_SSL_CONNECT_ERROR;
          break;
        }

          /* detail is already set to the SSL error above */

        /* If we e.g. use SSLv2 request-method and the server doesn't like us
         * (RST connection etc.), OpenSSL gives no explanation whatsoever and
         * the SO_ERROR is also lost.
         */
        if (CURLE_SSL_CONNECT_ERROR == rc && errdetail == 0) {
          failf(data, "Unknown SSL protocol error in connection to %s:%d ",
                conn->host.name, conn->port);
          return rc;
        }
        /* Could be a CERT problem */

#ifdef HAVE_ERR_ERROR_STRING_N
          /* OpenSSL 0.9.6 and later has a function named
             ERRO_error_string_n() that takes the size of the buffer as a
             third argument */
          ERR_error_string_n(errdetail, error_buffer, sizeof(error_buffer));
#else
          ERR_error_string(errdetail, error_buffer);
#endif
        failf(data, "%s%s", cert_problem ? cert_problem : "", error_buffer);
        return rc;
      }
    }
    else
      /* we have been connected fine, get out of the connect loop */
      break;

    interval.tv_sec = (int)(timeout_ms/1000);
    timeout_ms -= interval.tv_sec*1000;

    interval.tv_usec = timeout_ms*1000;

    while(1) {
      what = select(sockfd+1, &readfd, &writefd, NULL, &interval);
      if(what > 0)
        /* reabable or writable, go loop in the outer loop */
        break;
      else if(0 == what) {
        /* timeout */
        failf(data, "SSL connection timeout");
        return CURLE_OPERATION_TIMEDOUT;
      }
      else {
#if !defined(WIN32) && defined(EINTR)
        /* For platforms without EINTR all errnos are bad */
        if (errno == EINTR)
          continue; /* retry the select() */
#endif
        /* anything other than the unimportant EINTR is fatally bad */
        failf(data, "select on SSL socket, errno: %d", Curl_ourerrno());
        return CURLE_SSL_CONNECT_ERROR;
      }
    } /* while()-loop for the select() */
  } /* while()-loop for the SSL_connect() */

  /* Informational message */
  infof (data, "SSL connection using %s\n",
         SSL_get_cipher(connssl->handle));

  if(!ssl_sessionid) {
    /* Since this is not a cached session ID, then we want to stach this one
       in the cache! */
    Store_SSL_Session(conn, connssl);
  }


  /* Get server's certificate (note: beware of dynamic allocation) - opt */
  /* major serious hack alert -- we should check certificates
   * to authenticate the server; otherwise we risk man-in-the-middle
   * attack
   */

  connssl->server_cert = SSL_get_peer_certificate(connssl->handle);
  if(!connssl->server_cert) {
    failf(data, "SSL: couldn't get peer certificate!");
    return CURLE_SSL_PEER_CERTIFICATE;
  }
  infof (data, "Server certificate:\n");

  str = X509_NAME_oneline(X509_get_subject_name(connssl->server_cert),
                          NULL, 0);
  if(!str) {
    failf(data, "SSL: couldn't get X509-subject!");
    X509_free(connssl->server_cert);
    return CURLE_SSL_CONNECT_ERROR;
  }
  infof(data, "\t subject: %s\n", str);
  CRYPTO_free(str);

  certdate = X509_get_notBefore(connssl->server_cert);
  Curl_ASN1_UTCTIME_output(conn, "\t start date: ", certdate);

  certdate = X509_get_notAfter(connssl->server_cert);
  Curl_ASN1_UTCTIME_output(conn, "\t expire date: ", certdate);

  if(data->set.ssl.verifyhost) {
    retcode = verifyhost(conn, connssl->server_cert);
    if(retcode) {
      X509_free(connssl->server_cert);
      return retcode;
    }
  }

  str = X509_NAME_oneline(X509_get_issuer_name(connssl->server_cert),
                          NULL, 0);
  if(!str) {
    failf(data, "SSL: couldn't get X509-issuer name!");
    retcode = CURLE_SSL_CONNECT_ERROR;
  }
  else {
    infof(data, "\t issuer: %s\n", str);
    CRYPTO_free(str);

    /* We could do all sorts of certificate verification stuff here before
       deallocating the certificate. */

    lerr = data->set.ssl.certverifyresult=
      SSL_get_verify_result(connssl->handle);
    if(data->set.ssl.certverifyresult != X509_V_OK) {
      if(data->set.ssl.verifypeer) {
        /* We probably never reach this, because SSL_connect() will fail
           and we return earlyer if verifypeer is set? */
        failf(data, "SSL certificate verify result: %s (%ld)",
              X509_verify_cert_error_string(lerr), lerr);
        retcode = CURLE_SSL_PEER_CERTIFICATE;
      }
      else
        infof(data, "SSL certificate verify result: %s (%ld),"
              " continuing anyway.\n",
              X509_verify_cert_error_string(err), lerr);
    }
    else
      infof(data, "SSL certificate verify ok.\n");
  }

  X509_free(connssl->server_cert);
#else /* USE_SSLEAY */
  (void)conn;
  (void)sockindex;
#endif
  return retcode;
}
示例#6
0
static int __ssl_setup(struct ast_tls_config *cfg, int client)
{
#ifndef DO_SSL
	cfg->enabled = 0;
	return 0;
#else
	int disable_ssl = 0;
 
	if (!cfg->enabled) {
		return 0;
	}

	/* Get rid of an old SSL_CTX since we're about to
	 * allocate a new one
	 */
	if (cfg->ssl_ctx) {
		SSL_CTX_free(cfg->ssl_ctx);
		cfg->ssl_ctx = NULL;
	}

	if (client) {
#ifndef OPENSSL_NO_SSL2
		if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) {
			ast_log(LOG_WARNING, "Usage of SSLv2 is discouraged due to known vulnerabilities. Please use 'tlsv1' or leave the TLS method unspecified!\n");
			cfg->ssl_ctx = SSL_CTX_new(SSLv2_client_method());
		} else
#endif
#ifndef OPENSSL_NO_SSL3_METHOD
		if (ast_test_flag(&cfg->flags, AST_SSL_SSLV3_CLIENT)) {
			ast_log(LOG_WARNING, "Usage of SSLv3 is discouraged due to known vulnerabilities. Please use 'tlsv1' or leave the TLS method unspecified!\n");
			cfg->ssl_ctx = SSL_CTX_new(SSLv3_client_method());
		} else
#endif
		if (ast_test_flag(&cfg->flags, AST_SSL_TLSV1_CLIENT)) {
			cfg->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
		} else {
			disable_ssl = 1;
			cfg->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
		}
	} else {
		disable_ssl = 1;
		cfg->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
	}

	if (!cfg->ssl_ctx) {
		ast_debug(1, "Sorry, SSL_CTX_new call returned null...\n");
		cfg->enabled = 0;
		return 0;
	}

	/* Due to the POODLE vulnerability, completely disable
	 * SSLv2 and SSLv3 if we are not explicitly told to use
	 * them. SSLv23_*_method supports TLSv1+.
	 */
	if (disable_ssl) {
		long ssl_opts;

		ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
		SSL_CTX_set_options(cfg->ssl_ctx, ssl_opts);
	}

	SSL_CTX_set_verify(cfg->ssl_ctx,
		ast_test_flag(&cfg->flags, AST_SSL_VERIFY_CLIENT) ? SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT : SSL_VERIFY_NONE,
		NULL);

	if (!ast_strlen_zero(cfg->certfile)) {
		char *tmpprivate = ast_strlen_zero(cfg->pvtfile) ? cfg->certfile : cfg->pvtfile;
		if (SSL_CTX_use_certificate_chain_file(cfg->ssl_ctx, cfg->certfile) == 0) {
			if (!client) {
				/* Clients don't need a certificate, but if its setup we can use it */
				ast_log(LOG_ERROR, "TLS/SSL error loading cert file. <%s>\n", cfg->certfile);
				cfg->enabled = 0;
				SSL_CTX_free(cfg->ssl_ctx);
				cfg->ssl_ctx = NULL;
				return 0;
			}
		}
		if ((SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, tmpprivate, SSL_FILETYPE_PEM) == 0) || (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 )) {
			if (!client) {
				/* Clients don't need a private key, but if its setup we can use it */
				ast_log(LOG_ERROR, "TLS/SSL error loading private key file. <%s>\n", tmpprivate);
				cfg->enabled = 0;
				SSL_CTX_free(cfg->ssl_ctx);
				cfg->ssl_ctx = NULL;
				return 0;
			}
		}
	}
	if (!ast_strlen_zero(cfg->cipher)) {
		if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {
			if (!client) {
				ast_log(LOG_ERROR, "TLS/SSL cipher error <%s>\n", cfg->cipher);
				cfg->enabled = 0;
				SSL_CTX_free(cfg->ssl_ctx);
				cfg->ssl_ctx = NULL;
				return 0;
			}
		}
	}
	if (!ast_strlen_zero(cfg->cafile) || !ast_strlen_zero(cfg->capath)) {
		if (SSL_CTX_load_verify_locations(cfg->ssl_ctx, S_OR(cfg->cafile, NULL), S_OR(cfg->capath,NULL)) == 0) {
			ast_log(LOG_ERROR, "TLS/SSL CA file(%s)/path(%s) error\n", cfg->cafile, cfg->capath);
		}
	}

#ifdef HAVE_OPENSSL_EC

	if (!ast_strlen_zero(cfg->pvtfile)) {
		BIO *bio = BIO_new_file(cfg->pvtfile, "r");
		if (bio != NULL) {
			DH *dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
			if (dh != NULL) {
				if (SSL_CTX_set_tmp_dh(cfg->ssl_ctx, dh)) {
					long options = SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_SINGLE_DH_USE | SSL_OP_SINGLE_ECDH_USE;
					options = SSL_CTX_set_options(cfg->ssl_ctx, options);
					ast_verb(2, "TLS/SSL DH initialized, PFS cipher-suites enabled\n");
				}
				DH_free(dh);
			}
			BIO_free(bio);
		}
	}
	#ifndef SSL_CTRL_SET_ECDH_AUTO
		#define SSL_CTRL_SET_ECDH_AUTO 94
	#endif
	/* SSL_CTX_set_ecdh_auto(cfg->ssl_ctx, on); requires OpenSSL 1.0.2 which wraps: */
	if (SSL_CTX_ctrl(cfg->ssl_ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL)) {
		ast_verb(2, "TLS/SSL ECDH initialized (automatic), faster PFS ciphers enabled\n");
	} else {
		/* enables AES-128 ciphers, to get AES-256 use NID_secp384r1 */
		EC_KEY *ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
		if (ecdh != NULL) {
			if (SSL_CTX_set_tmp_ecdh(cfg->ssl_ctx, ecdh)) {
				ast_verb(2, "TLS/SSL ECDH initialized (secp256r1), faster PFS cipher-suites enabled\n");
			}
			EC_KEY_free(ecdh);
		}
	}

#endif /* #ifdef HAVE_OPENSSL_EC */

	ast_verb(2, "TLS/SSL certificate ok\n");	/* We should log which one that is ok. This message doesn't really make sense in production use */
	return 1;
#endif
}
示例#7
0
static int _tnet_transport_ssl_init(tnet_transport_t* transport)
{
    if (!transport){
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }
#if HAVE_OPENSSL
    {
        tnet_socket_type_t type = tnet_transport_get_type(transport);
        tsk_bool_t is_tls = (TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type));
        tsk_bool_t is_dtls = transport->dtls.enabled/* TNET_SOCKET_TYPE_IS_DTLS(type)*/; // DTLS-RTP, not raw DTLS
        if (is_dtls && !tnet_dtls_is_supported()){
            TSK_DEBUG_ERROR("Requesting to create DTLS transport but source code not built with support for this feature");
            return -1;
        }
        if (is_tls && !tnet_tls_is_supported()){
            TSK_DEBUG_ERROR("Requesting to create TLS transport but source code not built with support for this feature");
            return -1;
        }
        if ((transport->tls.enabled = is_tls)){
            if (!transport->tls.ctx_client && !(transport->tls.ctx_client = SSL_CTX_new(SSLv23_client_method()))){
                TSK_DEBUG_ERROR("Failed to create SSL client context");
                return -2;
            }
            if (!transport->tls.ctx_server && !(transport->tls.ctx_server = SSL_CTX_new(SSLv23_server_method()))){
                TSK_DEBUG_ERROR("Failed to create SSL server context");
                return -3;
            }
            SSL_CTX_set_mode(transport->tls.ctx_client, SSL_MODE_AUTO_RETRY);
            SSL_CTX_set_mode(transport->tls.ctx_server, SSL_MODE_AUTO_RETRY);
            SSL_CTX_set_verify(transport->tls.ctx_server, SSL_VERIFY_NONE, tsk_null); // to be updated by tnet_transport_tls_set_certs()
            SSL_CTX_set_verify(transport->tls.ctx_client, SSL_VERIFY_NONE, tsk_null); // to be updated by tnet_transport_tls_set_certs()
            if (SSL_CTX_set_cipher_list(transport->tls.ctx_client, TNET_CIPHER_LIST) <= 0 || SSL_CTX_set_cipher_list(transport->tls.ctx_server, TNET_CIPHER_LIST) <= 0){
                TSK_DEBUG_ERROR("SSL_CTX_set_cipher_list failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
                return -4;
            }
        }
#if HAVE_OPENSSL_DTLS
		if ((transport->dtls.enabled = is_dtls)){
			if (!transport->dtls.ctx && !(transport->dtls.ctx = SSL_CTX_new(DTLSv1_method()))){
				TSK_DEBUG_ERROR("Failed to create DTLSv1 context");
				TSK_OBJECT_SAFE_FREE(transport);
				return -5;
			}
			SSL_CTX_set_read_ahead(transport->dtls.ctx, 1);
			// SSL_CTX_set_options(transport->dtls.ctx, SSL_OP_ALL);
			// SSL_CTX_set_mode(transport->dtls.ctx, SSL_MODE_AUTO_RETRY);
			SSL_CTX_set_verify(transport->dtls.ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, tsk_null); // to be updated by tnet_transport_tls_set_certs()
			if (SSL_CTX_set_cipher_list(transport->dtls.ctx, TNET_CIPHER_LIST) <= 0){
				TSK_DEBUG_ERROR("SSL_CTX_set_cipher_list failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
				return -6;
			}
			//!\ This is required even if the local transport is TCP/TLS because the relayed (TURN) transport could be UDP
			// Up to the DTLS socket to set the default MTU value
			SSL_CTX_set_options(transport->dtls.ctx, SSL_OP_NO_QUERY_MTU);
			SSL_CTX_ctrl(transport->dtls.ctx, SSL_CTRL_SET_MTU, TNET_DTLS_MTU - 28, NULL);
			
			transport->dtls.activated = tsk_true;
		}
#endif /* HAVE_OPENSSL_DTLS */
    }
#endif /* HAVE_OPENSSL */
    
    return 0;
}
示例#8
0
文件: apibridge.c 项目: dotnet/corefx
unsigned long local_SSL_CTX_set_options(SSL_CTX* ctx, unsigned long options)
{
    // SSL_CTX_ctrl is signed long in and signed long out; but SSL_CTX_set_options,
    // which was a macro call to SSL_CTX_ctrl in 1.0, is unsigned/unsigned.
    return (unsigned long)SSL_CTX_ctrl(ctx, SSL_CTRL_OPTIONS, (long)options, NULL);
}
示例#9
0
文件: tls.c 项目: bamarni/pure-ftpd
int tls_init_library(void)
{
    unsigned int rnd;

    tls_cnx_handshook = 0;
    tls_data_cnx_handshook = 0;
    SSL_library_init();
    SSL_load_error_strings();
    OpenSSL_add_all_algorithms();
    while (RAND_status() == 0) {
        rnd = zrand();
        RAND_seed(&rnd, (int) sizeof rnd);
    }
    if ((tls_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
        tls_error(__LINE__, 0);
    }
# ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
    SSL_CTX_set_options(tls_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
# endif
# ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
    SSL_CTX_set_options(tls_ctx,
                        SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
# endif
    SSL_CTX_set_options(tls_ctx, SSL_OP_NO_SSLv2);
    SSL_CTX_set_options(tls_ctx, SSL_OP_NO_SSLv3);
# ifdef SSL_OP_NO_TLSv1
    SSL_CTX_clear_options(tls_ctx, SSL_OP_NO_TLSv1);
# endif
# ifdef SSL_OP_NO_TLSv1_1
    SSL_CTX_clear_options(tls_ctx, SSL_OP_NO_TLSv1_1);
# endif
# ifdef SSL_OP_NO_TLSv1_2
    SSL_CTX_clear_options(tls_ctx, SSL_OP_NO_TLSv1_2);
# endif
    if (tlsciphersuite != NULL) {
        if (SSL_CTX_set_cipher_list(tls_ctx, tlsciphersuite) != 1) {
            logfile(LOG_ERR, MSG_TLS_CIPHER_FAILED, tlsciphersuite);
            _EXIT(EXIT_FAILURE);
        }
    }
    if (SSL_CTX_use_certificate_chain_file(tls_ctx, cert_file) != 1) {
        die(421, LOG_ERR,
            MSG_FILE_DOESNT_EXIST ": [%s]", cert_file);
    }
    if (SSL_CTX_use_PrivateKey_file(tls_ctx, cert_file,
                                    SSL_FILETYPE_PEM) != 1) {
        tls_error(__LINE__, 0);
    }
    if (SSL_CTX_check_private_key(tls_ctx) != 1) {
        tls_error(__LINE__, 0);
    }
    tls_init_cache();
# ifdef SSL_CTRL_SET_ECDH_AUTO
    SSL_CTX_ctrl(tls_ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL);
# else
    tls_init_ecdh_curve();
# endif
# ifdef SSL_CTRL_SET_DH_AUTO
    if (tls_init_dhparams() != 0) {
        SSL_CTX_ctrl(tls_ctx, SSL_CTRL_SET_DH_AUTO, 1, NULL);
    }
# else
    if (tls_init_dhparams() != 0) {
        tls_init_dhparams_default();
    }
# endif
# ifdef DISABLE_SSL_RENEGOTIATION
    SSL_CTX_set_info_callback(tls_ctx, ssl_info_cb);
# endif
    SSL_CTX_set_verify_depth(tls_ctx, 6);
    if (ssl_verify_client_cert) {
        SSL_CTX_set_verify(tls_ctx, SSL_VERIFY_FAIL_IF_NO_PEER_CERT |
                           SSL_VERIFY_PEER, NULL);
        if (SSL_CTX_load_verify_locations(tls_ctx, cert_file, NULL) != 1) {
            tls_error(__LINE__, 0);
        }
    }
    return 0;
}