예제 #1
0
/**
 * \brief do TLS negotiation with client application
 * \param[in]	*C	The context of verse server
 * \return This function returns 1, when TLS connection was established and
 * it returns 0, when TLS was not established.
 */
int vs_TLS_handshake(struct vContext *C)
{
	struct VS_CTX *vs_ctx = CTX_server_ctx(C);
	struct IO_CTX *io_ctx = CTX_io_ctx(C);
	struct VStreamConn *stream_conn = CTX_current_stream_conn(C);

	int flag, ret;

	/* Make sure socket is blocking */
	flag = fcntl(stream_conn->io_ctx.sockfd, F_GETFL, 0);
	if( (fcntl(stream_conn->io_ctx.sockfd, F_SETFL, flag & ~O_NONBLOCK)) == -1) {
		if(is_log_level(VRS_PRINT_ERROR)) v_print_log(VRS_PRINT_ERROR, "fcntl(): %s\n", strerror(errno));
		return 0;
	}

	/* Set up SSL */
	if( (stream_conn->io_ctx.ssl = SSL_new(vs_ctx->tls_ctx)) == NULL) {
		v_print_log(VRS_PRINT_ERROR, "Setting up SSL failed.\n");
		ERR_print_errors_fp(v_log_file());
		SSL_free(stream_conn->io_ctx.ssl);
		stream_conn->io_ctx.ssl = NULL;
		close(io_ctx->sockfd);
		return 0;
	}

	/* Bind socket and SSL */
	if (SSL_set_fd(stream_conn->io_ctx.ssl, io_ctx->sockfd) == 0) {
		v_print_log(VRS_PRINT_ERROR, "Failed binding socket descriptor and SSL.\n");
		ERR_print_errors_fp(v_log_file());
		SSL_free(stream_conn->io_ctx.ssl);
		stream_conn->io_ctx.ssl = NULL;
		close(io_ctx->sockfd);
		return 0;
	}

	SSL_set_mode(stream_conn->io_ctx.ssl, SSL_MODE_AUTO_RETRY);

	/* Do TLS handshake and negotiation */
	if( (ret = SSL_accept(stream_conn->io_ctx.ssl)) != 1) {
		int err = SSL_get_error(stream_conn->io_ctx.ssl, ret);
		v_print_log(VRS_PRINT_ERROR, "SSL handshake failed: %d -> %d\n", ret, err);
		ERR_print_errors_fp(v_log_file());
		SSL_free(stream_conn->io_ctx.ssl);
		stream_conn->io_ctx.ssl = NULL;
		close(io_ctx->sockfd);
		return 0;
	}

	v_print_log(VRS_PRINT_DEBUG_MSG, "SSL handshake succeed.\n");
	return 1;
}
예제 #2
0
파일: vs_main.c 프로젝트: GitReinDa/verse
/**
 * \brief This function sets debug level of verse server.
 */
static int vs_set_debug_level(char *debug_level)
{
	FILE *log_file = v_log_file();

	if( strcmp(debug_level, "debug") == 0) {
		v_init_print_log(VRS_PRINT_DEBUG_MSG, log_file);
		return 1;
	} else if( strcmp(debug_level, "warning") == 0 ) {
		v_init_print_log(VRS_PRINT_WARNING, log_file);
		return 1;
	} else if( strcmp(debug_level, "error") == 0 ) {
		v_init_print_log(VRS_PRINT_ERROR, log_file);
		return 1;
	} else if( strcmp(debug_level, "info") == 0 ) {
		v_init_print_log(VRS_PRINT_INFO, log_file);
		return 1;
	} else if( strcmp(debug_level, "none") == 0 ) {
		v_init_print_log(VRS_PRINT_NONE, log_file);
		return 1;
	} else {
		v_print_log(VRS_PRINT_ERROR, "Unsupported debug level: %s\n", debug_level);
		return 0;
	}
}
예제 #3
0
파일: vs_tcp_connect.c 프로젝트: ged/verse
/*
 * \brief Initialize OpenSSl of Verse server
 */
static int vs_init_ssl(VS_CTX *vs_ctx)
{
	/* Set up the library */
	SSL_library_init();
	ERR_load_BIO_strings();
	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();

	/* Set up SSL context for TLS  */
	if( (vs_ctx->tls_ctx = SSL_CTX_new(TLSv1_server_method())) == NULL ) {
		v_print_log(VRS_PRINT_ERROR, "Setting up SSL_CTX failed.\n");
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Load certificate chain file from CA */
	if(vs_ctx->ca_cert_file != NULL) {
		if(SSL_CTX_use_certificate_chain_file(vs_ctx->tls_ctx, vs_ctx->ca_cert_file) != 1) {
			v_print_log(VRS_PRINT_ERROR, "TLS: Loading certificate chain file: %s failed.\n",
					vs_ctx->ca_cert_file);
			ERR_print_errors_fp(v_log_file());
			return -1;
		}
	}

	/* Load certificate with public key for TLS */
	if(SSL_CTX_use_certificate_file(vs_ctx->tls_ctx, vs_ctx->public_cert_file, SSL_FILETYPE_PEM) != 1) {
		v_print_log(VRS_PRINT_ERROR, "TLS: Loading certificate file: %s failed.\n",
				vs_ctx->public_cert_file);
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Load private key for TLS */
	if(SSL_CTX_use_PrivateKey_file(vs_ctx->tls_ctx, vs_ctx->private_cert_file, SSL_FILETYPE_PEM) != 1) {
		v_print_log(VRS_PRINT_ERROR, "TLS: Loading private key file: %s failed.\n",
				vs_ctx->private_cert_file);
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Check the consistency of a private key with the corresponding
	 * certificate loaded into ssl_ctx */
	if(SSL_CTX_check_private_key(vs_ctx->tls_ctx) != 1) {
		v_print_log(VRS_PRINT_ERROR, "TLS: Private key does not match the certificate public key\n");
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* When CA certificate file was set, then try to load it */
	if(vs_ctx->ca_cert_file != NULL) {
		if(SSL_CTX_load_verify_locations(vs_ctx->tls_ctx, vs_ctx->ca_cert_file, NULL) != 1) {
			v_print_log(VRS_PRINT_ERROR, "TLS: Loading CA certificate file: %s failed.\n",
					vs_ctx->ca_cert_file);
			ERR_print_errors_fp(v_log_file());
			return -1;
		}
	}

#if OPENSSL_VERSION_NUMBER>=0x10000000

	/* Set up SSL context for DTLS  */
	if( (vs_ctx->dtls_ctx = SSL_CTX_new(DTLSv1_server_method())) == NULL ) {
		v_print_log(VRS_PRINT_ERROR, "Setting up SSL_CTX failed.\n");
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Load certificate chain file from CA */
	if(vs_ctx->ca_cert_file != NULL) {
		if(SSL_CTX_use_certificate_chain_file(vs_ctx->dtls_ctx, vs_ctx->ca_cert_file) != 1) {
			v_print_log(VRS_PRINT_ERROR, "DTLS: Loading certificate chain file: %s failed.\n",
					vs_ctx->ca_cert_file);
			ERR_print_errors_fp(v_log_file());
			return -1;
		}
	}

	/* Load certificate with public key for DTLS */
	if (SSL_CTX_use_certificate_file(vs_ctx->dtls_ctx, vs_ctx->public_cert_file, SSL_FILETYPE_PEM) != 1) {
		v_print_log(VRS_PRINT_ERROR, "DTLS: Loading certificate file: %s failed.\n",
						vs_ctx->public_cert_file);
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Load private key for DTLS */
	if(SSL_CTX_use_PrivateKey_file(vs_ctx->dtls_ctx, vs_ctx->private_cert_file, SSL_FILETYPE_PEM) != 1) {
		v_print_log(VRS_PRINT_ERROR, "DTLS: Loading private key file: %s failed.\n",
						vs_ctx->private_cert_file);
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* Check the consistency of a private key with the corresponding
	 * certificate loaded into ssl_ctx */
	if(SSL_CTX_check_private_key(vs_ctx->dtls_ctx) != 1) {
		v_print_log(VRS_PRINT_ERROR, "DTLS: Private key does not match the certificate public key\n");
		ERR_print_errors_fp(v_log_file());
		return -1;
	}

	/* When CA certificate file was set, then try to load it */
	if(vs_ctx->ca_cert_file != NULL) {
		if(SSL_CTX_load_verify_locations(vs_ctx->dtls_ctx, vs_ctx->ca_cert_file, NULL) != 1) {
			v_print_log(VRS_PRINT_ERROR, "DTLS: Loading CA certificate file: %s failed.\n",
					vs_ctx->ca_cert_file);
			ERR_print_errors_fp(v_log_file());
			return -1;
		}
	}

	/* Set up callback functions for DTLS cookie */
	SSL_CTX_set_cookie_generate_cb(vs_ctx->dtls_ctx, vs_dtls_generate_cookie);
	SSL_CTX_set_cookie_verify_cb(vs_ctx->dtls_ctx, vs_dtls_verify_cookie);
	/* Accept all cipher including NULL cipher (testing) */
	if( SSL_CTX_set_cipher_list(vs_ctx->dtls_ctx, "ALL:NULL:eNULL:aNULL") == 0) {
		v_print_log(VRS_PRINT_ERROR, "Setting ciphers for DTLS failed.\n");
		ERR_print_errors_fp(v_log_file());
		return 0;
	}
	/* DTLS require this */
	SSL_CTX_set_read_ahead(vs_ctx->dtls_ctx, 1);
#else
	vs_ctx->dtls_ctx = NULL;
#endif

	return 1;
}
예제 #4
0
파일: vc_main.c 프로젝트: GitReinDa/verse
/**
 * \brief Initialize verse client context
 */
int vc_init_ctx(struct VC_CTX *vc_ctx)
{
	int i;

	/* Allocate memory for session slots and make session slots NULL */
	vc_ctx->vsessions = (struct VSession**)malloc(sizeof(struct VSession*)*vc_ctx->max_sessions);
	vc_ctx->session_counter = 0;
	for(i=0; i<vc_ctx->max_sessions; i++) {
		vc_ctx->vsessions[i] = NULL;
	}
	/* Initialize callback function */
	vc_init_func_storage(&vc_ctx->vfs);

#ifdef WITH_OPENSSL
	/* Set up the library */
	SSL_library_init();
	ERR_load_BIO_strings();
	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();

	/* Set up SSL context for TLS */
	if( (vc_ctx->tls_ctx = SSL_CTX_new(TLSv1_client_method())) == NULL ) {
		v_print_log(VRS_PRINT_ERROR, "Setting up SSL_CTX for TLS failed.\n");
		ERR_print_errors_fp(v_log_file());
		return 0;
	}

	/* Load the trust store for TLS */
	if(SSL_CTX_load_verify_locations(vc_ctx->tls_ctx, NULL, vc_ctx->ca_path) != 1) {
		v_print_log(VRS_PRINT_ERROR, "Loading path with CA certificates failed.\n");
		ERR_print_errors_fp(v_log_file());
	} else {
		v_print_log(VRS_PRINT_DEBUG_MSG, "Path %s with CA certificates loaded successfully.\n",
				vc_ctx->ca_path);
	}
#endif

#if (defined WITH_OPENSSL) && OPENSSL_VERSION_NUMBER>=0x10000000
	/* Set up SSL context for DTSL */
	if( (vc_ctx->dtls_ctx = SSL_CTX_new(DTLSv1_client_method())) == NULL ) {
		v_print_log(VRS_PRINT_ERROR, "Setting up SSL_CTX for DTLS failed.\n");
		ERR_print_errors_fp(v_log_file());
		return 0;
	}

	/* Load the trust store for DTLS */
	if(SSL_CTX_load_verify_locations(vc_ctx->dtls_ctx, NULL, vc_ctx->ca_path) != 1) {
		v_print_log(VRS_PRINT_ERROR, "Loading path with CA certificates failed.\n");
		ERR_print_errors_fp(v_log_file());
	} else {
		v_print_log(VRS_PRINT_DEBUG_MSG, "Path %s with CA certificates loaded successfully.\n",
				vc_ctx->ca_path);
	}

	/* Negotiate ciphers with server
	 * For testing: (encryption:none, mac:sha) eNULL:!MDP5
	 * For real use: ALL:ALL */
	if( SSL_CTX_set_cipher_list(vc_ctx->dtls_ctx, "eNULL:!MD5") == 0) {
		v_print_log(VRS_PRINT_ERROR, "Setting ciphers for DTLS failed.\n");
		ERR_print_errors_fp(v_log_file());
		return 0;
	}

	/* This is necessary for DTLS */
	SSL_CTX_set_read_ahead(vc_ctx->dtls_ctx, 1);
#else
	vc_ctx->dtls_ctx = NULL;
#endif

	/* Default name and version */
	vc_ctx->client_name = NULL;
	vc_ctx->client_version = NULL;

	pthread_mutex_init(&vc_ctx->mutex, NULL);

	return 1;
}