summary refs log tree commit diff stats
path: root/src/common/ssl.c
diff options
context:
space:
mode:
authorTingPing <tngpng@gmail.com>2013-03-23 22:24:19 -0300
committerTingPing <tngpng@gmail.com>2013-03-23 22:24:19 -0300
commit84ffde7152dfe579700addce4ffaf29bc39eaa95 (patch)
tree5adf158c13b450c29a8072fb494b6ecd992d29eb /src/common/ssl.c
parent2c029f763c719138981b6fcf2de8ca621a083e4b (diff)
Be compatable with TLS
closes #461
Diffstat (limited to 'src/common/ssl.c')
-rw-r--r--src/common/ssl.c658
1 files changed, 329 insertions, 329 deletions
diff --git a/src/common/ssl.c b/src/common/ssl.c
index 75a81250..71fae87a 100644
--- a/src/common/ssl.c
+++ b/src/common/ssl.c
@@ -1,330 +1,330 @@
-/*
- * ssl.c v0.0.3
- * Copyright (C) 2000  --  DaP <profeta@freemail.c3.hu>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "inet.h"				  /* make it first to avoid macro redefinitions */
-#include <openssl/ssl.h>		  /* SSL_() */
-#include <openssl/err.h>		  /* ERR_() */
-#ifdef WIN32
-#include <openssl/rand.h>		  /* RAND_seed() */
-#include "../../config-win32.h"	  /* HAVE_SNPRINTF */
-#else
-#include "../../config.h"
-#endif
-#include <time.h>				  /* asctime() */
-#include <string.h>				  /* strncpy() */
-#include "ssl.h"				  /* struct cert_info */
-
-#ifndef HAVE_SNPRINTF
+/*

+ * ssl.c v0.0.3

+ * Copyright (C) 2000  --  DaP <profeta@freemail.c3.hu>

+ *

+ * This program is free software; you can redistribute it and/or modify

+ * it under the terms of the GNU General Public License as published by

+ * the Free Software Foundation; either version 2 of the License, or

+ * (at your option) any later version.

+ *

+ * This program is distributed in the hope that it will be useful,

+ * but WITHOUT ANY WARRANTY; without even the implied warranty of

+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the

+ * GNU General Public License for more details.

+ *

+ * You should have received a copy of the GNU General Public License

+ * along with this program; if not, write to the Free Software

+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA

+ */

+

+#include "inet.h"				  /* make it first to avoid macro redefinitions */

+#include <openssl/ssl.h>		  /* SSL_() */

+#include <openssl/err.h>		  /* ERR_() */

+#ifdef WIN32

+#include <openssl/rand.h>		  /* RAND_seed() */

+#include "../../config-win32.h"	  /* HAVE_SNPRINTF */

+#else

+#include "../../config.h"

+#endif

+#include <time.h>				  /* asctime() */

+#include <string.h>				  /* strncpy() */

+#include "ssl.h"				  /* struct cert_info */

+

+#ifndef HAVE_SNPRINTF

 #include <glib.h>

-#include <glib/gprintf.h>
-#define snprintf g_snprintf
-#endif
-
-/* globals */
-static struct chiper_info chiper_info;		/* static buffer for _SSL_get_cipher_info() */
-static char err_buf[256];			/* generic error buffer */
-
-
-/* +++++ Internal functions +++++ */
-
-static void
-__SSL_fill_err_buf (char *funcname)
-{
-	int err;
-	char buf[256];
-
-
-	err = ERR_get_error ();
-	ERR_error_string (err, buf);
-	snprintf (err_buf, sizeof (err_buf), "%s: %s (%d)\n", funcname, buf, err);
-}
-
-
-static void
-__SSL_critical_error (char *funcname)
-{
-	__SSL_fill_err_buf (funcname);
-	fprintf (stderr, "%s\n", err_buf);
-
-	exit (1);
-}
-
-/* +++++ SSL functions +++++ */
-
-SSL_CTX *
-_SSL_context_init (void (*info_cb_func), int server)
-{
-	SSL_CTX *ctx;
-#ifdef WIN32
-	int i, r;
-#endif
-
-	SSLeay_add_ssl_algorithms ();
-	SSL_load_error_strings ();
-	ctx = SSL_CTX_new (server ? SSLv3_server_method() : SSLv3_client_method ());
-
-	SSL_CTX_set_session_cache_mode (ctx, SSL_SESS_CACHE_BOTH);
-	SSL_CTX_set_timeout (ctx, 300);
-
-	/* used in SSL_connect(), SSL_accept() */
-	SSL_CTX_set_info_callback (ctx, info_cb_func);
-
-#ifdef WIN32
-	/* under win32, OpenSSL needs to be seeded with some randomness */
-	for (i = 0; i < 128; i++)
-	{
-		r = rand ();
-		RAND_seed ((unsigned char *)&r, sizeof (r));
-	}
-#endif
-
-	return(ctx);
-}
-
-static void
-ASN1_TIME_snprintf (char *buf, int buf_len, ASN1_TIME * tm)
-{
-	char *expires = NULL;
-	BIO *inMem = BIO_new (BIO_s_mem ());
-
-	ASN1_TIME_print (inMem, tm);
-	BIO_get_mem_data (inMem, &expires);
-	buf[0] = 0;
-	if (expires != NULL)
-	{
-		memset (buf, 0, buf_len);
-		strncpy (buf, expires, 24);
-	}
-	BIO_free (inMem);
-}
-
-
-static void
-broke_oneline (char *oneline, char *parray[])
-{
-	char *pt, *ppt;
-	int i;
-
-
-	i = 0;
-	ppt = pt = oneline + 1;
-	while ((pt = strchr (pt, '/')))
-	{
-		*pt = 0;
-		parray[i++] = ppt;
-		ppt = ++pt;
-	}
-	parray[i++] = ppt;
-	parray[i] = NULL;
-}
-
-
-/*
-    FIXME: Master-Key, Extensions, CA bits
-	    (openssl x509 -text -in servcert.pem)
-*/
-int
-_SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl)
-{
-	X509 *peer_cert;
-	EVP_PKEY *peer_pkey;
-	/* EVP_PKEY *ca_pkey; */
-	/* EVP_PKEY *tmp_pkey; */
-	char notBefore[64];
-	char notAfter[64];
-	int alg;
-	int sign_alg;
-
-
-	if (!(peer_cert = SSL_get_peer_certificate (ssl)))
-		return (1);				  /* FATAL? */
-
-	X509_NAME_oneline (X509_get_subject_name (peer_cert), cert_info->subject,
-							 sizeof (cert_info->subject));
-	X509_NAME_oneline (X509_get_issuer_name (peer_cert), cert_info->issuer,
-							 sizeof (cert_info->issuer));
-	broke_oneline (cert_info->subject, cert_info->subject_word);
-	broke_oneline (cert_info->issuer, cert_info->issuer_word);
-
-	alg = OBJ_obj2nid (peer_cert->cert_info->key->algor->algorithm);
-	sign_alg = OBJ_obj2nid (peer_cert->sig_alg->algorithm);
-	ASN1_TIME_snprintf (notBefore, sizeof (notBefore),
-							  X509_get_notBefore (peer_cert));
-	ASN1_TIME_snprintf (notAfter, sizeof (notAfter),
-							  X509_get_notAfter (peer_cert));
-
-	peer_pkey = X509_get_pubkey (peer_cert);
-
-	strncpy (cert_info->algorithm,
-				(alg == NID_undef) ? "Unknown" : OBJ_nid2ln (alg),
-				sizeof (cert_info->algorithm));
-	cert_info->algorithm_bits = EVP_PKEY_bits (peer_pkey);
-	strncpy (cert_info->sign_algorithm,
-				(sign_alg == NID_undef) ? "Unknown" : OBJ_nid2ln (sign_alg),
-				sizeof (cert_info->sign_algorithm));
-	/* EVP_PKEY_bits(ca_pkey)); */
-	cert_info->sign_algorithm_bits = 0;
-	strncpy (cert_info->notbefore, notBefore, sizeof (cert_info->notbefore));
-	strncpy (cert_info->notafter, notAfter, sizeof (cert_info->notafter));
-
-	EVP_PKEY_free (peer_pkey);
-
-	/* SSL_SESSION_print_fp(stdout, SSL_get_session(ssl)); */
-/*
-	if (ssl->session->sess_cert->peer_rsa_tmp) {
-		tmp_pkey = EVP_PKEY_new();
-		EVP_PKEY_assign_RSA(tmp_pkey, ssl->session->sess_cert->peer_rsa_tmp);
-		cert_info->rsa_tmp_bits = EVP_PKEY_bits (tmp_pkey);
-		EVP_PKEY_free(tmp_pkey);
-	} else
-		fprintf(stderr, "REMOTE SIDE DOESN'T PROVIDES ->peer_rsa_tmp\n");
-*/
-	cert_info->rsa_tmp_bits = 0;
-
-	X509_free (peer_cert);
-
-	return (0);
-}
-
-
-struct chiper_info *
-_SSL_get_cipher_info (SSL * ssl)
-{
-	const SSL_CIPHER *c;
-
-
-	c = SSL_get_current_cipher (ssl);
-	strncpy (chiper_info.version, SSL_CIPHER_get_version (c),
-				sizeof (chiper_info.version));
-	strncpy (chiper_info.chiper, SSL_CIPHER_get_name (c),
-				sizeof (chiper_info.chiper));
-	SSL_CIPHER_get_bits (c, &chiper_info.chiper_bits);
-
-	return (&chiper_info);
-}
-
-
-int
-_SSL_send (SSL * ssl, char *buf, int len)
-{
-	int num;
-
-
-	num = SSL_write (ssl, buf, len);
-
-	switch (SSL_get_error (ssl, num))
-	{
-	case SSL_ERROR_SSL:			  /* setup errno! */
-		/* ??? */
-		__SSL_fill_err_buf ("SSL_write");
-		fprintf (stderr, "%s\n", err_buf);
-		break;
-	case SSL_ERROR_SYSCALL:
-		/* ??? */
-		perror ("SSL_write/write");
-		break;
-	case SSL_ERROR_ZERO_RETURN:
-		/* fprintf(stderr, "SSL closed on write\n"); */
-		break;
-	}
-
-	return (num);
-}
-
-
-int
-_SSL_recv (SSL * ssl, char *buf, int len)
-{
-	int num;
-
-
-	num = SSL_read (ssl, buf, len);
-
-	switch (SSL_get_error (ssl, num))
-	{
-	case SSL_ERROR_SSL:
-		/* ??? */
-		__SSL_fill_err_buf ("SSL_read");
-		fprintf (stderr, "%s\n", err_buf);
-		break;
-	case SSL_ERROR_SYSCALL:
-		/* ??? */
-		if (!would_block ())
-			perror ("SSL_read/read");
-		break;
-	case SSL_ERROR_ZERO_RETURN:
-		/* fprintf(stdeerr, "SSL closed on read\n"); */
-		break;
-	}
-
-	return (num);
-}
-
-
-SSL *
-_SSL_socket (SSL_CTX *ctx, int sd)
-{
-	SSL *ssl;
-
-
-	if (!(ssl = SSL_new (ctx)))
-		/* FATAL */
-		__SSL_critical_error ("SSL_new");
-
-	SSL_set_fd (ssl, sd);
-	if (ctx->method == SSLv3_client_method())
-		SSL_set_connect_state (ssl);
-	else
-	        SSL_set_accept_state(ssl);
-
-	return (ssl);
-}
-
-
-char *
-_SSL_set_verify (SSL_CTX *ctx, void *verify_callback, char *cacert)
-{
-	if (!SSL_CTX_set_default_verify_paths (ctx))
-	{
-		__SSL_fill_err_buf ("SSL_CTX_set_default_verify_paths");
-		return (err_buf);
-	}
-/*
-	if (cacert)
-	{
-		if (!SSL_CTX_load_verify_locations (ctx, cacert, NULL))
-		{
-			__SSL_fill_err_buf ("SSL_CTX_load_verify_locations");
-			return (err_buf);
-		}
-	}
-*/
-	SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER, verify_callback);
-
-	return (NULL);
-}
-
-
-void
-_SSL_close (SSL * ssl)
-{
-	SSL_set_shutdown (ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
-	SSL_free (ssl);
-	ERR_remove_state (0);		  /* free state buffer */
-}
+#include <glib/gprintf.h>

+#define snprintf g_snprintf

+#endif

+

+/* globals */

+static struct chiper_info chiper_info;		/* static buffer for _SSL_get_cipher_info() */

+static char err_buf[256];			/* generic error buffer */

+

+

+/* +++++ Internal functions +++++ */

+

+static void

+__SSL_fill_err_buf (char *funcname)

+{

+	int err;

+	char buf[256];

+

+

+	err = ERR_get_error ();

+	ERR_error_string (err, buf);

+	snprintf (err_buf, sizeof (err_buf), "%s: %s (%d)\n", funcname, buf, err);

+}

+

+

+static void

+__SSL_critical_error (char *funcname)

+{

+	__SSL_fill_err_buf (funcname);

+	fprintf (stderr, "%s\n", err_buf);

+

+	exit (1);

+}

+

+/* +++++ SSL functions +++++ */

+

+SSL_CTX *

+_SSL_context_init (void (*info_cb_func), int server)

+{

+	SSL_CTX *ctx;

+#ifdef WIN32

+	int i, r;

+#endif

+

+	SSLeay_add_ssl_algorithms ();

+	SSL_load_error_strings ();

+	ctx = SSL_CTX_new (server ? SSLv23_server_method() : SSLv23_client_method ());

+

+	SSL_CTX_set_session_cache_mode (ctx, SSL_SESS_CACHE_BOTH);

+	SSL_CTX_set_timeout (ctx, 300);

+

+	/* used in SSL_connect(), SSL_accept() */

+	SSL_CTX_set_info_callback (ctx, info_cb_func);

+

+#ifdef WIN32

+	/* under win32, OpenSSL needs to be seeded with some randomness */

+	for (i = 0; i < 128; i++)

+	{

+		r = rand ();

+		RAND_seed ((unsigned char *)&r, sizeof (r));

+	}

+#endif

+

+	return(ctx);

+}

+

+static void

+ASN1_TIME_snprintf (char *buf, int buf_len, ASN1_TIME * tm)

+{

+	char *expires = NULL;

+	BIO *inMem = BIO_new (BIO_s_mem ());

+

+	ASN1_TIME_print (inMem, tm);

+	BIO_get_mem_data (inMem, &expires);

+	buf[0] = 0;

+	if (expires != NULL)

+	{

+		memset (buf, 0, buf_len);

+		strncpy (buf, expires, 24);

+	}

+	BIO_free (inMem);

+}

+

+

+static void

+broke_oneline (char *oneline, char *parray[])

+{

+	char *pt, *ppt;

+	int i;

+

+

+	i = 0;

+	ppt = pt = oneline + 1;

+	while ((pt = strchr (pt, '/')))

+	{

+		*pt = 0;

+		parray[i++] = ppt;

+		ppt = ++pt;

+	}

+	parray[i++] = ppt;

+	parray[i] = NULL;

+}

+

+

+/*

+    FIXME: Master-Key, Extensions, CA bits

+	    (openssl x509 -text -in servcert.pem)

+*/

+int

+_SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl)

+{

+	X509 *peer_cert;

+	EVP_PKEY *peer_pkey;

+	/* EVP_PKEY *ca_pkey; */

+	/* EVP_PKEY *tmp_pkey; */

+	char notBefore[64];

+	char notAfter[64];

+	int alg;

+	int sign_alg;

+

+

+	if (!(peer_cert = SSL_get_peer_certificate (ssl)))

+		return (1);				  /* FATAL? */

+

+	X509_NAME_oneline (X509_get_subject_name (peer_cert), cert_info->subject,

+							 sizeof (cert_info->subject));

+	X509_NAME_oneline (X509_get_issuer_name (peer_cert), cert_info->issuer,

+							 sizeof (cert_info->issuer));

+	broke_oneline (cert_info->subject, cert_info->subject_word);

+	broke_oneline (cert_info->issuer, cert_info->issuer_word);

+

+	alg = OBJ_obj2nid (peer_cert->cert_info->key->algor->algorithm);

+	sign_alg = OBJ_obj2nid (peer_cert->sig_alg->algorithm);

+	ASN1_TIME_snprintf (notBefore, sizeof (notBefore),

+							  X509_get_notBefore (peer_cert));

+	ASN1_TIME_snprintf (notAfter, sizeof (notAfter),

+							  X509_get_notAfter (peer_cert));

+

+	peer_pkey = X509_get_pubkey (peer_cert);

+

+	strncpy (cert_info->algorithm,

+				(alg == NID_undef) ? "Unknown" : OBJ_nid2ln (alg),

+				sizeof (cert_info->algorithm));

+	cert_info->algorithm_bits = EVP_PKEY_bits (peer_pkey);

+	strncpy (cert_info->sign_algorithm,

+				(sign_alg == NID_undef) ? "Unknown" : OBJ_nid2ln (sign_alg),

+				sizeof (cert_info->sign_algorithm));

+	/* EVP_PKEY_bits(ca_pkey)); */

+	cert_info->sign_algorithm_bits = 0;

+	strncpy (cert_info->notbefore, notBefore, sizeof (cert_info->notbefore));

+	strncpy (cert_info->notafter, notAfter, sizeof (cert_info->notafter));

+

+	EVP_PKEY_free (peer_pkey);

+

+	/* SSL_SESSION_print_fp(stdout, SSL_get_session(ssl)); */

+/*

+	if (ssl->session->sess_cert->peer_rsa_tmp) {

+		tmp_pkey = EVP_PKEY_new();

+		EVP_PKEY_assign_RSA(tmp_pkey, ssl->session->sess_cert->peer_rsa_tmp);

+		cert_info->rsa_tmp_bits = EVP_PKEY_bits (tmp_pkey);

+		EVP_PKEY_free(tmp_pkey);

+	} else

+		fprintf(stderr, "REMOTE SIDE DOESN'T PROVIDES ->peer_rsa_tmp\n");

+*/

+	cert_info->rsa_tmp_bits = 0;

+

+	X509_free (peer_cert);

+

+	return (0);

+}

+

+

+struct chiper_info *

+_SSL_get_cipher_info (SSL * ssl)

+{

+	const SSL_CIPHER *c;

+

+

+	c = SSL_get_current_cipher (ssl);

+	strncpy (chiper_info.version, SSL_CIPHER_get_version (c),

+				sizeof (chiper_info.version));

+	strncpy (chiper_info.chiper, SSL_CIPHER_get_name (c),

+				sizeof (chiper_info.chiper));

+	SSL_CIPHER_get_bits (c, &chiper_info.chiper_bits);

+

+	return (&chiper_info);

+}

+

+

+int

+_SSL_send (SSL * ssl, char *buf, int len)

+{

+	int num;

+

+

+	num = SSL_write (ssl, buf, len);

+

+	switch (SSL_get_error (ssl, num))

+	{

+	case SSL_ERROR_SSL:			  /* setup errno! */

+		/* ??? */

+		__SSL_fill_err_buf ("SSL_write");

+		fprintf (stderr, "%s\n", err_buf);

+		break;

+	case SSL_ERROR_SYSCALL:

+		/* ??? */

+		perror ("SSL_write/write");

+		break;

+	case SSL_ERROR_ZERO_RETURN:

+		/* fprintf(stderr, "SSL closed on write\n"); */

+		break;

+	}

+

+	return (num);

+}

+

+

+int

+_SSL_recv (SSL * ssl, char *buf, int len)

+{

+	int num;

+

+

+	num = SSL_read (ssl, buf, len);

+

+	switch (SSL_get_error (ssl, num))

+	{

+	case SSL_ERROR_SSL:

+		/* ??? */

+		__SSL_fill_err_buf ("SSL_read");

+		fprintf (stderr, "%s\n", err_buf);

+		break;

+	case SSL_ERROR_SYSCALL:

+		/* ??? */

+		if (!would_block ())

+			perror ("SSL_read/read");

+		break;

+	case SSL_ERROR_ZERO_RETURN:

+		/* fprintf(stdeerr, "SSL closed on read\n"); */

+		break;

+	}

+

+	return (num);

+}

+

+

+SSL *

+_SSL_socket (SSL_CTX *ctx, int sd)

+{

+	SSL *ssl;

+

+

+	if (!(ssl = SSL_new (ctx)))

+		/* FATAL */

+		__SSL_critical_error ("SSL_new");

+

+	SSL_set_fd (ssl, sd);

+	if (ctx->method == SSLv23_client_method())

+		SSL_set_connect_state (ssl);

+	else

+	        SSL_set_accept_state(ssl);

+

+	return (ssl);

+}

+

+

+char *

+_SSL_set_verify (SSL_CTX *ctx, void *verify_callback, char *cacert)

+{

+	if (!SSL_CTX_set_default_verify_paths (ctx))

+	{

+		__SSL_fill_err_buf ("SSL_CTX_set_default_verify_paths");

+		return (err_buf);

+	}

+/*

+	if (cacert)

+	{

+		if (!SSL_CTX_load_verify_locations (ctx, cacert, NULL))

+		{

+			__SSL_fill_err_buf ("SSL_CTX_load_verify_locations");

+			return (err_buf);

+		}

+	}

+*/

+	SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER, verify_callback);

+

+	return (NULL);

+}

+

+

+void

+_SSL_close (SSL * ssl)

+{

+	SSL_set_shutdown (ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);

+	SSL_free (ssl);

+	ERR_remove_state (0);		  /* free state buffer */

+}