Ejemplo n.º 1
0
int ssl_open(http_t *client, char *msg)
{
	char buf[256];
	const char *sn;
	X509 *cert;

	if (!client->ssl_enabled)
		return tcp_init(&client->tcp, msg);

	tcp_set_port(&client->tcp, HTTPS_DEFAULT_PORT);
	DO(tcp_init(&client->tcp, msg));

	logit(LOG_INFO, "%s, initiating HTTPS ...", msg);
	client->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
	if (!client->ssl_ctx)
		return RC_HTTPS_OUT_OF_MEMORY;

	/* POODLE, only allow TLSv1.x or later */
	SSL_CTX_set_options(client->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION);

	SSL_CTX_set_verify(client->ssl_ctx, SSL_VERIFY_PEER, verify_callback);
	SSL_CTX_set_verify_depth(client->ssl_ctx, 150);

	/* Try to figure out location of trusted CA certs on system */
	if (ssl_set_ca_location(client))
		return RC_HTTPS_NO_TRUSTED_CA_STORE;

	client->ssl = SSL_new(client->ssl_ctx);
	if (!client->ssl)
		return RC_HTTPS_OUT_OF_MEMORY;

	/* SSL SNI support: tell the servername we want to speak to */
	http_get_remote_name(client, &sn);
	if (!SSL_set_tlsext_host_name(client->ssl, sn))
		return RC_HTTPS_SNI_ERROR;

	SSL_set_fd(client->ssl, client->tcp.ip.socket);
	if (-1 == SSL_connect(client->ssl))
		return RC_HTTPS_FAILED_CONNECT;

	logit(LOG_INFO, "SSL connection using %s", SSL_get_cipher(client->ssl));

	cert = SSL_get_peer_certificate(client->ssl);
	if (!cert)
		return RC_HTTPS_FAILED_GETTING_CERT;

	if (SSL_get_verify_result(client->ssl) == X509_V_OK)
		logit(LOG_DEBUG, "Certificate OK");

	X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
	logit(LOG_INFO, "SSL server cert subject: %s", buf);
	X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
	logit(LOG_INFO, "SSL server cert issuer: %s", buf);

	X509_free(cert);

	return 0;
}
Ejemplo n.º 2
0
int ssl_open(http_t *client, char *msg)
{
	char buf[256];
	const char *sn;
	const X509 *cert;

	if (!client->ssl_enabled)
		return tcp_init(&client->tcp, msg);

	tcp_set_port(&client->tcp, 443);
	DO(tcp_init(&client->tcp, msg));

	logit(LOG_INFO, "%s, initiating HTTPS ...", msg);
	client->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
	if (!client->ssl_ctx)
		return RC_HTTPS_OUT_OF_MEMORY;

	client->ssl = SSL_new(client->ssl_ctx);
	if (!client->ssl)
		return RC_HTTPS_OUT_OF_MEMORY;

	/* SSL SNI support: tell the servername we want to speak to */
	http_get_remote_name(client, &sn);
	if (gnutls_server_name_set(client->ssl->gnutls_state, GNUTLS_NAME_DNS, sn, strlen(sn)))
		return RC_HTTPS_SNI_ERROR;

	SSL_set_fd(client->ssl, client->tcp.ip.socket);
	if (-1 == SSL_connect(client->ssl))
		return RC_HTTPS_FAILED_CONNECT;

	logit(LOG_INFO, "SSL connection using %s", SSL_get_cipher(client->ssl));

	/* Get server's certificate (note: beware of dynamic allocation) - opt */
	cert = SSL_get_peer_certificate(client->ssl);
	if (!cert)
		return RC_HTTPS_FAILED_GETTING_CERT;

	/* Logging some cert details. Please note: X509_NAME_oneline doesn't
	   work when giving NULL instead of a buffer. */
	X509_NAME_oneline(X509_get_subject_name(cert), buf, sizeof(buf));
	logit(LOG_INFO, "SSL server cert subject: %s", buf);
	X509_NAME_oneline(X509_get_issuer_name(cert), buf, sizeof(buf));
	logit(LOG_INFO, "SSL server cert issuer: %s", buf);

	/* We could do all sorts of certificate verification stuff here before
	   deallocating the certificate. */
	X509_free(cert);

	return 0;
}
Ejemplo n.º 3
0
int ssl_open(http_t *client, char *msg)
{
	int ret;
	char buf[256];
	size_t len;
	const char *sn, *err;
	const gnutls_datum_t *cert_list;
	unsigned int cert_list_size = 0;
	gnutls_x509_crt_t cert;

	if (!client->ssl_enabled)
		return tcp_init(&client->tcp, msg);

	/* Initialize TLS session */
	logit(LOG_INFO, "%s, initiating HTTPS ...", msg);
	gnutls_init(&client->ssl, GNUTLS_CLIENT);

	/* SSL SNI support: tell the servername we want to speak to */
	http_get_remote_name(client, &sn);
	gnutls_session_set_ptr(client->ssl, (void *)sn);
	if (gnutls_server_name_set(client->ssl, GNUTLS_NAME_DNS, sn, strlen(sn)))
		return RC_HTTPS_SNI_ERROR;

	/* Use default priorities */
	ret = gnutls_priority_set_direct(client->ssl, "NORMAL", &err);
	if (ret < 0) {
		if (ret == GNUTLS_E_INVALID_REQUEST)
			logit(LOG_ERR, "Syntax error at: %s", err);

		return RC_HTTPS_INVALID_REQUEST;
	}

	/* put the x509 credentials to the current session */
	gnutls_credentials_set(client->ssl, GNUTLS_CRD_CERTIFICATE, xcred);

	/* connect to the peer */
	tcp_set_port(&client->tcp, HTTPS_DEFAULT_PORT);
	DO(tcp_init(&client->tcp, msg));

	/* Forward TCP socket to GnuTLS, the set_int() API is perhaps too new still ... since 3.1.9 */
//	gnutls_transport_set_int(client->ssl, client->tcp.ip.socket);
	gnutls_transport_set_ptr(client->ssl, (gnutls_transport_ptr_t)(intptr_t)client->tcp.ip.socket);

	/* Perform the TLS handshake, ignore non-fatal errors. */
	do {
		ret = gnutls_handshake(client->ssl);
	}
	while (ret != 0 && !gnutls_error_is_fatal(ret));

	if (gnutls_error_is_fatal(ret)) {
		logit(LOG_ERR, "SSL handshake with %s failed: %s", sn, gnutls_strerror(ret));
		return RC_HTTPS_FAILED_CONNECT;
	}

	ssl_get_info(client);

	/* Get server's certificate (note: beware of dynamic allocation) - opt */
	cert_list = gnutls_certificate_get_peers(client->ssl, &cert_list_size);
	if (cert_list_size > 0) {
		if (gnutls_x509_crt_init(&cert))
			return RC_HTTPS_FAILED_GETTING_CERT;

		gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER);

		len = sizeof(buf);
		gnutls_x509_crt_get_dn(cert, buf, &len);
		logit(LOG_INFO, "SSL server cert subject: %s", buf);

		len = sizeof(buf);
		gnutls_x509_crt_get_issuer_dn(cert, buf, &len);
		logit(LOG_INFO, "SSL server cert issuer: %s", buf);

		gnutls_x509_crt_deinit(cert);
	}

	return 0;
}
Ejemplo n.º 4
0
RC_TYPE http_client_set_port(HTTP_CLIENT *p_self, int p)
{
	return tcp_set_port(&p_self->super, p);
}
Ejemplo n.º 5
0
int http_set_port(http_t *client, int port)
{
	ASSERT(client);
	return tcp_set_port(&client->tcp, port);
}