
%%{
#include <openssl/x509.h>
#include "zeek/Reporter.h"
#include "zeek/zeek-config.h"

#ifndef ENABLE_SPICY_SSL
#include "zeek/analyzer/protocol/ssl/SSL.h"
#endif
%%}

## Sets if the SSL analyzer should consider the connection established (handshake
## finished successfully).
##
## c: The SSL connection.
##
## Returns: T on success, F on failure.
function set_ssl_established%(c: connection%): bool
	%{
#ifndef ENABLE_SPICY_SSL
/* not implemented for Spicy ssl */
	zeek::analyzer::Analyzer* sa = c->FindAnalyzer("SSL");

	if ( sa )
		{
		static_cast<zeek::analyzer::ssl::SSL_Analyzer*>(sa)->StartEncryption();
		return zeek::val_mgr->True();
		}
#endif

	return zeek::val_mgr->False();
	%}

## Set the secret that should be used to derive keys for the connection.
## (For TLS 1.2 this is the pre-master secret).
##
## c: The affected connection
##
## secret: secret to set
##
## Returns: T on success, F on failure.
function set_secret%(c: connection, secret: string%): bool
	%{
#ifndef ENABLE_SPICY_SSL
/* not implemented for Spicy ssl */
	analyzer::Analyzer* sa = c->FindAnalyzer("SSL");

	if ( sa )
		{
		static_cast<zeek::analyzer::ssl::SSL_Analyzer*>(sa)->SetSecret(*secret);
		return zeek::val_mgr->True();
		}
#endif

	return zeek::val_mgr->False();
	%}

## Set the decryption keys that should be used to decrypt
## TLS application data in the connection.
##
## c: The affected connection
##
## keys: The key buffer as derived via TLS PRF.
##
## Returns: T on success, F on failure.
function set_keys%(c: connection, keys: string%): bool
	%{
#ifndef ENABLE_SPICY_SSL
/* not implemented for Spicy ssl */
	analyzer::Analyzer* sa = c->FindAnalyzer("SSL");

	if ( sa )
		{
		static_cast<zeek::analyzer::ssl::SSL_Analyzer*>(sa)->SetKeys(*keys);
		return zeek::val_mgr->True();
		}
#endif

	return zeek::val_mgr->False();
	%}

## Decodes a DER-encoded distinguished name into an ASCII string,
## using the RFC2253 representation
##
## dn: DER encoded distinguished name
##
## Returns: Ascii representation on success, empty string on failure
##
## .. zeek:see:: ssl_certificate_request
function parse_distinguished_name%(dn: string%): string
	%{
	const unsigned char* in = dn->Bytes();

	X509_NAME* dn_x509 = d2i_X509_NAME(nullptr, &in, dn->Len());
	if ( ! dn_x509 )
		{
		// we were not able to parse. Let's return an empty string.
		return zeek::make_intrusive<zeek::StringVal>("");
		}

	char buf[256];
	memset(buf, 0, sizeof(buf));
	BIO* bio = BIO_new(BIO_s_mem());

	X509_NAME_print_ex(bio, dn_x509, 0, XN_FLAG_RFC2253);
	int len = BIO_gets(bio, buf, sizeof(buf));
	auto out = zeek::make_intrusive<zeek::StringVal>(len, buf);
	BIO_free(bio);
	X509_NAME_free(dn_x509);
	return out;
	%}
