/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#ifdef GIT_SECURE_TRANSPORT

#include <CoreFoundation/CoreFoundation.h>
#include <Security/SecureTransport.h>
#include <Security/SecCertificate.h>

#include "git2/transport.h"

#include "socket_stream.h"
#include "curl_stream.h"

static int stransport_error(OSStatus ret)
{
	CFStringRef message;

	if (ret == noErr || ret == errSSLClosedGraceful) {
		giterr_clear();
		return 0;
	}

#if !TARGET_OS_IPHONE
	message = SecCopyErrorMessageString(ret, NULL);
	GITERR_CHECK_ALLOC(message);

	giterr_set(GITERR_NET, "SecureTransport error: %s", CFStringGetCStringPtr(message, kCFStringEncodingUTF8));
	CFRelease(message);
#else
    giterr_set(GITERR_NET, "SecureTransport error: OSStatus %d", (unsigned int)ret);
    GIT_UNUSED(message);
#endif

	return -1;
}

typedef struct {
	git_stream parent;
	git_stream *io;
	SSLContextRef ctx;
	CFDataRef der_data;
	git_cert_x509 cert_info;
} stransport_stream;

static int stransport_connect(git_stream *stream)
{
	stransport_stream *st = (stransport_stream *) stream;
	int error;
	SecTrustRef trust = NULL;
	SecTrustResultType sec_res;
	OSStatus ret;

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

	ret = SSLHandshake(st->ctx);
	if (ret != errSSLServerAuthCompleted) {
		giterr_set(GITERR_SSL, "unexpected return value from ssl handshake %d", ret);
		return -1;
	}

	if ((ret = SSLCopyPeerTrust(st->ctx, &trust)) != noErr)
		goto on_error;

	if (!trust)
		return GIT_ECERTIFICATE;

	if ((ret = SecTrustEvaluate(trust, &sec_res)) != noErr)
		goto on_error;

	CFRelease(trust);

	if (sec_res == kSecTrustResultInvalid || sec_res == kSecTrustResultOtherError) {
		giterr_set(GITERR_SSL, "internal security trust error");
		return -1;
	}

	if (sec_res == kSecTrustResultDeny || sec_res == kSecTrustResultRecoverableTrustFailure ||
	    sec_res == kSecTrustResultFatalTrustFailure)
		return GIT_ECERTIFICATE;

	return 0;

on_error:
	if (trust)
		CFRelease(trust);

	return stransport_error(ret);
}

static int stransport_certificate(git_cert **out, git_stream *stream)
{
	stransport_stream *st = (stransport_stream *) stream;
	SecTrustRef trust = NULL;
	SecCertificateRef sec_cert;
	OSStatus ret;

	if ((ret = SSLCopyPeerTrust(st->ctx, &trust)) != noErr)
		return stransport_error(ret);

	sec_cert = SecTrustGetCertificateAtIndex(trust, 0);
	st->der_data = SecCertificateCopyData(sec_cert);
	CFRelease(trust);

	if (st->der_data == NULL) {
		giterr_set(GITERR_SSL, "retrieved invalid certificate data");
		return -1;
	}

	st->cert_info.parent.cert_type = GIT_CERT_X509;
	st->cert_info.data = (void *) CFDataGetBytePtr(st->der_data);
	st->cert_info.len = CFDataGetLength(st->der_data);

	*out = (git_cert *)&st->cert_info;
	return 0;
}

static int stransport_set_proxy(
	git_stream *stream,
	const git_proxy_options *proxy_opts)
{
	stransport_stream *st = (stransport_stream *) stream;

	return git_stream_set_proxy(st->io, proxy_opts);
}

/*
 * Contrary to typical network IO callbacks, Secure Transport write callback is
 * expected to write *all* passed data, not just as much as it can, and any
 * other case would be considered a failure.
 *
 * This behavior is actually not specified in the Apple documentation, but is
 * required for things to work correctly (and incidentally, that's also how
 * Apple implements it in its projects at opensource.apple.com).
 *
 * Libgit2 streams happen to already have this very behavior so this is just
 * passthrough.
 */
static OSStatus write_cb(SSLConnectionRef conn, const void *data, size_t *len)
{
	git_stream *io = (git_stream *) conn;

	if (git_stream_write(io, data, *len, 0) < 0) {
		return -36; /* "ioErr" from MacErrors.h which is not available on iOS */
	}

	return noErr;
}

static ssize_t stransport_write(git_stream *stream, const char *data, size_t len, int flags)
{
	stransport_stream *st = (stransport_stream *) stream;
	size_t data_len, processed;
	OSStatus ret;

	GIT_UNUSED(flags);

	data_len = len;
	if ((ret = SSLWrite(st->ctx, data, data_len, &processed)) != noErr)
		return stransport_error(ret);

	return processed;
}

/*
 * Contrary to typical network IO callbacks, Secure Transport read callback is
 * expected to read *exactly* the requested number of bytes, not just as much
 * as it can, and any other case would be considered a failure.
 *
 * This behavior is actually not specified in the Apple documentation, but is
 * required for things to work correctly (and incidentally, that's also how
 * Apple implements it in its projects at opensource.apple.com).
 */
static OSStatus read_cb(SSLConnectionRef conn, void *data, size_t *len)
{
	git_stream *io = (git_stream *) conn;
	OSStatus error = noErr;
	size_t off = 0;
	ssize_t ret;

	do {
		ret = git_stream_read(io, data + off, *len - off);
		if (ret < 0) {
			error = -36; /* "ioErr" from MacErrors.h which is not available on iOS */
			break;
		}
		if (ret == 0) {
			error = errSSLClosedGraceful;
			break;
		}

		off += ret;
	} while (off < *len);

	*len = off;
	return error;
}

static ssize_t stransport_read(git_stream *stream, void *data, size_t len)
{
	stransport_stream *st = (stransport_stream *) stream;
	size_t processed;
	OSStatus ret;

	if ((ret = SSLRead(st->ctx, data, len, &processed)) != noErr)
		return stransport_error(ret);

	return processed;
}

static int stransport_close(git_stream *stream)
{
	stransport_stream *st = (stransport_stream *) stream;
	OSStatus ret;

	ret = SSLClose(st->ctx);
	if (ret != noErr && ret != errSSLClosedGraceful)
		return stransport_error(ret);

	return git_stream_close(st->io);
}

static void stransport_free(git_stream *stream)
{
	stransport_stream *st = (stransport_stream *) stream;

	git_stream_free(st->io);
	CFRelease(st->ctx);
	if (st->der_data)
		CFRelease(st->der_data);
	git__free(st);
}

int git_stransport_stream_new(git_stream **out, const char *host, const char *port)
{
	stransport_stream *st;
	int error;
	OSStatus ret;

	assert(out && host);

	st = git__calloc(1, sizeof(stransport_stream));
	GITERR_CHECK_ALLOC(st);

#ifdef GIT_CURL
	error = git_curl_stream_new(&st->io, host, port);
#else
	error = git_socket_stream_new(&st->io, host, port);
#endif

	if (error < 0){
		git__free(st);
		return error;
	}

	st->ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
	if (!st->ctx) {
		giterr_set(GITERR_NET, "failed to create SSL context");
		git__free(st);
		return -1;
	}

	if ((ret = SSLSetIOFuncs(st->ctx, read_cb, write_cb)) != noErr ||
	    (ret = SSLSetConnection(st->ctx, st->io)) != noErr ||
	    (ret = SSLSetSessionOption(st->ctx, kSSLSessionOptionBreakOnServerAuth, true)) != noErr ||
	    (ret = SSLSetProtocolVersionMin(st->ctx, kTLSProtocol1)) != noErr ||
	    (ret = SSLSetProtocolVersionMax(st->ctx, kTLSProtocol12)) != noErr ||
	    (ret = SSLSetPeerDomainName(st->ctx, host, strlen(host))) != noErr) {
		CFRelease(st->ctx);
		git__free(st);
		return stransport_error(ret);
	}

	st->parent.version = GIT_STREAM_VERSION;
	st->parent.encrypted = 1;
	st->parent.proxy_support = git_stream_supports_proxy(st->io);
	st->parent.connect = stransport_connect;
	st->parent.certificate = stransport_certificate;
	st->parent.set_proxy = stransport_set_proxy;
	st->parent.read = stransport_read;
	st->parent.write = stransport_write;
	st->parent.close = stransport_close;
	st->parent.free = stransport_free;

	*out = (git_stream *) st;
	return 0;
}

#endif
