예제 #1
0
static int server_setup_sni(void)
{
    SSL_CTX *cctx = NULL, *sctx = NULL;
    SSL *clientssl = NULL, *serverssl = NULL;
    int testresult = 0;

    if (!TEST_true(create_ssl_ctx_pair(TLS_server_method(),
                                       TLS_client_method(),
                                       TLS1_VERSION, 0,
                                       &sctx, &cctx, cert, privkey))
            || !TEST_true(create_ssl_objects(sctx, cctx, &serverssl, &clientssl,
                                             NULL, NULL)))
        goto end;

    /* set SNI at server side */
    SSL_set_tlsext_host_name(serverssl, host);

    if (!TEST_true(create_ssl_connection(serverssl, clientssl, SSL_ERROR_NONE)))
        goto end;

    if (!TEST_ptr_null(SSL_get_servername(serverssl,
                                          TLSEXT_NAMETYPE_host_name))) {
        /* SNI should have been cleared during handshake */
        goto end;
    }

    testresult = 1;
end:
    SSL_free(serverssl);
    SSL_free(clientssl);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);

    return testresult;
}
예제 #2
0
파일: init.c 프로젝트: bheesham/hst
SSL_CTX *hst_tls_init() {
     _HSTU("open");
     SSL_load_error_strings();
     SSL_library_init();

     const SSL_METHOD *method = TLS_client_method();
     return SSL_CTX_new(method);
}
예제 #3
0
static CIPHERLIST_TEST_FIXTURE set_up(const char *const test_case_name)
{
    CIPHERLIST_TEST_FIXTURE fixture;
    fixture.test_case_name = test_case_name;
    fixture.server = SSL_CTX_new(TLS_server_method());
    fixture.client = SSL_CTX_new(TLS_client_method());
    OPENSSL_assert(fixture.client != NULL && fixture.server != NULL);
    return fixture;
}
예제 #4
0
파일: ssl_test.c 프로젝트: Bloody99/openssl
static int execute_test(SSL_TEST_FIXTURE fixture)
{
    int ret = 0;
    SSL_CTX *server_ctx = NULL, *server2_ctx = NULL, *client_ctx = NULL;
    SSL_TEST_CTX *test_ctx = NULL;
    HANDSHAKE_RESULT result;

    test_ctx = SSL_TEST_CTX_create(conf, fixture.test_app);
    if (test_ctx == NULL)
        goto err;

#ifndef OPENSSL_NO_DTLS
    if (test_ctx->method == SSL_TEST_METHOD_DTLS) {
        server_ctx = SSL_CTX_new(DTLS_server_method());
        if (test_ctx->servername_callback != SSL_TEST_SERVERNAME_CB_NONE) {
            server2_ctx = SSL_CTX_new(DTLS_server_method());
            OPENSSL_assert(server2_ctx != NULL);
        }
        client_ctx = SSL_CTX_new(DTLS_client_method());
    }
#endif
    if (test_ctx->method == SSL_TEST_METHOD_TLS) {
        server_ctx = SSL_CTX_new(TLS_server_method());
        if (test_ctx->servername_callback != SSL_TEST_SERVERNAME_CB_NONE) {
            server2_ctx = SSL_CTX_new(TLS_server_method());
            OPENSSL_assert(server2_ctx != NULL);
        }
        client_ctx = SSL_CTX_new(TLS_client_method());
    }

    OPENSSL_assert(server_ctx != NULL && client_ctx != NULL);

    OPENSSL_assert(CONF_modules_load(conf, fixture.test_app, 0) > 0);

    if (!SSL_CTX_config(server_ctx, "server")
        || !SSL_CTX_config(client_ctx, "client")) {
        goto err;
    }

    if (server2_ctx != NULL && !SSL_CTX_config(server2_ctx, "server2"))
        goto err;

    result = do_handshake(server_ctx, server2_ctx, client_ctx, test_ctx);

    ret = check_test(result, test_ctx);

err:
    CONF_modules_unload(0);
    SSL_CTX_free(server_ctx);
    SSL_CTX_free(server2_ctx);
    SSL_CTX_free(client_ctx);
    SSL_TEST_CTX_free(test_ctx);
    if (ret != 1)
        ERR_print_errors_fp(stderr);
    return ret;
}
예제 #5
0
파일: mbedtls-client.c 프로젝트: 93i/godot
int
lws_tls_client_create_vhost_context(struct lws_vhost *vh,
				    const struct lws_context_creation_info *info,
				    const char *cipher_list,
				    const char *ca_filepath,
				    const char *cert_filepath,
				    const char *private_key_filepath)
{
	X509 *d2i_X509(X509 **cert, const unsigned char *buffer, long len);
	SSL_METHOD *method = (SSL_METHOD *)TLS_client_method();
	unsigned long error;
	lws_filepos_t len;
	uint8_t *buf;

	if (!method) {
		error = ERR_get_error();
		lwsl_err("problem creating ssl method %lu: %s\n",
			error, ERR_error_string(error,
				      (char *)vh->context->pt[0].serv_buf));
		return 1;
	}
	/* create context */
	vh->tls.ssl_client_ctx = SSL_CTX_new(method);
	if (!vh->tls.ssl_client_ctx) {
		error = ERR_get_error();
		lwsl_err("problem creating ssl context %lu: %s\n",
			error, ERR_error_string(error,
				      (char *)vh->context->pt[0].serv_buf));
		return 1;
	}

	if (!ca_filepath)
		return 0;

	if (alloc_file(vh->context, ca_filepath, &buf, &len)) {
		lwsl_err("Load CA cert file %s failed\n", ca_filepath);
		return 1;
	}

	vh->tls.x509_client_CA = d2i_X509(NULL, buf, len);
	free(buf);
	if (!vh->tls.x509_client_CA) {
		lwsl_err("client CA: x509 parse failed\n");
		return 1;
	}

	if (!vh->tls.ssl_ctx)
		SSL_CTX_add_client_CA(vh->tls.ssl_client_ctx, vh->tls.x509_client_CA);
	else
		SSL_CTX_add_client_CA(vh->tls.ssl_ctx, vh->tls.x509_client_CA);

	lwsl_notice("client loaded CA for verification %s\n", ca_filepath);

	return 0;
}
예제 #6
0
/*
  Initializes SSL and allocate global
  context SSL_context

  SYNOPSIS
    my_ssl_start
      mysql        connection handle

  RETURN VALUES
    0  success
    1  error
*/
int ma_tls_start(char *errmsg, size_t errmsg_len)
{
  int rc= 1;
  if (ma_tls_initialized)
    return 0;

  /* lock mutex to prevent multiple initialization */
  pthread_mutex_init(&LOCK_openssl_config,MY_MUTEX_INIT_FAST);
  pthread_mutex_lock(&LOCK_openssl_config);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
  OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
#else
  if (ssl_thread_init())
  {
    strncpy(errmsg, "Not enough memory", errmsg_len);
    goto end;
  }
  SSL_library_init();

#if SSLEAY_VERSION_NUMBER >= 0x00907000L
  OPENSSL_config(NULL);
#endif
#endif
  /* load errors */
  SSL_load_error_strings();
  /* digests and ciphers */
  OpenSSL_add_all_algorithms();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
  if (!(SSL_context= SSL_CTX_new(TLS_client_method())))
#else
  if (!(SSL_context= SSL_CTX_new(SSLv23_client_method())))
#endif
  {
    ma_tls_get_error(errmsg, errmsg_len);
    goto end;
  }
#ifdef HAVE_TLS_SESSION_CACHE
  SSL_CTX_set_session_cache_mode(SSL_context, SSL_SESS_CACHE_CLIENT);
  ma_tls_sessions= (MA_SSL_SESSION *)calloc(1, sizeof(struct st_ma_tls_session) * ma_tls_session_cache_size);
  SSL_CTX_sess_set_new_cb(SSL_context, ma_tls_session_cb);
  SSL_CTX_sess_set_remove_cb(SSL_context, ma_tls_remove_session_cb);
#endif
  disable_sigpipe();
#if OPENSSL_USE_BIOMETHOD
  memcpy(&ma_BIO_method, BIO_s_socket(), sizeof(BIO_METHOD));
  ma_BIO_method.bread= ma_bio_read;
  ma_BIO_method.bwrite= ma_bio_write;
#endif
  rc= 0;
  ma_tls_initialized= TRUE;
end:
  pthread_mutex_unlock(&LOCK_openssl_config);
  return rc;
}
예제 #7
0
//--------------------------------------------------------------------------------------------------
le_result_t secSocket_Init
(
    secSocket_Ctx_t**  ctxPtr       ///< [INOUT] Secure socket context pointer
)
{
    // Check input parameter
    if (!ctxPtr)
    {
        LE_ERROR("Null pointer provided");
        return LE_BAD_PARAMETER;
    }

    // Initialize the socket context pool
    if (!SocketCtxPoolRef)
    {
        SocketCtxPoolRef = le_mem_InitStaticPool(SocketCtxPool,
                                                 MAX_SOCKET_NB,
                                                 sizeof(OpensslCtx_t));
    }

    // Check if the socket is already initialized
    OpensslCtx_t* contextPtr = GetContext(*ctxPtr);
    if ((contextPtr) && (contextPtr->isInit))
    {
        LE_ERROR("Socket context already initialized");
        return LE_FAULT;
    }

    // Alloc memory from pool
    contextPtr = le_mem_TryAlloc(SocketCtxPoolRef);
    if (NULL == contextPtr)
    {
        LE_ERROR("Unable to allocate a socket context from pool");
        return LE_FAULT;
    }

    // Set the magic number
    contextPtr->magicNb = OPENSSL_MAGIC_NUMBER;

    // Initialize OpenSSL library and setup SSL pointers
#if OPENSSL_VERSION_NUMBER < 0x10100000L
    SSL_library_init();
    contextPtr->sslCtxPtr = SSL_CTX_new(TLSv1_client_method());
#else
    OPENSSL_init_ssl(0, NULL);
    contextPtr->sslCtxPtr = SSL_CTX_new(TLS_client_method());
#endif

    contextPtr->isInit = true;
    *ctxPtr = (secSocket_Ctx_t*)contextPtr;

    return LE_OK;
}
예제 #8
0
static CIPHERLIST_TEST_FIXTURE *set_up(const char *const test_case_name)
{
    CIPHERLIST_TEST_FIXTURE *fixture;

    if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))))
        return NULL;
    fixture->test_case_name = test_case_name;
    if (!TEST_ptr(fixture->server = SSL_CTX_new(TLS_server_method()))
            || !TEST_ptr(fixture->client = SSL_CTX_new(TLS_client_method()))) {
        tear_down(fixture);
        return NULL;
    }
    return fixture;
}
예제 #9
0
/*@C
    PetscSSLInitializeContext - Set up an SSL context suitable for initiating HTTPS requests.

    Output Parameter:
.   octx - the SSL_CTX to be passed to PetscHTTPSConnect

    Level: advanced

    If PETSc was ./configure -with-ssl-certificate requires the user have created a self-signed certificate with
$    saws/CA.pl  -newcert  (using the passphrase of password)
$    cat newkey.pem newcert.pem > sslclient.pem

    and put the resulting file in either the current directory (with the application) or in the home directory. This seems kind of
    silly but it was all I could figure out.

.seealso: PetscSSLDestroyContext(), PetscHTTPSConnect(), PetscHTTPSRequest()

@*/
PetscErrorCode PetscSSLInitializeContext(SSL_CTX **octx)
{
    SSL_CTX        *ctx;
#if defined(PETSC_USE_SSL_CERTIFICATE)
    char           keyfile[PETSC_MAX_PATH_LEN];
    PetscBool      exists;
    PetscErrorCode ierr;
#endif

    PetscFunctionBegin;
    if (!bio_err){
      SSL_library_init();
      SSL_load_error_strings();
      bio_err = BIO_new_fp(stderr,BIO_NOCLOSE);
    }

    /* Set up a SIGPIPE handler */
    signal(SIGPIPE,sigpipe_handle);

/* suggested at https://mta.openssl.org/pipermail/openssl-dev/2015-May/001449.html */
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
    ctx  = SSL_CTX_new(TLS_client_method());
#else
    ctx  = SSL_CTX_new(SSLv23_client_method());
#endif
    SSL_CTX_set_mode(ctx,SSL_MODE_AUTO_RETRY);

#if defined(PETSC_USE_SSL_CERTIFICATE)
    /* Locate keyfile */
    ierr = PetscStrcpy(keyfile,"sslclient.pem");CHKERRQ(ierr);
    ierr = PetscTestFile(keyfile,'r',&exists);CHKERRQ(ierr);
    if (!exists) {
      ierr = PetscGetHomeDirectory(keyfile,PETSC_MAX_PATH_LEN);CHKERRQ(ierr);
      ierr = PetscStrcat(keyfile,"/");CHKERRQ(ierr);
      ierr = PetscStrcat(keyfile,"sslclient.pem");CHKERRQ(ierr);
      ierr = PetscTestFile(keyfile,'r',&exists);CHKERRQ(ierr);
      if (!exists) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Unable to locate sslclient.pem file in current directory or home directory");
    }

    /* Load our keys and certificates*/
    if (!(SSL_CTX_use_certificate_chain_file(ctx,keyfile))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot read certificate file");

    SSL_CTX_set_default_passwd_cb(ctx,password_cb);
    if (!(SSL_CTX_use_PrivateKey_file(ctx,keyfile,SSL_FILETYPE_PEM))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,"Cannot read key file");
#endif

    *octx = ctx;
    PetscFunctionReturn(0);
}
예제 #10
0
파일: methods.c 프로젝트: AndreV84/openssl
static const SSL_METHOD *tls1_get_client_method(int ver)
{
    if (ver == TLS_ANY_VERSION)
        return TLS_client_method();
    if (ver == TLS1_2_VERSION)
        return TLSv1_2_client_method();
    if (ver == TLS1_1_VERSION)
        return TLSv1_1_client_method();
    if (ver == TLS1_VERSION)
        return TLSv1_client_method();
#ifndef OPENSSL_NO_SSL3
    if (ver == SSL3_VERSION)
        return (SSLv3_client_method());
#endif
    return NULL;
}
예제 #11
0
static struct mailstream_ssl_data * ssl_data_new(int fd, time_t timeout,
	void (* callback)(struct mailstream_ssl_context * ssl_context, void * cb_data), void * cb_data)
{
  return ssl_data_new_full(fd, timeout,
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
		TLS_client_method(),
#else
	/* Despite their name the SSLv23_*method() functions have nothing to do
	 * with the availability of SSLv2 or SSLv3. What these functions do is
	 * negotiate with the peer the highest available SSL/TLS protocol version
	 * available. The name is as it is for historic reasons. This is a very
	 * common confusion and is the main reason why these names have been
	 * deprecated in the latest dev version of OpenSSL. */
		SSLv23_client_method(),
#endif
		callback, cb_data);
}
예제 #12
0
noPollPtr ssl_context_creator (noPollCtx * ctx, noPollConn * conn, noPollConnOpts * opts, nopoll_bool is_client, noPollPtr user_data)
{
	SSL_CTX             * ssl_ctx;
	noPollConn          * listener;

	/* very basic context creation using default settings provided
	 * by OpenSSL */
	if (is_client) {
#if OPENSSL_VERSION_NUMBER < 0x10100000L
		return SSL_CTX_new (TLSv1_client_method ());
#else
	        return SSL_CTX_new (TLS_client_method ());
#endif
	} /* end if */

	/* get the ssl context */
#if OPENSSL_VERSION_NUMBER < 0x10100000L
	ssl_ctx = SSL_CTX_new (TLSv1_server_method ());
#else
	ssl_ctx = SSL_CTX_new (TLS_server_method ());
#endif

	/* get a reference to the listener */
	listener = nopoll_conn_get_listener (conn);

	if (nopoll_cmp ("1239", nopoll_conn_port (listener))) {
		printf ("ACCEPTED ssl connection on port: %s (for conn %p)\n", nopoll_conn_port (listener), conn);

		/* ok, especiall case where we require a certain
		 * certificate from renote side */
		if (SSL_CTX_load_verify_locations (ssl_ctx, "client-side-cert-auth-cacert.crt", NULL) != 1) {
			printf ("ERROR: unable to add ca certificate...\n");
		}


		/* make server to ask for a certificate to the client
		 * .... and verify it */
		SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback);
	} /* end if */
	
	printf ("RETURNING: ssl context reference %p\n", ssl_ctx);
	return ssl_ctx;
}
예제 #13
0
/*
  Initializes SSL and allocate global
  context SSL_context

  SYNOPSIS
    my_ssl_start
      mysql        connection handle

  RETURN VALUES
    0  success
    1  error
*/
int my_ssl_start(MYSQL *mysql)
{
  int rc= 0;
  DBUG_ENTER("my_ssl_start");
  /* lock mutex to prevent multiple initialization */
  pthread_mutex_lock(&LOCK_ssl_config);
  if (!my_ssl_initialized)
  {
#if OPENSSL_VERSION_NUMBER < 0x10100000
    if (ssl_crypto_init())
      goto end;
#endif
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
    OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
#else
    SSL_library_init();
#if SSLEAY_VERSION_NUMBER >= 0x00907000L
    OPENSSL_config(NULL);
#endif
#endif

    /* load errors */
    SSL_load_error_strings();
    /* digests and ciphers */
    OpenSSL_add_all_algorithms();

#if OPENSSL_VERSION_NUMBER >= 0x10100000L
    if (!(SSL_context= SSL_CTX_new(TLS_client_method())))
#else
    if (!(SSL_context= SSL_CTX_new(TLSv1_client_method())))
#endif
    {
      my_SSL_error(mysql);
      rc= 1;
      goto end;
    }
    my_ssl_initialized= TRUE;
  }
end:
  pthread_mutex_unlock(&LOCK_ssl_config);
  DBUG_RETURN(rc);
}
예제 #14
0
const SSL_METHOD * hb_ssl_method_id_to_ptr( int n )
{
   const SSL_METHOD * p;

   switch( n )
   {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
      case HB_SSL_CTX_NEW_METHOD_TLS:           p = TLS_method();           break;
      case HB_SSL_CTX_NEW_METHOD_TLS_SERVER:    p = TLS_server_method();    break;
      case HB_SSL_CTX_NEW_METHOD_TLS_CLIENT:    p = TLS_client_method();    break;
#else
      case HB_SSL_CTX_NEW_METHOD_TLSV1:         p = TLSv1_method();         break;
      case HB_SSL_CTX_NEW_METHOD_TLSV1_SERVER:  p = TLSv1_server_method();  break;
      case HB_SSL_CTX_NEW_METHOD_TLSV1_CLIENT:  p = TLSv1_client_method();  break;
      case HB_SSL_CTX_NEW_METHOD_TLS:           p = SSLv23_method();        break;
      case HB_SSL_CTX_NEW_METHOD_TLS_SERVER:    p = SSLv23_server_method(); break;
      case HB_SSL_CTX_NEW_METHOD_TLS_CLIENT:    p = SSLv23_client_method(); break;
#endif
      default: p = SSLv23_method();
   }

   return p;
}
예제 #15
0
/*
 * Custom call back tests.
 * Test 0: callbacks in TLSv1.2
 * Test 1: callbacks in TLSv1.2 with SNI
 */
static int test_custom_exts(int tst)
{
    SSL_CTX *cctx = NULL, *sctx = NULL, *sctx2 = NULL;
    SSL *clientssl = NULL, *serverssl = NULL;
    int testresult = 0;
    static int server = 1;
    static int client = 0;
    SSL_SESSION *sess = NULL;

    /* Reset callback counters */
    clntaddcb = clntparsecb = srvaddcb = srvparsecb = 0;
    snicb = 0;

    if (!create_ssl_ctx_pair(TLS_server_method(),  TLS_client_method(), &sctx,
                             &cctx, cert, privkey)) {
        printf("Unable to create SSL_CTX pair\n");
        goto end;
    }

    if (tst == 1
            && !create_ssl_ctx_pair(TLS_server_method(), NULL, &sctx2, NULL,
                                    cert, privkey)) {
        printf("Unable to create SSL_CTX pair (2)\n");
        goto end;
    }

    /* Create a client side custom extension */
    if (!SSL_CTX_add_client_custom_ext(cctx, TEST_EXT_TYPE1, add_cb, free_cb,
                                       &client, parse_cb, &client)) {
        printf("Unable to add client custom extension\n");
        goto end;
    }

    /* Should not be able to add duplicates */
    if (SSL_CTX_add_client_custom_ext(cctx, TEST_EXT_TYPE1, add_cb, free_cb,
                                      &client, parse_cb, &client)) {
        printf("Unexpected success adding duplicate extension\n");
        goto end;
    }

    /* Create a server side custom extension */
    if (!SSL_CTX_add_server_custom_ext(sctx, TEST_EXT_TYPE1, add_cb, free_cb,
                                       &server, parse_cb, &server)) {
        printf("Unable to add server custom extension\n");
        goto end;
    }
    if (sctx2 != NULL
            && !SSL_CTX_add_server_custom_ext(sctx2, TEST_EXT_TYPE1,
                                                        add_cb, free_cb,
                                                        &server, parse_cb,
                                                        &server)) {
        printf("Unable to add server custom extension for SNI\n");
        goto end;
    }

    /* Should not be able to add duplicates */
    if (SSL_CTX_add_server_custom_ext(sctx, TEST_EXT_TYPE1, add_cb, free_cb,
                                      &server, parse_cb, &server)) {
        printf("Unexpected success adding duplicate extension (2)\n");
        goto end;
    }

    if (tst == 1) {
        /* Set up SNI */
        if (!SSL_CTX_set_tlsext_servername_callback(sctx, sni_cb)
                || !SSL_CTX_set_tlsext_servername_arg(sctx, sctx2)) {
            printf("Cannot set SNI callbacks\n");
            goto end;
        }
    }

    if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)
            || !create_ssl_connection(serverssl, clientssl)) {
        printf("Cannot create SSL connection\n");
        goto end;
    }

    if (clntaddcb != 1
            || clntparsecb != 1
            || srvaddcb != 1
            || srvparsecb != 1
            || (tst != 1 && snicb != 0)
            || (tst == 1 && snicb != 1)) {
        printf("Incorrect callback counts\n");
        goto end;
    }

    sess = SSL_get1_session(clientssl);
    SSL_shutdown(clientssl);
    SSL_shutdown(serverssl);
    SSL_free(serverssl);
    SSL_free(clientssl);
    serverssl = clientssl = NULL;

    if (tst == 1) {
        /* We don't bother with the resumption aspects for this test */
        testresult = 1;
        goto end;
    }

    if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)
            || !SSL_set_session(clientssl, sess)
            || !create_ssl_connection(serverssl, clientssl)) {
        printf("Cannot create resumption connection\n");
        goto end;
    }

    /*
     * For a resumed session we expect to add the ClientHello extension but we
     * should ignore it on the server side.
     */
    if (clntaddcb != 2
            || clntparsecb != 1
            || srvaddcb != 1
            || srvparsecb != 1) {
        printf("Incorrect resumption callback counts\n");
        goto end;
    }

    testresult = 1;

end:
    SSL_SESSION_free(sess);
    SSL_free(serverssl);
    SSL_free(clientssl);
    SSL_CTX_free(sctx2);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);
    return testresult;
}
예제 #16
0
net_socketSSL_t*
net_socketSSL_connect(const char* addr,
                      const char* port, int type)
{
	assert(addr);
	assert(port);

	int socktype;
	if((type >= NET_SOCKETSSL_TCP) &&
	   (type <= NET_SOCKETSSL_TCP_BUFFERED))
	{
		socktype = SOCK_STREAM;
	}
	else
	{
		LOGE("invalid type=%i", type);
		return NULL;
	}

	net_socketSSL_t* self;
	self = (net_socketSSL_t*)
	       malloc(sizeof(net_socketSSL_t));
	if(self == NULL)
	{
		LOGE("malloc failed");
		return NULL;
	}

	// SIGPIPE causes the process to exit for broken streams
	// but we want to receive EPIPE instead
	signal(SIGPIPE, SIG_IGN);

	if(type == NET_SOCKETSSL_TCP_BUFFERED)
	{
		self->buffer = (unsigned char*)
		               malloc(NET_SOCKETSSL_BUFSIZE*
		                      sizeof(unsigned char));
		if(self->buffer == NULL)
		{
			LOGE("malloc failed");
			goto fail_buffer;
		}
	}
	else
	{
		self->buffer = NULL;
	}
	self->len = 0;

	// for HTTP
	snprintf(self->host, 256, "%s:%s", addr, port);

	// init SSL ctx
#if NET_SOCKET_USE_OPENSSL_1_1
	self->ctx = SSL_CTX_new(TLS_client_method());
#else
	// app should call SSL_library_init(); prior to creating any
	// OpenSSL sockets with the old API
	self->ctx = SSL_CTX_new(SSLv23_client_method());
#endif
	if(self->ctx == NULL)
	{
		LOGE("SSL_CTX_new failed");
		goto fail_ctx;
	}
	self->method = NET_SOCKETSSL_METHOD_CLIENT;

	if(SSL_CTX_load_verify_locations(self->ctx,
	                                 "ca_cert.pem", NULL) != 1)
	{
		LOGE("SSL_CTX_load_verify_locations failed");
		goto fail_load_verify;
	}

#if NET_SOCKET_USE_OPENSSL_1_1
	if(SSL_CTX_set_default_verify_file(self->ctx) != 1)
	{
		LOGE("SSL_CTX_set_default_verify_file failed");
		goto fail_set_default_verify_file;
	}
#endif

	if(SSL_CTX_use_certificate_file(self->ctx,
	                                "client_cert.pem",
	                                SSL_FILETYPE_PEM) != 1)
	{
		LOGE("SSL_CTX_use_certificate_file failed");
		goto fail_use_cert;
	}

	if(SSL_CTX_use_PrivateKey_file(self->ctx,
	                               "client_key.pem",
	                               SSL_FILETYPE_PEM) != 1)
	{
		LOGE("SSL_CTX_use_PrivateKey_file failed");
		goto fail_use_priv;
	}

	if(SSL_CTX_check_private_key(self->ctx) != 1)
	{
		LOGE("SSL_CTX_check_private_key failed");
		goto fail_check_priv;
	}

	SSL_CTX_set_mode(self->ctx, SSL_MODE_AUTO_RETRY);
	SSL_CTX_set_verify(self->ctx, SSL_VERIFY_PEER, NULL);
	SSL_CTX_set_verify_depth(self->ctx, 1);

	struct addrinfo hints;
	memset(&hints, 0, sizeof(hints));
	hints.ai_family   = AF_UNSPEC;
	hints.ai_socktype = socktype;

	struct addrinfo* info;
	if(getaddrinfo(addr, port, &hints, &info) != 0)
	{
		LOGD("getaddrinfo addr=%s, port=%s, failed",
		     addr, port);
		goto fail_getaddrinfo;
	}

	struct addrinfo* i = info;
	self->sockfd = -1;
	while(i)
	{
		self->sockfd = socket(i->ai_family,
		                      i->ai_socktype,
		                      i->ai_protocol);
		if(self->sockfd == -1)
		{
			LOGD("socket failed");
			i = i->ai_next;
			continue;
		}

		if((type == NET_SOCKETSSL_TCP_NODELAY) ||
		   (type == NET_SOCKETSSL_TCP_BUFFERED))
		{
			int yes = 1;
			if(setsockopt(self->sockfd, IPPROTO_TCP,
			              TCP_NODELAY, (const void*) &yes,
			              sizeof(int)) == -1)
			{
				LOGD("setsockopt TCP_NODELAY failed");
			}
		}

		if(net_socketSSL_connectTimeout(self, i) == 0)
		{
			close(self->sockfd);
			self->sockfd = -1;
			i = i->ai_next;
			continue;
		}

		break;
	}
	freeaddrinfo(info);

	if(self->sockfd == -1)
	{
		LOGD("socket failed");
		goto fail_socket;
	}

	self->error     = 0;
	self->connected = 1;
	self->type      = type;

	// success
	return self;

	// failure
	fail_socket:
	fail_getaddrinfo:
	fail_check_priv:
	fail_use_priv:
	fail_use_cert:
#if NET_SOCKET_USE_OPENSSL_1_1
	fail_set_default_verify_file:
#endif
	fail_load_verify:
		SSL_CTX_free(self->ctx);
	fail_ctx:
		free(self->buffer);
	fail_buffer:
		free(self);
	return NULL;
}
예제 #17
0
파일: openssl.c 프로젝트: ariscop/charybdis
int
rb_init_ssl(void)
{
	int ret = 1;
	char libratbox_data[] = "libratbox data";
	const char libratbox_ciphers[] = "kEECDH+HIGH:kEDH+HIGH:HIGH:!RC4:!aNULL";
	SSL_load_error_strings();
	SSL_library_init();
	libratbox_index = SSL_get_ex_new_index(0, libratbox_data, NULL, NULL, NULL);

#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L)
	ssl_server_ctx = SSL_CTX_new(SSLv23_server_method());
#else
	ssl_server_ctx = SSL_CTX_new(TLS_server_method());
#endif

	if(ssl_server_ctx == NULL)
	{
		rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s",
			   get_ssl_error(ERR_get_error()));
		ret = 0;
	}

	long server_options = SSL_CTX_get_options(ssl_server_ctx);

#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L)
	server_options |= SSL_OP_NO_SSLv2;
	server_options |= SSL_OP_NO_SSLv3;
#endif

#ifdef SSL_OP_SINGLE_DH_USE
	server_options |= SSL_OP_SINGLE_DH_USE;
#endif

#ifdef SSL_OP_SINGLE_ECDH_USE
	server_options |= SSL_OP_SINGLE_ECDH_USE;
#endif

#ifdef SSL_OP_NO_TICKET
	server_options |= SSL_OP_NO_TICKET;
#endif

	server_options |= SSL_OP_CIPHER_SERVER_PREFERENCE;

	SSL_CTX_set_options(ssl_server_ctx, server_options);
	SSL_CTX_set_verify(ssl_server_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb);
	SSL_CTX_set_session_cache_mode(ssl_server_ctx, SSL_SESS_CACHE_OFF);
	SSL_CTX_set_cipher_list(ssl_server_ctx, libratbox_ciphers);

	/* Set ECDHE on OpenSSL 1.00+, but make sure it's actually available because redhat are dicks
	   and bastardise their OpenSSL for stupid reasons... */
	#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && defined(NID_secp384r1)
		EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp384r1);
		if (key) {
			SSL_CTX_set_tmp_ecdh(ssl_server_ctx, key);
			EC_KEY_free(key);
		}
	#endif

#if defined(LIBRESSL_VERSION_NUMBER) || (OPENSSL_VERSION_NUMBER < 0x10100000L)
	ssl_client_ctx = SSL_CTX_new(TLSv1_client_method());
#else
	ssl_client_ctx = SSL_CTX_new(TLS_client_method());
#endif

	if(ssl_client_ctx == NULL)
	{
		rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s",
			   get_ssl_error(ERR_get_error()));
		ret = 0;
	}

#ifdef SSL_OP_NO_TICKET
	SSL_CTX_set_options(ssl_client_ctx, SSL_OP_NO_TICKET);
#endif

	SSL_CTX_set_cipher_list(ssl_client_ctx, libratbox_ciphers);

	return ret;
}
예제 #18
0
static int test_tlsext_status_type(void)
{
    SSL_CTX *cctx = NULL, *sctx = NULL;
    SSL *clientssl = NULL, *serverssl = NULL;
    int testresult = 0;
    STACK_OF(OCSP_RESPID) *ids = NULL;
    OCSP_RESPID *id = NULL;
    BIO *certbio = NULL;

    if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx,
                             &cctx, cert, privkey)) {
        printf("Unable to create SSL_CTX pair\n");
        return 0;
    }

    if (SSL_CTX_get_tlsext_status_type(cctx) != -1) {
        printf("Unexpected initial value for "
               "SSL_CTX_get_tlsext_status_type()\n");
        goto end;
    }

    /* First just do various checks getting and setting tlsext_status_type */

    clientssl = SSL_new(cctx);
    if (SSL_get_tlsext_status_type(clientssl) != -1) {
        printf("Unexpected initial value for SSL_get_tlsext_status_type()\n");
        goto end;
    }

    if (!SSL_set_tlsext_status_type(clientssl, TLSEXT_STATUSTYPE_ocsp)) {
        printf("Unexpected fail for SSL_set_tlsext_status_type()\n");
        goto end;
    }

    if (SSL_get_tlsext_status_type(clientssl) != TLSEXT_STATUSTYPE_ocsp) {
        printf("Unexpected result for SSL_get_tlsext_status_type()\n");
        goto end;
    }

    SSL_free(clientssl);
    clientssl = NULL;

    if (!SSL_CTX_set_tlsext_status_type(cctx, TLSEXT_STATUSTYPE_ocsp)) {
        printf("Unexpected fail for SSL_CTX_set_tlsext_status_type()\n");
        goto end;
    }

    if (SSL_CTX_get_tlsext_status_type(cctx) != TLSEXT_STATUSTYPE_ocsp) {
        printf("Unexpected result for SSL_CTX_get_tlsext_status_type()\n");
        goto end;
    }

    clientssl = SSL_new(cctx);

    if (SSL_get_tlsext_status_type(clientssl) != TLSEXT_STATUSTYPE_ocsp) {
        printf("Unexpected result for SSL_get_tlsext_status_type() (test 2)\n");
        goto end;
    }

    SSL_free(clientssl);
    clientssl = NULL;

    /*
     * Now actually do a handshake and check OCSP information is exchanged and
     * the callbacks get called
     */

    SSL_CTX_set_tlsext_status_cb(cctx, ocsp_client_cb);
    SSL_CTX_set_tlsext_status_arg(cctx, &cdummyarg);
    SSL_CTX_set_tlsext_status_cb(sctx, ocsp_server_cb);
    SSL_CTX_set_tlsext_status_arg(sctx, &cdummyarg);

    if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) {
        printf("Unable to create SSL objects\n");
        goto end;
    }

    if (!create_ssl_connection(serverssl, clientssl)) {
        printf("Unable to create SSL connection\n");
        goto end;
    }

    if (!ocsp_client_called || !ocsp_server_called) {
        printf("OCSP callbacks not called\n");
        goto end;
    }

    SSL_free(serverssl);
    SSL_free(clientssl);
    serverssl = NULL;
    clientssl = NULL;

    /* Try again but this time force the server side callback to fail */
    ocsp_client_called = 0;
    ocsp_server_called = 0;
    cdummyarg = 0;

    if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) {
        printf("Unable to create SSL objects\n");
        goto end;
    }

    /* This should fail because the callback will fail */
    if (create_ssl_connection(serverssl, clientssl)) {
        printf("Unexpected success creating the connection\n");
        goto end;
    }

    if (ocsp_client_called || ocsp_server_called) {
        printf("OCSP callbacks successfully called unexpectedly\n");
        goto end;
    }

    SSL_free(serverssl);
    SSL_free(clientssl);
    serverssl = NULL;
    clientssl = NULL;

    /*
     * This time we'll get the client to send an OCSP_RESPID that it will
     * accept.
     */
    ocsp_client_called = 0;
    ocsp_server_called = 0;
    cdummyarg = 2;

    if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) {
        printf("Unable to create SSL objects\n");
        goto end;
    }

    /*
     * We'll just use any old cert for this test - it doesn't have to be an OCSP
     * specific one. We'll use the server cert.
     */
    certbio = BIO_new_file(cert, "r");
    if (certbio == NULL) {
        printf("Can't load the certificate file\n");
        goto end;
    }
    id = OCSP_RESPID_new();
    ids = sk_OCSP_RESPID_new_null();
    ocspcert = PEM_read_bio_X509(certbio, NULL, NULL, NULL);
    if (id == NULL || ids == NULL || ocspcert == NULL
            || !OCSP_RESPID_set_by_key(id, ocspcert)
            || !sk_OCSP_RESPID_push(ids, id)) {
        printf("Unable to set OCSP_RESPIDs\n");
        goto end;
    }
    id = NULL;
    SSL_set_tlsext_status_ids(clientssl, ids);
    /* Control has been transferred */
    ids = NULL;

    BIO_free(certbio);
    certbio = NULL;

    if (!create_ssl_connection(serverssl, clientssl)) {
        printf("Unable to create SSL connection\n");
        goto end;
    }

    if (!ocsp_client_called || !ocsp_server_called) {
        printf("OCSP callbacks not called\n");
        goto end;
    }

    testresult = 1;

 end:
    SSL_free(serverssl);
    SSL_free(clientssl);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);
    sk_OCSP_RESPID_pop_free(ids, OCSP_RESPID_free);
    OCSP_RESPID_free(id);
    BIO_free(certbio);
    X509_free(ocspcert);
    ocspcert = NULL;

    return testresult;
}
예제 #19
0
static int test_set_sigalgs(int idx)
{
    SSL_CTX *cctx = NULL, *sctx = NULL;
    SSL *clientssl = NULL, *serverssl = NULL;
    int testresult = 0;
    const sigalgs_list *curr;
    int testctx;

    /* Should never happen */
    if ((size_t)idx >= OSSL_NELEM(testsigalgs) * 2)
        return 0;

    testctx = ((size_t)idx < OSSL_NELEM(testsigalgs));
    curr = testctx ? &testsigalgs[idx]
                   : &testsigalgs[idx - OSSL_NELEM(testsigalgs)];

    if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx,
                             &cctx, cert, privkey)) {
        printf("Unable to create SSL_CTX pair\n");
        return 0;
    }

    if (testctx) {
        int ret;
        if (curr->list != NULL)
            ret = SSL_CTX_set1_sigalgs(cctx, curr->list, curr->listlen);
        else
            ret = SSL_CTX_set1_sigalgs_list(cctx, curr->liststr);

        if (!ret) {
            if (curr->valid)
                printf("Unexpected failure setting sigalgs in SSL_CTX (%d)\n",
                       idx);
            else
                testresult = 1;
            goto end;
        }
        if (!curr->valid) {
            printf("Unexpected success setting sigalgs in SSL_CTX (%d)\n", idx);
            goto end;
        }
    }

    if (!create_ssl_objects(sctx, cctx, &serverssl, &clientssl, NULL, NULL)) {
        printf("Unable to create SSL objects\n");
        goto end;
    }

    if (!testctx) {
        int ret;

        if (curr->list != NULL)
            ret = SSL_set1_sigalgs(clientssl, curr->list, curr->listlen);
        else
            ret = SSL_set1_sigalgs_list(clientssl, curr->liststr);
        if (!ret) {
            if (curr->valid)
                printf("Unexpected failure setting sigalgs in SSL (%d)\n", idx);
            else
                testresult = 1;
            goto end;
        }
        if (!curr->valid) {
            printf("Unexpected success setting sigalgs in SSL (%d)\n", idx);
            goto end;
        }
    }

    if (curr->connsuccess != create_ssl_connection(serverssl, clientssl)) {
        printf("Unexpected return value creating SSL connection (%d)\n", idx);
        goto end;
    }

    testresult = 1;

 end:
    SSL_free(serverssl);
    SSL_free(clientssl);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);

    return testresult;
}
예제 #20
0
int main(int argc, char **argv)
{
    BIO *sbio = NULL, *out = NULL;
    int i, len, rv;
    char tmpbuf[1024];
    SSL_CTX *ctx = NULL;
    SSL_CONF_CTX *cctx = NULL;
    SSL *ssl = NULL;
    CONF *conf = NULL;
    STACK_OF(CONF_VALUE) *sect = NULL;
    CONF_VALUE *cnf;
    const char *connect_str = "localhost:4433";
    long errline = -1;

    ERR_load_crypto_strings();
    ERR_load_SSL_strings();
    SSL_library_init();

    conf = NCONF_new(NULL);

    if (NCONF_load(conf, "connect.cnf", &errline) <= 0) {
        if (errline <= 0)
            fprintf(stderr, "Error processing config file\n");
        else
            fprintf(stderr, "Error on line %ld\n", errline);
        goto end;
    }

    sect = NCONF_get_section(conf, "default");

    if (sect == NULL) {
        fprintf(stderr, "Error retrieving default section\n");
        goto end;
    }

    ctx = SSL_CTX_new(TLS_client_method());
    cctx = SSL_CONF_CTX_new();
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
    SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_FILE);
    SSL_CONF_CTX_set_ssl_ctx(cctx, ctx);
    for (i = 0; i < sk_CONF_VALUE_num(sect); i++) {
        cnf = sk_CONF_VALUE_value(sect, i);
        rv = SSL_CONF_cmd(cctx, cnf->name, cnf->value);
        if (rv > 0)
            continue;
        if (rv != -2) {
            fprintf(stderr, "Error processing %s = %s\n",
                    cnf->name, cnf->value);
            ERR_print_errors_fp(stderr);
            goto end;
        }
        if (strcmp(cnf->name, "Connect") == 0) {
            connect_str = cnf->value;
        } else {
            fprintf(stderr, "Unknown configuration option %s\n", cnf->name);
            goto end;
        }
    }

    if (!SSL_CONF_CTX_finish(cctx)) {
        fprintf(stderr, "Finish error\n");
        ERR_print_errors_fp(stderr);
        goto err;
    }

    /*
     * We'd normally set some stuff like the verify paths and * mode here
     * because as things stand this will connect to * any server whose
     * certificate is signed by any CA.
     */

    sbio = BIO_new_ssl_connect(ctx);

    BIO_get_ssl(sbio, &ssl);

    if (!ssl) {
        fprintf(stderr, "Can't locate SSL pointer\n");
        goto end;
    }

    /* Don't want any retries */
    SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

    /* We might want to do other things with ssl here */

    BIO_set_conn_hostname(sbio, connect_str);

    out = BIO_new_fp(stdout, BIO_NOCLOSE);
    if (BIO_do_connect(sbio) <= 0) {
        fprintf(stderr, "Error connecting to server\n");
        ERR_print_errors_fp(stderr);
        goto end;
    }

    if (BIO_do_handshake(sbio) <= 0) {
        fprintf(stderr, "Error establishing SSL connection\n");
        ERR_print_errors_fp(stderr);
        goto end;
    }

    /* Could examine ssl here to get connection info */

    BIO_puts(sbio, "GET / HTTP/1.0\n\n");
    for (;;) {
        len = BIO_read(sbio, tmpbuf, 1024);
        if (len <= 0)
            break;
        BIO_write(out, tmpbuf, len);
    }
 end:
    SSL_CONF_CTX_free(cctx);
    BIO_free_all(sbio);
    BIO_free(out);
    NCONF_free(conf);
    return 0;
}
예제 #21
0
int
rb_setup_ssl_server(const char *certfile, const char *keyfile, const char *dhfile, const char *cipher_list)
{
	const char librb_ciphers[] = "kEECDH+HIGH:kEDH+HIGH:HIGH:!aNULL";

	#ifdef LRB_HAVE_TLS_SET_CURVES
	const char librb_curves[] = "P-521:P-384:P-256";
	#endif

	if(certfile == NULL)
	{
		rb_lib_log("rb_setup_ssl_server: No certificate file");
		return 0;
	}

	if(keyfile == NULL)
		keyfile = certfile;

	if(cipher_list == NULL)
		cipher_list = librb_ciphers;

	if (ssl_server_ctx)
		SSL_CTX_free(ssl_server_ctx);

	if (ssl_client_ctx)
		SSL_CTX_free(ssl_client_ctx);

	#ifdef LRB_HAVE_TLS_METHOD_API
	ssl_server_ctx = SSL_CTX_new(TLS_server_method());
	ssl_client_ctx = SSL_CTX_new(TLS_client_method());
	#else
	ssl_server_ctx = SSL_CTX_new(SSLv23_server_method());
	ssl_client_ctx = SSL_CTX_new(SSLv23_client_method());
	#endif

	if(ssl_server_ctx == NULL)
	{
		rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s",
			   get_ssl_error(ERR_get_error()));
		return 0;
	}

	if(ssl_client_ctx == NULL)
	{
		rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL client context: %s",
			   get_ssl_error(ERR_get_error()));
		return 0;
	}

	#ifndef LRB_HAVE_TLS_METHOD_API
	SSL_CTX_set_options(ssl_server_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
	SSL_CTX_set_options(ssl_client_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
	#endif

	#ifdef SSL_OP_SINGLE_DH_USE
	SSL_CTX_set_options(ssl_server_ctx, SSL_OP_SINGLE_DH_USE);
	#endif

	#ifdef SSL_OP_SINGLE_ECDH_USE
	SSL_CTX_set_options(ssl_server_ctx, SSL_OP_SINGLE_ECDH_USE);
	#endif

	#ifdef SSL_OP_NO_TICKET
	SSL_CTX_set_options(ssl_server_ctx, SSL_OP_NO_TICKET);
	SSL_CTX_set_options(ssl_client_ctx, SSL_OP_NO_TICKET);
	#endif

	#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
	SSL_CTX_set_options(ssl_server_ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
	#endif

	SSL_CTX_set_verify(ssl_server_ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_accept_all_cb);
	SSL_CTX_set_session_cache_mode(ssl_server_ctx, SSL_SESS_CACHE_OFF);

	#ifdef LRB_HAVE_TLS_SET_CURVES
	SSL_CTX_set1_curves_list(ssl_server_ctx, librb_curves);
	#endif

	#ifdef LRB_HAVE_TLS_ECDH_AUTO
	SSL_CTX_set_ecdh_auto(ssl_server_ctx, 1);
	#endif

	/*
	 * Set manual ECDHE curve on OpenSSL 1.0.0 & 1.0.1, but make sure it's actually available
	 */
	#if (OPENSSL_VERSION_NUMBER >= 0x10000000L) && (OPENSSL_VERSION_NUMBER < 0x10002000L) && !defined(OPENSSL_NO_ECDH)
	EC_KEY *key = EC_KEY_new_by_curve_name(NID_secp384r1);
	if (key) {
		SSL_CTX_set_tmp_ecdh(ssl_server_ctx, key);
		EC_KEY_free(key);
	}
	#endif

	SSL_CTX_set_cipher_list(ssl_server_ctx, cipher_list);
	SSL_CTX_set_cipher_list(ssl_client_ctx, cipher_list);

	if(!SSL_CTX_use_certificate_chain_file(ssl_server_ctx, certfile) || !SSL_CTX_use_certificate_chain_file(ssl_client_ctx, certfile))
	{
		rb_lib_log("rb_setup_ssl_server: Error loading certificate file [%s]: %s", certfile,
			   get_ssl_error(ERR_get_error()));
		return 0;
	}

	if(!SSL_CTX_use_PrivateKey_file(ssl_server_ctx, keyfile, SSL_FILETYPE_PEM) || !SSL_CTX_use_PrivateKey_file(ssl_client_ctx, keyfile, SSL_FILETYPE_PEM))
	{
		rb_lib_log("rb_setup_ssl_server: Error loading keyfile [%s]: %s", keyfile,
			   get_ssl_error(ERR_get_error()));
		return 0;
	}

	if(dhfile != NULL)
	{
		/* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */
		FILE *fp = fopen(dhfile, "r");
		DH *dh = NULL;

		if(fp == NULL)
		{
			rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
			           dhfile, strerror(errno));
		}
		else if(PEM_read_DHparams(fp, &dh, NULL, NULL) == NULL)
		{
			rb_lib_log("rb_setup_ssl_server: Error loading DH params file [%s]: %s",
			           dhfile, get_ssl_error(ERR_get_error()));
			fclose(fp);
		}
		else
		{
			SSL_CTX_set_tmp_dh(ssl_server_ctx, dh);
			DH_free(dh);
			fclose(fp);
		}
	}

	return 1;
}
예제 #22
0
void Context::createSSLContext()
{
	if (SSLManager::isFIPSEnabled())
	{
		_pSSLContext = SSL_CTX_new(TLSv1_method());
	}
	else
	{
		switch (_usage)
		{
		case CLIENT_USE:
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
			_pSSLContext = SSL_CTX_new(TLS_client_method());
#else
			_pSSLContext = SSL_CTX_new(SSLv23_client_method());
#endif
			break;
		case SERVER_USE:
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
			_pSSLContext = SSL_CTX_new(TLS_server_method());
#else
			_pSSLContext = SSL_CTX_new(SSLv23_server_method());
#endif
			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);
}
예제 #23
0
static int test_large_message_tls(void)
{
    return execute_test_large_message(TLS_server_method(), TLS_client_method(),
                                      0);
}
예제 #24
0
TLS_APPL_STATE *tls_client_init(const TLS_CLIENT_INIT_PROPS *props)
{
    long    off = 0;
    int     cachable;
    int     scache_timeout;
    SSL_CTX *client_ctx;
    TLS_APPL_STATE *app_ctx;
    int     log_mask;

    /*
     * Convert user loglevel to internal logmask.
     */
    log_mask = tls_log_mask(props->log_param, props->log_level);

    if (log_mask & TLS_LOG_VERBOSE)
	msg_info("initializing the client-side TLS engine");

    /*
     * Load (mostly cipher related) TLS-library internal main.cf parameters.
     */
    tls_param_init();

    /*
     * Detect mismatch between compile-time headers and run-time library.
     */
    tls_check_version();

    /*
     * Initialize the OpenSSL library by the book! To start with, we must
     * initialize the algorithms. We want cleartext error messages instead of
     * just error codes, so we load the error_strings.
     */
    SSL_load_error_strings();
    OpenSSL_add_ssl_algorithms();

    /*
     * Create an application data index for SSL objects, so that we can
     * attach TLScontext information; this information is needed inside
     * tls_verify_certificate_callback().
     */
    if (TLScontext_index < 0) {
	if ((TLScontext_index = SSL_get_ex_new_index(0, 0, 0, 0, 0)) < 0) {
	    msg_warn("Cannot allocate SSL application data index: "
		     "disabling TLS support");
	    return (0);
	}
    }

    /*
     * If the administrator specifies an unsupported digest algorithm, fail
     * now, rather than in the middle of a TLS handshake.
     */
    if (!tls_validate_digest(props->mdalg)) {
	msg_warn("disabling TLS support");
	return (0);
    }

    /*
     * Initialize the PRNG (Pseudo Random Number Generator) with some seed
     * from external and internal sources. Don't enable TLS without some real
     * entropy.
     */
    if (tls_ext_seed(var_tls_daemon_rand_bytes) < 0) {
	msg_warn("no entropy for TLS key generation: disabling TLS support");
	return (0);
    }
    tls_int_seed();

    /*
     * The SSL/TLS specifications require the client to send a message in the
     * oldest specification it understands with the highest level it
     * understands in the message. RFC2487 is only specified for TLSv1, but
     * we want to be as compatible as possible, so we will start off with a
     * SSLv2 greeting allowing the best we can offer: TLSv1. We can restrict
     * this with the options setting later, anyhow.
     *
     * OpenSSL 1.1.0-dev deprecates SSLv23_client_method() in favour of
     * TLS_client_method(), with the change in question signalled via a new
     * TLS_ANY_VERSION macro.
     */
    ERR_clear_error();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L && defined(TLS_ANY_VERSION)
    client_ctx = SSL_CTX_new(TLS_client_method());
#else
    client_ctx = SSL_CTX_new(SSLv23_client_method());
#endif
    if (client_ctx == 0) {
	msg_warn("cannot allocate client SSL_CTX: disabling TLS support");
	tls_print_errors();
	return (0);
    }

    /*
     * See the verify callback in tls_verify.c
     */
    SSL_CTX_set_verify_depth(client_ctx, props->verifydepth + 1);

    /*
     * Protocol selection is destination dependent, so we delay the protocol
     * selection options to the per-session SSL object.
     */
    off |= tls_bug_bits();
    SSL_CTX_set_options(client_ctx, off);

    /*
     * Set the call-back routine for verbose logging.
     */
    if (log_mask & TLS_LOG_DEBUG)
	SSL_CTX_set_info_callback(client_ctx, tls_info_callback);

    /*
     * Load the CA public key certificates for both the client cert and for
     * the verification of server certificates. As provided by OpenSSL we
     * support two types of CA certificate handling: One possibility is to
     * add all CA certificates to one large CAfile, the other possibility is
     * a directory pointed to by CApath, containing separate files for each
     * CA with softlinks named after the hash values of the certificate. The
     * first alternative has the advantage that the file is opened and read
     * at startup time, so that you don't have the hassle to maintain another
     * copy of the CApath directory for chroot-jail.
     */
    if (tls_set_ca_certificate_info(client_ctx,
				    props->CAfile, props->CApath) < 0) {
	/* tls_set_ca_certificate_info() already logs a warning. */
	SSL_CTX_free(client_ctx);		/* 200411 */
	return (0);
    }

    /*
     * We do not need a client certificate, so the certificates are only
     * loaded (and checked) if supplied. A clever client would handle
     * multiple client certificates and decide based on the list of
     * acceptable CAs, sent by the server, which certificate to submit.
     * OpenSSL does however not do this and also has no call-back hooks to
     * easily implement it.
     * 
     * Load the client public key certificate and private key from file and
     * check whether the cert matches the key. We can use RSA certificates
     * ("cert") DSA certificates ("dcert") or ECDSA certificates ("eccert").
     * All three can be made available at the same time. The CA certificates
     * for all three are handled in the same setup already finished. Which
     * one is used depends on the cipher negotiated (that is: the first
     * cipher listed by the client which does match the server). The client
     * certificate is presented after the server chooses the session cipher,
     * so we will just present the right cert for the chosen cipher (if it
     * uses certificates).
     */
    if (tls_set_my_certificate_key_info(client_ctx,
					props->cert_file,
					props->key_file,
					props->dcert_file,
					props->dkey_file,
					props->eccert_file,
					props->eckey_file) < 0) {
	/* tls_set_my_certificate_key_info() already logs a warning. */
	SSL_CTX_free(client_ctx);		/* 200411 */
	return (0);
    }

    /*
     * According to the OpenSSL documentation, temporary RSA key is needed
     * export ciphers are in use. We have to provide one, so well, we just do
     * it.
     */
    SSL_CTX_set_tmp_rsa_callback(client_ctx, tls_tmp_rsa_cb);

    /*
     * Finally, the setup for the server certificate checking, done "by the
     * book".
     */
    SSL_CTX_set_verify(client_ctx, SSL_VERIFY_NONE,
		       tls_verify_certificate_callback);

    /*
     * Initialize the session cache.
     * 
     * Since the client does not search an internal cache, we simply disable it.
     * It is only useful for expiring old sessions, but we do that in the
     * tlsmgr(8).
     * 
     * This makes SSL_CTX_remove_session() not useful for flushing broken
     * sessions from the external cache, so we must delete them directly (not
     * via a callback).
     */
    if (tls_mgr_policy(props->cache_type, &cachable,
		       &scache_timeout) != TLS_MGR_STAT_OK)
	scache_timeout = 0;
    if (scache_timeout <= 0)
	cachable = 0;

    /*
     * Allocate an application context, and populate with mandatory protocol
     * and cipher data.
     */
    app_ctx = tls_alloc_app_context(client_ctx, log_mask);

    /*
     * The external session cache is implemented by the tlsmgr(8) process.
     */
    if (cachable) {

	app_ctx->cache_type = mystrdup(props->cache_type);

	/*
	 * OpenSSL does not use callbacks to load sessions from a client
	 * cache, so we must invoke that function directly. Apparently,
	 * OpenSSL does not provide a way to pass session names from here to
	 * call-back routines that do session lookup.
	 * 
	 * OpenSSL can, however, automatically save newly created sessions for
	 * us by callback (we create the session name in the call-back
	 * function).
	 * 
	 * XXX gcc 2.95 can't compile #ifdef .. #endif in the expansion of
	 * SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL_STORE |
	 * SSL_SESS_CACHE_NO_AUTO_CLEAR.
	 */
#ifndef SSL_SESS_CACHE_NO_INTERNAL_STORE
#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0
#endif

	SSL_CTX_set_session_cache_mode(client_ctx,
				       SSL_SESS_CACHE_CLIENT |
				       SSL_SESS_CACHE_NO_INTERNAL_STORE |
				       SSL_SESS_CACHE_NO_AUTO_CLEAR);
	SSL_CTX_sess_set_new_cb(client_ctx, new_client_session_cb);

	/*
	 * OpenSSL ignores timed-out sessions. We need to set the internal
	 * cache timeout at least as high as the external cache timeout. This
	 * applies even if no internal cache is used.  We set the session to
	 * twice the cache lifetime.  This way a session always lasts longer
	 * than its lifetime in the cache.
	 */
	SSL_CTX_set_timeout(client_ctx, 2 * scache_timeout);
    }
    return (app_ctx);
}
예제 #25
0
static int test_large_message_tls_read_ahead(void)
{
    return execute_test_large_message(TLS_server_method(), TLS_client_method(),
                                      1);
}
예제 #26
0
as_status
as_tls_context_setup(as_config_tls* tlscfg, as_tls_context* ctx, as_error* errp)
{
	// Clear the destination, in case we don't make it.
	ctx->ssl_ctx = NULL;
	ctx->pkey = NULL;
	ctx->cert_blacklist = NULL;
	ctx->log_session_info = tlscfg->log_session_info;
	ctx->for_login_only = tlscfg->for_login_only;

	as_tls_check_init();
	pthread_mutex_init(&ctx->lock, NULL);

	if (tlscfg->cert_blacklist) {
		ctx->cert_blacklist = cert_blacklist_read(tlscfg->cert_blacklist);

		if (! ctx->cert_blacklist) {
			as_tls_context_destroy(ctx);
			return as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR,
								   "Failed to read certificate blacklist: %s",
								   tlscfg->cert_blacklist);
		}
	}
	
	uint16_t protocols = AS_TLS_PROTOCOL_NONE;
	as_status status = protocols_parse(tlscfg, &protocols, errp);

	if (status != AEROSPIKE_OK) {
		as_tls_context_destroy(ctx);
		return status;
	}

	const SSL_METHOD* method = NULL;

	// If the selected protocol set is a single protocol we can use a specific method.
	if (protocols == AS_TLS_PROTOCOL_TLSV1) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
		method = TLS_client_method();
#else
		method = TLSv1_client_method();
#endif
	}
	else if (protocols == AS_TLS_PROTOCOL_TLSV1_1) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
		method = TLS_client_method();
#else
		method = TLSv1_1_client_method();
#endif
	}
	else if (protocols == AS_TLS_PROTOCOL_TLSV1_2) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
		method = TLS_client_method();
#else
		method = TLSv1_2_client_method();
#endif
	}
	else {
		// Multiple protocols are enabled, use a flexible method.
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
		method = TLS_client_method();
#else
		method = SSLv23_client_method();
#endif
	}

	ctx->ssl_ctx = SSL_CTX_new(method);

	if (ctx->ssl_ctx == NULL) {
		as_tls_context_destroy(ctx);

		unsigned long errcode = ERR_get_error();
		char errbuf[1024];
		ERR_error_string_n(errcode, errbuf, sizeof(errbuf));
		return as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR,
							   "Failed to create new TLS context: %s", errbuf);
	}

	/* always disable SSLv2, as per RFC 6176 */
    SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2);
	SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv3);

	// Turn off non-enabled protocols.
	if (! (protocols & AS_TLS_PROTOCOL_TLSV1)) {
        SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1);
    }
	if (! (protocols & AS_TLS_PROTOCOL_TLSV1_1)) {
        SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_1);
    }
	if (! (protocols & AS_TLS_PROTOCOL_TLSV1_2)) {
        SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_TLSv1_2);
    }
	
	if (tlscfg->cafile || tlscfg->capath) {
		int rv = SSL_CTX_load_verify_locations(ctx->ssl_ctx, tlscfg->cafile, tlscfg->capath);

		if (rv != 1) {
			as_tls_context_destroy(ctx);

			char errbuf[1024];
			unsigned long errcode = ERR_get_error();

			if (errcode != 0) {
				ERR_error_string_n(errcode, errbuf, sizeof(errbuf));
				return as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR,
									   "Failed to load CAFile: %s", errbuf);
			}
			return as_error_set_message(errp, AEROSPIKE_ERR_TLS_ERROR,
										"Unknown failure loading CAFile");
		}
	}

	if (tlscfg->certfile) {
		int rv = SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, tlscfg->certfile);

		if (rv != 1) {
			// We seem to be seeing this bug:
			// https://groups.google.com/
			//          forum/#!topic/mailing.openssl.users/nRvRzmKnEQA
			// If the rv is not 1 check the error stack; if it doesn't have an
			// error assume we are OK.
			//
			unsigned long errcode = ERR_peek_error();

			if (errcode != SSL_ERROR_NONE) {
				// There *was* an error after all.
				as_tls_context_destroy(ctx);

				unsigned long errcode = ERR_get_error();
				char errbuf[1024];
				ERR_error_string_n(errcode, errbuf, sizeof(errbuf));
				return as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR,
									   "SSL_CTX_use_certificate_chain_file failed: %s",
									   errbuf);
			}
		}
	}

	if (tlscfg->keyfile) {
		bool ok = false;
		FILE *fh = fopen(tlscfg->keyfile, "r");

		if (fh == NULL) {
			as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR,
					"failed to open key file %s: %s", tlscfg->keyfile,
					strerror(errno));
		}
		else {
			EVP_PKEY *pkey = PEM_read_PrivateKey(fh, NULL, password_cb,
					tlscfg->keyfile_pw);

			if (pkey == NULL) {
				unsigned long errcode = ERR_get_error();

				if (ERR_GET_REASON(errcode) == PEM_R_BAD_PASSWORD_READ) {
					if (tlscfg->keyfile_pw == NULL) {
						as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR,
								"key file %s requires a password",
								tlscfg->keyfile);
					}
					else {
						as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR,
								"password for key file %s too long",
								tlscfg->keyfile);
					}
				}
				else if (ERR_GET_REASON(errcode) == EVP_R_BAD_DECRYPT) {
					as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR,
							"invalid password for key file %s",
							tlscfg->keyfile);
				}
				else {
					char errbuf[1024];
					ERR_error_string_n(errcode, errbuf, sizeof(errbuf));
					as_error_update(errp, AEROSPIKE_ERR_TLS_ERROR,
							"PEM_read_PrivateKey failed: %s", errbuf);
				}
			}
			else {
				ctx->pkey = pkey;
				SSL_CTX_use_PrivateKey(ctx->ssl_ctx, pkey);
				ok = true;
			}

			fclose(fh);
		}

		if (!ok) {
			as_tls_context_destroy(ctx);
			return AEROSPIKE_ERR_TLS_ERROR;
		}
	}

	if (tlscfg->cipher_suite) {
		int rv = SSL_CTX_set_cipher_list(ctx->ssl_ctx, tlscfg->cipher_suite);

		if (rv != 1) {
			as_tls_context_destroy(ctx);
			return as_error_set_message(errp, AEROSPIKE_ERR_TLS_ERROR,
										"no compatible cipher found");
		}
		// It's bogus that we have to create an SSL just to get the
		// cipher list, but SSL_CTX_get_ciphers doesn't appear to
		// exist ...
		SSL* ssl = SSL_new(ctx->ssl_ctx);

		for (int prio = 0; true; ++prio) {
			char const * cipherstr = SSL_get_cipher_list(ssl, prio);
			if (!cipherstr) {
				break;
			}
			as_log_info("cipher %d: %s", prio+1, cipherstr);
		}
		SSL_free(ssl);
	}

	if (tlscfg->crl_check || tlscfg->crl_check_all) {
		X509_VERIFY_PARAM* param = X509_VERIFY_PARAM_new();
		unsigned long flags = X509_V_FLAG_CRL_CHECK;

		if (tlscfg->crl_check_all) {
			flags |= X509_V_FLAG_CRL_CHECK_ALL;
		}

		X509_VERIFY_PARAM_set_flags(param, flags);
		SSL_CTX_set1_param(ctx->ssl_ctx, param);
		X509_VERIFY_PARAM_free(param);
	}

	SSL_CTX_set_verify(ctx->ssl_ctx, SSL_VERIFY_PEER, verify_callback);
	manage_sigpipe();
	return AEROSPIKE_OK;
}
예제 #27
0
static int execute_test_session(SSL_SESSION_TEST_FIXTURE fix)
{
    SSL_CTX *sctx = NULL, *cctx = NULL;
    SSL *serverssl1 = NULL, *clientssl1 = NULL;
    SSL *serverssl2 = NULL, *clientssl2 = NULL;
#ifndef OPENSSL_NO_TLS1_1
    SSL *serverssl3 = NULL, *clientssl3 = NULL;
#endif
    SSL_SESSION *sess1 = NULL, *sess2 = NULL;
    int testresult = 0;

    if (!create_ssl_ctx_pair(TLS_server_method(), TLS_client_method(), &sctx,
                             &cctx, cert, privkey)) {
        printf("Unable to create SSL_CTX pair\n");
        return 0;
    }

#ifndef OPENSSL_NO_TLS1_2
    /* Only allow TLS1.2 so we can force a connection failure later */
    SSL_CTX_set_min_proto_version(cctx, TLS1_2_VERSION);
#endif

    /* Set up session cache */
    if (fix.use_ext_cache) {
        SSL_CTX_sess_set_new_cb(cctx, new_session_cb);
        SSL_CTX_sess_set_remove_cb(cctx, remove_session_cb);
    }
    if (fix.use_int_cache) {
        /* Also covers instance where both are set */
        SSL_CTX_set_session_cache_mode(cctx, SSL_SESS_CACHE_CLIENT);
    } else {
        SSL_CTX_set_session_cache_mode(cctx,
                                       SSL_SESS_CACHE_CLIENT
                                       | SSL_SESS_CACHE_NO_INTERNAL_STORE);
    }

    if (!create_ssl_objects(sctx, cctx, &serverssl1, &clientssl1, NULL,
                               NULL)) {
        printf("Unable to create SSL objects\n");
        goto end;
    }

    if (!create_ssl_connection(serverssl1, clientssl1)) {
        printf("Unable to create SSL connection\n");
        goto end;
    }
    sess1 = SSL_get1_session(clientssl1);
    if (sess1 == NULL) {
        printf("Unexpected NULL session\n");
        goto end;
    }

    if (fix.use_int_cache && SSL_CTX_add_session(cctx, sess1)) {
        /* Should have failed because it should already be in the cache */
        printf("Unexpected success adding session to cache\n");
        goto end;
    }

    if (fix.use_ext_cache && (new_called != 1 || remove_called != 0)) {
        printf("Session not added to cache\n");
        goto end;
    }

    if (!create_ssl_objects(sctx, cctx, &serverssl2, &clientssl2, NULL, NULL)) {
        printf("Unable to create second SSL objects\n");
        goto end;
    }

    if (!create_ssl_connection(serverssl2, clientssl2)) {
        printf("Unable to create second SSL connection\n");
        goto end;
    }

    sess2 = SSL_get1_session(clientssl2);
    if (sess2 == NULL) {
        printf("Unexpected NULL session from clientssl2\n");
        goto end;
    }

    if (fix.use_ext_cache && (new_called != 2 || remove_called != 0)) {
        printf("Remove session callback unexpectedly called\n");
        goto end;
    }

    /*
     * This should clear sess2 from the cache because it is a "bad" session. See
     * SSL_set_session() documentation.
     */
    if (!SSL_set_session(clientssl2, sess1)) {
        printf("Unexpected failure setting session\n");
        goto end;
    }

    if (fix.use_ext_cache && (new_called != 2 || remove_called != 1)) {
        printf("Failed to call callback to remove session\n");
        goto end;
    }


    if (SSL_get_session(clientssl2) != sess1) {
        printf("Unexpected session found\n");
        goto end;
    }

    if (fix.use_int_cache) {
        if (!SSL_CTX_add_session(cctx, sess2)) {
            /*
             * Should have succeeded because it should not already be in the cache
             */
            printf("Unexpected failure adding session to cache\n");
            goto end;
        }

        if (!SSL_CTX_remove_session(cctx, sess2)) {
            printf("Unexpected failure removing session from cache\n");
            goto end;
        }

        /* This is for the purposes of internal cache testing...ignore the
         * counter for external cache
         */
        if (fix.use_ext_cache)
            remove_called--;
    }

    /* This shouldn't be in the cache so should fail */
    if (SSL_CTX_remove_session(cctx, sess2)) {
        printf("Unexpected success removing session from cache\n");
        goto end;
    }

    if (fix.use_ext_cache && (new_called != 2 || remove_called != 2)) {
        printf("Failed to call callback to remove session #2\n");
        goto end;
    }

#if !defined(OPENSSL_NO_TLS1_1) && !defined(OPENSSL_NO_TLS1_2)
    /* Force a connection failure */
    SSL_CTX_set_max_proto_version(sctx, TLS1_1_VERSION);

    if (!create_ssl_objects(sctx, cctx, &serverssl3, &clientssl3, NULL, NULL)) {
        printf("Unable to create third SSL objects\n");
        goto end;
    }

    if (!SSL_set_session(clientssl3, sess1)) {
        printf("Unable to set session for third connection\n");
        goto end;
    }

    /* This should fail because of the mismatched protocol versions */
    if (create_ssl_connection(serverssl3, clientssl3)) {
        printf("Unable to create third SSL connection\n");
        goto end;
    }


    /* We should have automatically removed the session from the cache */
    if (fix.use_ext_cache && (new_called != 2 || remove_called != 3)) {
        printf("Failed to call callback to remove session #2\n");
        goto end;
    }

    if (fix.use_int_cache && !SSL_CTX_add_session(cctx, sess2)) {
        /*
         * Should have succeeded because it should not already be in the cache
         */
        printf("Unexpected failure adding session to cache #2\n");
        goto end;
    }
#endif

    testresult = 1;

 end:
    SSL_free(serverssl1);
    SSL_free(clientssl1);
    SSL_free(serverssl2);
    SSL_free(clientssl2);
#ifndef OPENSSL_NO_TLS1_1
    SSL_free(serverssl3);
    SSL_free(clientssl3);
#endif
    SSL_SESSION_free(sess1);
    SSL_SESSION_free(sess2);
    /*
     * Check if we need to remove any sessions up-refed for the external cache
     */
    if (new_called >= 1)
        SSL_SESSION_free(sess1);
    if (new_called >= 2)
        SSL_SESSION_free(sess2);
    SSL_CTX_free(sctx);
    SSL_CTX_free(cctx);

    return testresult;
}
예제 #28
0
파일: sconnect.c 프로젝트: Ana06/openssl
int main(int argc, char *argv[])
{
    const char *hostport = HOSTPORT;
    const char *CAfile = CAFILE;
    char *hostname;
    char *cp;
    BIO *out = NULL;
    char buf[1024 * 10], *p;
    SSL_CTX *ssl_ctx = NULL;
    SSL *ssl;
    BIO *ssl_bio;
    int i, len, off, ret = EXIT_FAILURE;

    if (argc > 1)
        hostport = argv[1];
    if (argc > 2)
        CAfile = argv[2];

    hostname = OPENSSL_strdup(hostport);
    if ((cp = strchr(hostname, ':')) != NULL)
        *cp = 0;

#ifdef WATT32
    dbug_init();
    sock_init();
#endif

    ssl_ctx = SSL_CTX_new(TLS_client_method());

    /* Enable trust chain verification */
    SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
    SSL_CTX_load_verify_locations(ssl_ctx, CAfile, NULL);

    /* Lets make a SSL structure */
    ssl = SSL_new(ssl_ctx);
    SSL_set_connect_state(ssl);

    /* Enable peername verification */
    if (SSL_set1_host(ssl, hostname) <= 0)
        goto err;

    /* Use it inside an SSL BIO */
    ssl_bio = BIO_new(BIO_f_ssl());
    BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE);

    /* Lets use a connect BIO under the SSL BIO */
    out = BIO_new(BIO_s_connect());
    BIO_set_conn_hostname(out, hostport);
    BIO_set_nbio(out, 1);
    out = BIO_push(ssl_bio, out);

    p = "GET / HTTP/1.0\r\n\r\n";
    len = strlen(p);

    off = 0;
    for (;;) {
        i = BIO_write(out, &(p[off]), len);
        if (i <= 0) {
            if (BIO_should_retry(out)) {
                fprintf(stderr, "write DELAY\n");
                sleep(1);
                continue;
            } else {
                goto err;
            }
        }
        off += i;
        len -= i;
        if (len <= 0)
            break;
    }

    for (;;) {
        i = BIO_read(out, buf, sizeof(buf));
        if (i == 0)
            break;
        if (i < 0) {
            if (BIO_should_retry(out)) {
                fprintf(stderr, "read DELAY\n");
                sleep(1);
                continue;
            }
            goto err;
        }
        fwrite(buf, 1, i, stdout);
    }

    ret = EXIT_SUCCESS;
    goto done;

 err:
    if (ERR_peek_error() == 0) { /* system call error */
        fprintf(stderr, "errno=%d ", errno);
        perror("error");
    } else {
        ERR_print_errors_fp(stderr);
    }
 done:
    BIO_free_all(out);
    SSL_CTX_free(ssl_ctx);
    return ret;
}
예제 #29
0
int s_time_main(int argc, char **argv)
{
    char buf[1024 * 8];
    SSL *scon = NULL;
    SSL_CTX *ctx = NULL;
    const SSL_METHOD *meth = NULL;
    char *CApath = NULL, *CAfile = NULL, *cipher = NULL, *ciphersuites = NULL;
    char *www_path = NULL;
    char *host = SSL_CONNECT_NAME, *certfile = NULL, *keyfile = NULL, *prog;
    double totalTime = 0.0;
    int noCApath = 0, noCAfile = 0;
    int maxtime = SECONDS, nConn = 0, perform = 3, ret = 1, i, st_bugs = 0;
    long bytes_read = 0, finishtime = 0;
    OPTION_CHOICE o;
    int max_version = 0, ver, buf_len;
    size_t buf_size;

    meth = TLS_client_method();

    prog = opt_init(argc, argv, s_time_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(s_time_options);
            ret = 0;
            goto end;
        case OPT_CONNECT:
            host = opt_arg();
            break;
        case OPT_REUSE:
            perform = 2;
            break;
        case OPT_NEW:
            perform = 1;
            break;
        case OPT_VERIFY:
            if (!opt_int(opt_arg(), &verify_args.depth))
                goto opthelp;
            BIO_printf(bio_err, "%s: verify depth is %d\n",
                       prog, verify_args.depth);
            break;
        case OPT_CERT:
            certfile = opt_arg();
            break;
        case OPT_NAMEOPT:
            if (!set_nameopt(opt_arg()))
                goto end;
            break;
        case OPT_KEY:
            keyfile = opt_arg();
            break;
        case OPT_CAPATH:
            CApath = opt_arg();
            break;
        case OPT_CAFILE:
            CAfile = opt_arg();
            break;
        case OPT_NOCAPATH:
            noCApath = 1;
            break;
        case OPT_NOCAFILE:
            noCAfile = 1;
            break;
        case OPT_CIPHER:
            cipher = opt_arg();
            break;
        case OPT_CIPHERSUITES:
            ciphersuites = opt_arg();
            break;
        case OPT_BUGS:
            st_bugs = 1;
            break;
        case OPT_TIME:
            if (!opt_int(opt_arg(), &maxtime))
                goto opthelp;
            break;
        case OPT_WWW:
            www_path = opt_arg();
            buf_size = strlen(www_path) + fmt_http_get_cmd_size;
            if (buf_size > sizeof(buf)) {
                BIO_printf(bio_err, "%s: -www option is too long\n", prog);
                goto end;
            }
            break;
        case OPT_SSL3:
            max_version = SSL3_VERSION;
            break;
        }
    }
    argc = opt_num_rest();
    if (argc != 0)
        goto opthelp;

    if (cipher == NULL)
        cipher = getenv("SSL_CIPHER");

    if ((ctx = SSL_CTX_new(meth)) == NULL)
        goto end;

    SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
    SSL_CTX_set_quiet_shutdown(ctx, 1);
    if (SSL_CTX_set_max_proto_version(ctx, max_version) == 0)
        goto end;

    if (st_bugs)
        SSL_CTX_set_options(ctx, SSL_OP_ALL);
    if (cipher != NULL && !SSL_CTX_set_cipher_list(ctx, cipher))
        goto end;
    if (ciphersuites != NULL && !SSL_CTX_set_ciphersuites(ctx, ciphersuites))
        goto end;
    if (!set_cert_stuff(ctx, certfile, keyfile))
        goto end;

    if (!ctx_set_verify_locations(ctx, CAfile, CApath, noCAfile, noCApath)) {
        ERR_print_errors(bio_err);
        goto end;
    }
    if (!(perform & 1))
        goto next;
    printf("Collecting connection statistics for %d seconds\n", maxtime);

    /* Loop and time how long it takes to make connections */

    bytes_read = 0;
    finishtime = (long)time(NULL) + maxtime;
    tm_Time_F(START);
    for (;;) {
        if (finishtime < (long)time(NULL))
            break;

        if ((scon = doConnection(NULL, host, ctx)) == NULL)
            goto end;

        if (www_path != NULL) {
            buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd,
                                   www_path);
            if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0)
                goto end;
            while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
                bytes_read += i;
        }
        SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
        BIO_closesocket(SSL_get_fd(scon));

        nConn += 1;
        if (SSL_session_reused(scon)) {
            ver = 'r';
        } else {
            ver = SSL_version(scon);
            if (ver == TLS1_VERSION)
                ver = 't';
            else if (ver == SSL3_VERSION)
                ver = '3';
            else
                ver = '*';
        }
        fputc(ver, stdout);
        fflush(stdout);

        SSL_free(scon);
        scon = NULL;
    }
    totalTime += tm_Time_F(STOP); /* Add the time for this iteration */

    i = (int)((long)time(NULL) - finishtime + maxtime);
    printf
        ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
         nConn, totalTime, ((double)nConn / totalTime), bytes_read);
    printf
        ("%d connections in %ld real seconds, %ld bytes read per connection\n",
         nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);

    /*
     * Now loop and time connections using the same session id over and over
     */

 next:
    if (!(perform & 2))
        goto end;
    printf("\n\nNow timing with session id reuse.\n");

    /* Get an SSL object so we can reuse the session id */
    if ((scon = doConnection(NULL, host, ctx)) == NULL) {
        BIO_printf(bio_err, "Unable to get connection\n");
        goto end;
    }

    if (www_path != NULL) {
        buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd, www_path);
        if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0)
            goto end;
        while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
            continue;
    }
    SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
    BIO_closesocket(SSL_get_fd(scon));

    nConn = 0;
    totalTime = 0.0;

    finishtime = (long)time(NULL) + maxtime;

    printf("starting\n");
    bytes_read = 0;
    tm_Time_F(START);

    for (;;) {
        if (finishtime < (long)time(NULL))
            break;

        if ((doConnection(scon, host, ctx)) == NULL)
            goto end;

        if (www_path != NULL) {
            buf_len = BIO_snprintf(buf, sizeof(buf), fmt_http_get_cmd,
                                   www_path);
            if (buf_len <= 0 || SSL_write(scon, buf, buf_len) <= 0)
                goto end;
            while ((i = SSL_read(scon, buf, sizeof(buf))) > 0)
                bytes_read += i;
        }
        SSL_set_shutdown(scon, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
        BIO_closesocket(SSL_get_fd(scon));

        nConn += 1;
        if (SSL_session_reused(scon)) {
            ver = 'r';
        } else {
            ver = SSL_version(scon);
            if (ver == TLS1_VERSION)
                ver = 't';
            else if (ver == SSL3_VERSION)
                ver = '3';
            else
                ver = '*';
        }
        fputc(ver, stdout);
        fflush(stdout);
    }
    totalTime += tm_Time_F(STOP); /* Add the time for this iteration */

    printf
        ("\n\n%d connections in %.2fs; %.2f connections/user sec, bytes read %ld\n",
         nConn, totalTime, ((double)nConn / totalTime), bytes_read);
    printf
        ("%d connections in %ld real seconds, %ld bytes read per connection\n",
         nConn, (long)time(NULL) - finishtime + maxtime, bytes_read / nConn);

    ret = 0;

 end:
    SSL_free(scon);
    SSL_CTX_free(ctx);
    return ret;
}
예제 #30
0
BOOL connect_ssl(int sockfd, 
    const char* ca_crt_root,
    const char* ca_crt_client,
    const char* ca_password,
    const char* ca_key_client,
    SSL** pp_ssl, SSL_CTX** pp_ssl_ctx)
{
    SSL_METHOD* meth = NULL;
#if OPENSSL_VERSION_NUMBER >= 0x010100000L
    meth = (SSL_METHOD*)TLS_client_method();
#else
    meth = (SSL_METHOD*)SSLv23_client_method();
#endif /* OPENSSL_VERSION_NUMBER */
        
    *pp_ssl_ctx = SSL_CTX_new(meth);

    if(!*pp_ssl_ctx)
    {
        CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME);
        uTrace.Write(Trace_Error, "SSL_CTX_new: %s\n", ERR_error_string(ERR_get_error(),NULL));
        goto clean_ssl3;
    }

    if(ca_crt_root && ca_crt_client && ca_password && ca_key_client)
    {
        SSL_CTX_load_verify_locations(*pp_ssl_ctx, ca_crt_root, NULL);
        if(SSL_CTX_use_certificate_file(*pp_ssl_ctx, ca_crt_client, SSL_FILETYPE_PEM) <= 0)
        {
            CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME);
            uTrace.Write(Trace_Error, "SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(),NULL));
            goto clean_ssl2;
        }

        SSL_CTX_set_default_passwd_cb_userdata(*pp_ssl_ctx, (char*)ca_password);
        if(SSL_CTX_use_PrivateKey_file(*pp_ssl_ctx, ca_key_client, SSL_FILETYPE_PEM) <= 0)
        {
            CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME);
            uTrace.Write(Trace_Error, "SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(),NULL));
            goto clean_ssl2;

        }
        
        if(!SSL_CTX_check_private_key(*pp_ssl_ctx))
        {
            CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME);
            uTrace.Write(Trace_Error, "SSL_CTX_use_certificate_file: %s", ERR_error_string(ERR_get_error(),NULL));
            goto clean_ssl2;
        }
    }
    
    *pp_ssl = SSL_new(*pp_ssl_ctx);
    if(!*pp_ssl)
    {
        CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME);
        uTrace.Write(Trace_Error, "SSL_new: %s\n", ERR_error_string(ERR_get_error(),NULL));
        goto clean_ssl2;
    }
    
    if(SSL_set_fd(*pp_ssl, sockfd) <= 0)
    {
        CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME);
        uTrace.Write(Trace_Error, "SSL_set_fd: %s\n", ERR_error_string(ERR_get_error(),NULL));
        goto clean_ssl1;
    }
    
    if(SSL_connect(*pp_ssl) <= 0)
    {
        CUplusTrace uTrace(SSLERR_LOGNAME, SSLERR_LCKNAME);
        uTrace.Write(Trace_Error, "SSL_connect: %s\n", ERR_error_string(ERR_get_error(),NULL));
        goto clean_ssl1;
    }
        
    return TRUE;

clean_ssl1:
    if(*pp_ssl)
    {
		SSL_free(*pp_ssl);
        *pp_ssl = NULL;
    }
clean_ssl2:
    if(*pp_ssl_ctx)
    {
		SSL_CTX_free(*pp_ssl_ctx);
        *pp_ssl_ctx = NULL;
    }
clean_ssl3:
    return FALSE;
}