$OpenBSD: patch-src_ssli_openssl_c,v 1.3 2016/05/24 09:13:14 dcoppa Exp $

commit 82e80f8f18cbb6fed903621751ba9751dc2b80a2
Author: Felix Morgner <felix.morgner@gmail.com>
Date:   Sun Jul 12 15:01:07 2015 +0200

Use different API for reading TLS cert (fixes #64)

The OpenSSL TLS backend now reads the certificate file using
SSL_CTX_use_certificate_chain_file(...) so that concatenated
certificate files containing a verification chain are read correctly.

commit c72ebd29f239793218f2248c3f8b48a7b3e0a541
Author: Felix Morgner <felix.morgner@gmail.com>
Date:   Sun Mar 6 23:40:45 2016 +0100

Upgrade TLS suites for GnuTLS, mbedTLS and OpenSSL

I could not figure out whether or not PolarSSL, which is technically
now mbedTLS, does support ECDHE suites. I currently have no access to
PolarSSL myself. It would be great if somebody could figure that one
out. Relates to #82, fixes #84 and #77.

--- src/ssli_openssl.c.orig	Sat Jun 20 00:58:46 2015
+++ src/ssli_openssl.c	Tue May 24 10:19:22 2016
@@ -48,6 +48,8 @@ static RSA *rsa;
 static SSL_CTX *context;
 static EVP_PKEY *pkey;
 
+static char const * ciphers = "EECDH+AESGCM:AES256-SHA:AES128-SHA";
+
 static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx);
 
 static int SSL_add_ext(X509 * crt, int nid, char *value) {
@@ -154,106 +156,86 @@ static void SSL_writekey(char *keyfile, RSA *rsa)
 
 static void SSL_initializeCert() {
 
-	char *crt, *key, *pass;
+	char *crt = (char *)getStrConf(CERTIFICATE);
+	char *key = (char *)getStrConf(KEY);
 
-	crt = (char *)getStrConf(CERTIFICATE);
-	key = (char *)getStrConf(KEY);
-	pass = (char *)getStrConf(PASSPHRASE);
+	if (context) {
+		bool_t did_load_cert = SSL_CTX_use_certificate_chain_file(context, crt);
+		rsa = SSL_readprivatekey(key);
 
-	x509 = SSL_readcert(crt);
-	rsa = SSL_readprivatekey(key);
-	if (rsa != NULL) {
-		pkey = EVP_PKEY_new();
-		EVP_PKEY_assign_RSA(pkey, rsa);
-	}
+		if (!rsa || !did_load_cert) {
+			Log_info("Generating new server certificate.");
 
 
-#if 0
-	/* Later ... */
-	if (key && !x509) {
-		qscCert = QSslCertificate(key);
-		if (! qscCert.isNull()) {
-			logthis("Using certificate from key.");
-		}
-	}
+			CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
 
-	if (! qscCert.isNull()) {
-		QSsl::KeyAlgorithm alg = qscCert.publicKey().algorithm();
-		/* Fetch algorith from cert */
-		if (! key.isEmpty()) {
-			/* get key */
-			qskKey = QSslKey(key, alg, QSsl::Pem, QSsl::PrivateKey, pass);
-			if (qskKey.isNull()) {
-				logthis("Failed to parse key.");
-			}
-		}
+			x509 = X509_new();
+			pkey = EVP_PKEY_new();
+			rsa = RSA_generate_key(4096,RSA_F4,NULL,NULL);
+			EVP_PKEY_assign_RSA(pkey, rsa);
 
-		if (! crt.isEmpty() && qskKey.isNull()) {
-			/* get key from certificate */
-			qskKey = QSslKey(crt, alg, QSsl::Pem, QSsl::PrivateKey, pass);
-			if (! qskKey.isNull()) {
-				logthis("Using key from certificate.");
-			}
-		}
+			X509_set_version(x509, 2);
+			ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
+			X509_gmtime_adj(X509_get_notBefore(x509),0);
+			X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365);
+			X509_set_pubkey(x509, pkey);
 
-	}
-#endif
+			X509_NAME *name=X509_get_subject_name(x509);
 
-	if (!rsa || !x509) {
-		Log_info("Generating new server certificate.");
+			X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const uint8_t *)"Murmur Autogenerated Certificate v2", -1, -1, 0);
+			X509_set_issuer_name(x509, name);
+			SSL_add_ext(x509, NID_basic_constraints, "critical,CA:FALSE");
+			SSL_add_ext(x509, NID_ext_key_usage, "serverAuth,clientAuth");
+			SSL_add_ext(x509, NID_subject_key_identifier, "hash");
+			SSL_add_ext(x509, NID_netscape_comment, "Generated from umurmur");
 
+			X509_sign(x509, pkey, EVP_md5());
 
-		CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
+			SSL_writecert(crt, x509);
+			SSL_writekey(key, rsa);
 
-		x509 = X509_new();
-		pkey = EVP_PKEY_new();
-		rsa = RSA_generate_key(1024,RSA_F4,NULL,NULL);
-		EVP_PKEY_assign_RSA(pkey, rsa);
+			SSL_CTX_use_certificate(context, x509);
+		} else {
+		  pkey = EVP_PKEY_new();
+		  EVP_PKEY_assign_RSA(pkey, rsa);
+		}
 
-		X509_set_version(x509, 2);
-		ASN1_INTEGER_set(X509_get_serialNumber(x509),1);
-		X509_gmtime_adj(X509_get_notBefore(x509),0);
-		X509_gmtime_adj(X509_get_notAfter(x509),60*60*24*365);
-		X509_set_pubkey(x509, pkey);
+		SSL_CTX_use_PrivateKey(context, pkey);
 
-		X509_NAME *name=X509_get_subject_name(x509);
-
-		X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (const uint8_t *)"Murmur Autogenerated Certificate v2", -1, -1, 0);
-		X509_set_issuer_name(x509, name);
-		SSL_add_ext(x509, NID_basic_constraints, "critical,CA:FALSE");
-		SSL_add_ext(x509, NID_ext_key_usage, "serverAuth,clientAuth");
-		SSL_add_ext(x509, NID_subject_key_identifier, "hash");
-		SSL_add_ext(x509, NID_netscape_comment, "Generated from umurmur");
-
-		X509_sign(x509, pkey, EVP_md5());
-
-		SSL_writecert(crt, x509);
-		SSL_writekey(key, rsa);
+	} else {
+		Log_fatal("Failed to initialize TLS context.");
 	}
 
 }
 
 void SSLi_init(void)
 {
-	SSL_METHOD *method;
 	SSL *ssl;
 	int i, offset = 0, cipherstringlen = 0;
 	STACK_OF(SSL_CIPHER) *cipherlist = NULL, *cipherlist_new = NULL;
 	SSL_CIPHER *cipher;
-	char *cipherstring, tempstring[128];
+	char *cipherstring;
 
 	SSL_library_init();
-	OpenSSL_add_all_algorithms();		/* load & register all cryptos, etc. */
-	SSL_load_error_strings();			/* load all error messages */
-	ERR_load_crypto_strings();			/* load all error messages */
-	method = SSLv23_server_method();		/* create new server-method instance */
-	context = SSL_CTX_new(method);			/* create new context from method */
+	OpenSSL_add_all_algorithms();
+	SSL_load_error_strings();
+	ERR_load_crypto_strings();
+
+	context = SSL_CTX_new(SSLv23_server_method());
+	SSL_CTX_set_options(context, SSL_OP_NO_SSLv2);
+	SSL_CTX_set_options(context, SSL_OP_NO_SSLv3);
 	if (context == NULL)
 	{
 		ERR_print_errors_fp(stderr);
 		abort();
 	}
 
+	SSL_CTX_set_cipher_list(context, ciphers);
+
+	EC_KEY *ecdhkey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+	SSL_CTX_set_tmp_ecdh(context, ecdhkey);
+	EC_KEY_free(ecdhkey);
+
 	char const * sslCAPath = getStrConf(CAPATH);
 	if(sslCAPath != NULL)
 	{
@@ -261,12 +243,6 @@ void SSLi_init(void)
 	}
 
 	SSL_initializeCert();
-	if (SSL_CTX_use_certificate(context, x509) <= 0)
-		Log_fatal("Failed to initialize cert");
-	if (SSL_CTX_use_PrivateKey(context, pkey) <= 0) {
-		ERR_print_errors_fp(stderr);
-		Log_fatal("Failed to initialize private key");
-	}
 
 	/* Set cipher list */
 	ssl = SSL_new(context);
