Example #1
0
static int ssl_setup(git_transport *t, const char *host)
{
	int ret;

	SSL_library_init();
	SSL_load_error_strings();
	t->ssl.ctx = SSL_CTX_new(SSLv23_method());
	if (t->ssl.ctx == NULL)
		return ssl_set_error(&t->ssl, 0);

	SSL_CTX_set_mode(t->ssl.ctx, SSL_MODE_AUTO_RETRY);
	SSL_CTX_set_verify(t->ssl.ctx, SSL_VERIFY_PEER, NULL);
	if (!SSL_CTX_set_default_verify_paths(t->ssl.ctx))
		return ssl_set_error(&t->ssl, 0);

	t->ssl.ssl = SSL_new(t->ssl.ctx);
	if (t->ssl.ssl == NULL)
		return ssl_set_error(&t->ssl, 0);

	if((ret = SSL_set_fd(t->ssl.ssl, t->socket)) == 0)
		return ssl_set_error(&t->ssl, ret);

	if ((ret = SSL_connect(t->ssl.ssl)) <= 0)
		return ssl_set_error(&t->ssl, ret);

	if (t->check_cert && verify_server_cert(t, host) < 0)
		return -1;

	return 0;
}
Example #2
0
File: netops.c Project: aep/libgit2
static int ssl_setup(gitno_socket *socket, const char *host, int flags)
{
	int ret;

	SSL_library_init();
	SSL_load_error_strings();
	socket->ssl.ctx = SSL_CTX_new(SSLv23_method());
	if (socket->ssl.ctx == NULL)
		return ssl_set_error(&socket->ssl, 0);

	SSL_CTX_set_mode(socket->ssl.ctx, SSL_MODE_AUTO_RETRY);
	SSL_CTX_set_verify(socket->ssl.ctx, SSL_VERIFY_NONE, NULL);
	if (!SSL_CTX_set_default_verify_paths(socket->ssl.ctx))
		return ssl_set_error(&socket->ssl, 0);

	socket->ssl.ssl = SSL_new(socket->ssl.ctx);
	if (socket->ssl.ssl == NULL)
		return ssl_set_error(&socket->ssl, 0);

	if((ret = SSL_set_fd(socket->ssl.ssl, socket->socket)) == 0)
		return ssl_set_error(&socket->ssl, ret);

	if ((ret = SSL_connect(socket->ssl.ssl)) <= 0)
		return ssl_set_error(&socket->ssl, ret);

	if (GITNO_CONNECT_SSL_NO_CHECK_CERT & flags)
		return 0;

	return verify_server_cert(&socket->ssl, host);
}
Example #3
0
int openssl_connect(git_stream *stream)
{
	int ret;
	BIO *bio;
	openssl_stream *st = (openssl_stream *) stream;

	if ((ret = git_stream_connect(st->io)) < 0)
		return ret;

	st->connected = true;

	bio = BIO_new(&git_stream_bio_method);
	GITERR_CHECK_ALLOC(bio);
	bio->ptr = st->io;

	SSL_set_bio(st->ssl, bio, bio);
	/* specify the host in case SNI is needed */
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
	SSL_set_tlsext_host_name(st->ssl, st->host);
#endif

	if ((ret = SSL_connect(st->ssl)) <= 0)
		return ssl_set_error(st->ssl, ret);

	return verify_server_cert(st->ssl, st->host);
}
int openssl_connect(git_stream *stream)
{
	int ret;
	openssl_stream *st = (openssl_stream *) stream;

	if ((ret = git_stream_connect((git_stream *)st->socket)) < 0)
		return ret;

	if ((ret = SSL_set_fd(st->ssl, st->socket->s)) <= 0) {
		openssl_close((git_stream *) st);
		return ssl_set_error(st->ssl, ret);
	}

	if ((ret = SSL_connect(st->ssl)) <= 0)
		return ssl_set_error(st->ssl, ret);

	return verify_server_cert(st->ssl, st->socket->host);
}
Example #5
0
ssize_t openssl_read(git_stream *stream, void *data, size_t len)
{
	openssl_stream *st = (openssl_stream *) stream;
	int ret;

	if ((ret = SSL_read(st->ssl, data, len)) <= 0)
		ssl_set_error(st->ssl, ret);

	return ret;
}
Example #6
0
static int ssl_teardown(SSL *ssl)
{
	int ret;

	ret = SSL_shutdown(ssl);
	if (ret < 0)
		ret = ssl_set_error(ssl, ret);
	else
		ret = 0;

	return ret;
}
Example #7
0
int openssl_connect(git_stream *stream)
{
	int ret;
	openssl_stream *st = (openssl_stream *) stream;

	if ((ret = git_stream_connect((git_stream *)st->socket)) < 0)
		return ret;

	if ((ret = SSL_set_fd(st->ssl, st->socket->s)) <= 0) {
		openssl_close((git_stream *) st);
		return ssl_set_error(st->ssl, ret);
	}

	/* specify the host in case SNI is needed */
	SSL_set_tlsext_host_name(st->ssl, st->socket->host);

	if ((ret = SSL_connect(st->ssl)) <= 0)
		return ssl_set_error(st->ssl, ret);

	return verify_server_cert(st->ssl, st->socket->host);
}
Example #8
0
ssize_t openssl_write(git_stream *stream, const char *data, size_t len, int flags)
{
	openssl_stream *st = (openssl_stream *) stream;
	int ret;

	GIT_UNUSED(flags);

	if ((ret = SSL_write(st->ssl, data, len)) <= 0) {
		return ssl_set_error(st->ssl, ret);
	}

	return ret;
}
Example #9
0
static int ssl_recv(gitno_ssl *ssl, void *data, size_t len)
{
	int ret;

	do {
		ret = SSL_read(ssl->ssl, data, len);
	} while (SSL_get_error(ssl->ssl, ret) == SSL_ERROR_WANT_READ);

	if (ret < 0)
		return ssl_set_error(ssl, ret);

	return ret;
}
Example #10
0
File: netops.c Project: aep/libgit2
static int gitno_ssl_teardown(gitno_ssl *ssl)
{
	int ret;

	ret = SSL_shutdown(ssl->ssl);
	if (ret < 0)
		ret = ssl_set_error(ssl, ret);
	else
		ret = 0;

	SSL_free(ssl->ssl);
	SSL_CTX_free(ssl->ctx);
	return ret;
}
Example #11
0
static int send_ssl(gitno_ssl *ssl, const char *msg, size_t len)
{
	int ret;
	size_t off = 0;

	while (off < len) {
		ret = SSL_write(ssl->ssl, msg + off, len - off);
		if (ret <= 0)
			return ssl_set_error(ssl, ret);

		off += ret;
	}

	return off;
}
ssize_t openssl_read(git_stream *stream, void *data, size_t len)
{
	openssl_stream *st = (openssl_stream *) stream;
	int ret;

	do {
		ret = SSL_read(st->ssl, data, len);
	} while (SSL_get_error(st->ssl, ret) == SSL_ERROR_WANT_READ);

	if (ret < 0) {
		ssl_set_error(st->ssl, ret);
		return -1;
	}

	return ret;
}
Example #13
0
File: netops.c Project: aep/libgit2
static int gitno_send_ssl(gitno_ssl *ssl, const char *msg, size_t len, int flags)
{
	int ret;
	size_t off = 0;

	GIT_UNUSED(flags);

	while (off < len) {
		ret = SSL_write(ssl->ssl, msg + off, len - off);
		if (ret <= 0 && ret != SSL_ERROR_WANT_WRITE)
			return ssl_set_error(ssl, ret);

		off += ret;
	}	

	return off;
}
ssize_t openssl_write(git_stream *stream, const char *data, size_t len, int flags)
{
	openssl_stream *st = (openssl_stream *) stream;
	int ret;
	size_t off = 0;

	GIT_UNUSED(flags);

	while (off < len) {
		ret = SSL_write(st->ssl, data + off, len - off);
		if (ret <= 0 && ret != SSL_ERROR_WANT_WRITE)
			return ssl_set_error(st->ssl, ret);

		off += ret;
	}	

	return off;
}
Example #15
0
int gitno_ssl_teardown(git_transport *t)
{
#ifdef GIT_SSL
	int ret;
#endif

	if (!t->use_ssl)
		return 0;

#ifdef GIT_SSL

	do {
		ret = SSL_shutdown(t->ssl.ssl);
	} while (ret == 0);
	if (ret < 0)
		return ssl_set_error(&t->ssl, ret);

	SSL_free(t->ssl.ssl);
	SSL_CTX_free(t->ssl.ctx);
#endif
	return 0;
}
Example #16
0
static int verify_server_cert(SSL *ssl, const char *host)
{
	X509 *cert;
	X509_NAME *peer_name;
	ASN1_STRING *str;
	unsigned char *peer_cn = NULL;
	int matched = -1, type = GEN_DNS;
	GENERAL_NAMES *alts;
	struct in6_addr addr6;
	struct in_addr addr4;
	void *addr;
	int i = -1,j;

	if (SSL_get_verify_result(ssl) != X509_V_OK) {
		giterr_set(GITERR_SSL, "The SSL certificate is invalid");
		return GIT_ECERTIFICATE;
	}

	/* Try to parse the host as an IP address to see if it is */
	if (p_inet_pton(AF_INET, host, &addr4)) {
		type = GEN_IPADD;
		addr = &addr4;
	} else {
		if(p_inet_pton(AF_INET6, host, &addr6)) {
			type = GEN_IPADD;
			addr = &addr6;
		}
	}


	cert = SSL_get_peer_certificate(ssl);
	if (!cert) {
		giterr_set(GITERR_SSL, "the server did not provide a certificate");
		return -1;
	}

	/* Check the alternative names */
	alts = X509_get_ext_d2i(cert, NID_subject_alt_name, NULL, NULL);
	if (alts) {
		int num;

		num = sk_GENERAL_NAME_num(alts);
		for (i = 0; i < num && matched != 1; i++) {
			const GENERAL_NAME *gn = sk_GENERAL_NAME_value(alts, i);
			const char *name = (char *) ASN1_STRING_data(gn->d.ia5);
			size_t namelen = (size_t) ASN1_STRING_length(gn->d.ia5);

			/* Skip any names of a type we're not looking for */
			if (gn->type != type)
				continue;

			if (type == GEN_DNS) {
				/* If it contains embedded NULs, don't even try */
				if (memchr(name, '\0', namelen))
					continue;

				if (check_host_name(name, host) < 0)
					matched = 0;
				else
					matched = 1;
			} else if (type == GEN_IPADD) {
				/* Here name isn't so much a name but a binary representation of the IP */
				matched = !!memcmp(name, addr, namelen);
			}
		}
	}
	GENERAL_NAMES_free(alts);

	if (matched == 0)
		goto cert_fail_name;

	if (matched == 1)
		return 0;

	/* If no alternative names are available, check the common name */
	peer_name = X509_get_subject_name(cert);
	if (peer_name == NULL)
		goto on_error;

	if (peer_name) {
		/* Get the index of the last CN entry */
		while ((j = X509_NAME_get_index_by_NID(peer_name, NID_commonName, i)) >= 0)
			i = j;
	}

	if (i < 0)
		goto on_error;

	str = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(peer_name, i));
	if (str == NULL)
		goto on_error;

	/* Work around a bug in OpenSSL whereby ASN1_STRING_to_UTF8 fails if it's already in utf-8 */
	if (ASN1_STRING_type(str) == V_ASN1_UTF8STRING) {
		int size = ASN1_STRING_length(str);

		if (size > 0) {
			peer_cn = OPENSSL_malloc(size + 1);
			GITERR_CHECK_ALLOC(peer_cn);
			memcpy(peer_cn, ASN1_STRING_data(str), size);
			peer_cn[size] = '\0';
		} else {
			goto cert_fail_name;
		}
	} else {
		int size = ASN1_STRING_to_UTF8(&peer_cn, str);
		GITERR_CHECK_ALLOC(peer_cn);
		if (memchr(peer_cn, '\0', size))
			goto cert_fail_name;
	}

	if (check_host_name((char *)peer_cn, host) < 0)
		goto cert_fail_name;

	OPENSSL_free(peer_cn);

	return 0;

on_error:
	OPENSSL_free(peer_cn);
	return ssl_set_error(ssl, 0);

cert_fail_name:
	OPENSSL_free(peer_cn);
	giterr_set(GITERR_SSL, "hostname does not match certificate");
	return GIT_ECERTIFICATE;
}