diff -ruN netcat-0.7.1/src/Makefile.in netcat-0.7.1.new/src/Makefile.in
--- netcat-0.7.1/src/Makefile.in	2004-01-11 17:46:31.000000000 -0300
+++ netcat-0.7.1.new/src/Makefile.in	2004-02-24 13:04:11.000000000 -0300
@@ -56,7 +56,7 @@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
 CYGPATH_W = @CYGPATH_W@
-DEFS = -DLOCALEDIR=\"\$(localedir)\" @DEFS@
+DEFS = -DLOCALEDIR=\"\$(localedir)\" @DEFS@ -DHAVE_TLS
 DEPDIR = @DEPDIR@
 ECHO_C = @ECHO_C@
 ECHO_N = @ECHO_N@
@@ -75,7 +75,7 @@
 LIBICONV = @LIBICONV@
 LIBINTL = @LIBINTL@
 LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
+LIBS = @LIBS@ -lssl -lcrypto
 LTLIBICONV = @LTLIBICONV@
 LTLIBINTL = @LTLIBINTL@
 LTLIBOBJS = @LTLIBOBJS@
@@ -157,6 +157,7 @@
 	netcat.c \
 	network.c \
 	telnet.c \
+	sslutils.c \
 	udphelper.c
 
 
@@ -178,7 +179,7 @@
 
 am_netcat_OBJECTS = core.$(OBJEXT) flagset.$(OBJEXT) misc.$(OBJEXT) \
 	netcat.$(OBJEXT) network.$(OBJEXT) telnet.$(OBJEXT) \
-	udphelper.$(OBJEXT)
+	udphelper.$(OBJEXT) sslutils.$(OBJEXT)
 netcat_OBJECTS = $(am_netcat_OBJECTS)
 netcat_DEPENDENCIES =
 netcat_LDFLAGS =
diff -ruN netcat-0.7.1/src/misc.c netcat-0.7.1.new/src/misc.c
--- netcat-0.7.1/src/misc.c	2004-01-03 13:42:07.000000000 -0300
+++ netcat-0.7.1.new/src/misc.c	2004-02-23 00:30:50.000000000 -0300
@@ -325,6 +325,15 @@
 "  -p, --local-port=NUM       local port number\n"
 "  -r, --randomize            randomize local and remote ports\n"
 "  -s, --source=ADDRESS       local source address (ip or hostname)\n"));
+#ifdef HAVE_TLS
+printf(_(""
+"  -E, --tls                  use tls\n"
+"  -f, --cafile=FILE          CA certificate file to auth the peer\n"
+"  -F, --capath=PATH          CA certificate dir to auth the peer\n"
+"  -K, --dontcheckhost        don't check hostname with certificate data\n"
+"  -R, --cert=FILE            use certificate file (listen mode)\n"
+"  -k, --key=FILE             use private key (listen mode)\n"));
+#endif
 #ifndef USE_OLD_COMPAT
   printf(_(""
 "  -t, --tcp                  TCP mode (default)\n"
diff -ruN netcat-0.7.1/src/netcat.c netcat-0.7.1.new/src/netcat.c
--- netcat-0.7.1/src/netcat.c	2003-08-28 14:20:25.000000000 -0300
+++ netcat-0.7.1.new/src/netcat.c	2004-02-23 00:29:55.000000000 -0300
@@ -30,6 +30,9 @@
 #include <signal.h>
 #include <getopt.h>
 #include <time.h>		/* time(2) used as random seed */
+#ifdef HAVE_TLS
+#include <sslutils.h>
+#endif
 
 /* int gatesidx = 0; */		/* LSRR hop count */
 /* int gatesptr = 4; */		/* initial LSRR pointer, settable */
@@ -50,6 +53,14 @@
 bool opt_numeric = FALSE;	/* don't resolve hostnames */
 bool opt_random = FALSE;	/* use random ports */
 bool opt_udpmode = FALSE;	/* use udp protocol instead of tcp */
+#ifdef HAVE_TLS
+bool opt_tls = FALSE;		/* use tls */
+bool opt_dontcheckhost = FALSE; /* don't check host */
+char *opt_cafile = NULL;	/* CA chain file */
+char *opt_capath = NULL;	/* CA chain dir */
+char *opt_keyfile = NULL;	/* key file */
+char *opt_certfile = NULL;	/* certificate file */
+#endif
 bool opt_telnet = FALSE;	/* answer in telnet mode */
 bool opt_hexdump = FALSE;	/* hexdump traffic */
 bool opt_zero = FALSE;		/* zero I/O mode (don't expect anything) */
@@ -101,20 +112,20 @@
 
 /* Execute an external file making its stdin/stdout/stderr the actual socket */
 
-static void ncexec(nc_sock_t *ncsock)
+static void ncexec(int readfd, int writefd)
 {
   int saved_stderr;
   char *p;
-  assert(ncsock && (ncsock->fd >= 0));
+  assert((writefd >= 0) && (readfd >= 0));
 
   /* save the stderr fd because we may need it later */
   saved_stderr = dup(STDERR_FILENO);
 
   /* duplicate the socket for the child program */
-  dup2(ncsock->fd, STDIN_FILENO);	/* the precise order of fiddlage */
-  close(ncsock->fd);			/* is apparently crucial; this is */
-  dup2(STDIN_FILENO, STDOUT_FILENO);	/* swiped directly out of "inetd". */
-  dup2(STDIN_FILENO, STDERR_FILENO);	/* also duplicate the stderr channel */
+  dup2(readfd, STDIN_FILENO);	/* the precise order of fiddlage */
+  //close(readfd);			/* is apparently crucial; this is */
+  dup2(writefd, STDOUT_FILENO);	/* swiped directly out of "inetd". */
+  dup2(writefd, STDERR_FILENO);	/* also duplicate the stderr channel */
 
   /* change the label for the executed program */
   if ((p = strrchr(opt_exec, '/')))
@@ -146,6 +157,11 @@
   nc_sock_t listen_sock;
   nc_sock_t connect_sock;
   nc_sock_t stdio_sock;
+#ifdef HAVE_TLS
+  SSL_CTX *ctx;
+  SSL *ssl;
+#endif
+  char *host = NULL;
 
   memset(&local_port, 0, sizeof(local_port));
   memset(&local_host, 0, sizeof(local_host));
@@ -200,6 +216,14 @@
 	{ "randomize",	no_argument,		NULL, 'r' },
 	{ "source",	required_argument,	NULL, 's' },
 	{ "tunnel-source", required_argument,	NULL, 'S' },
+#ifdef HAVE_TLS
+	{ "tls",	no_argument,		NULL, 'E' },
+	{ "cafile",	required_argument,	NULL, 'f' },
+	{ "capath",	required_argument,	NULL, 'F' },
+	{ "dontcheckhost",	no_argument,	NULL, 'K' },
+	{ "cert",	required_argument,	NULL, 'R' },
+	{ "key",	required_argument,	NULL, 'k' },
+#endif
 #ifndef USE_OLD_COMPAT
 	{ "tcp",	no_argument,		NULL, 't' },
 	{ "telnet",	no_argument,		NULL, 'T' },
@@ -216,7 +240,11 @@
 	{ 0, 0, 0, 0 }
     };
 
-    c = getopt_long(argc, argv, "cde:g:G:hi:lL:no:p:P:rs:S:tTuvVxw:z",
+    c = getopt_long(argc, argv, "cde:g:G:hi:lL:no:p:P:rs:S:"
+#ifdef HAVE_TLS
+				"Ef:F:R:k:"
+#endif
+    				"tTuvVxw:z",
 		    long_options, &option_index);
     if (c == -1)
       break;
@@ -234,6 +262,38 @@
 		_("Cannot specify `-e' option double"));
       opt_exec = strdup(optarg);
       break;
+#ifdef HAVE_TLS
+    case 'E':
+      opt_tls = 1;
+      break;
+    case 'f':
+      if (opt_cafile)
+	ncprint(NCPRINT_ERROR | NCPRINT_EXIT,
+		_("Cannot specify `-f' option double"));
+      opt_cafile = strdup(optarg);
+      break;
+    case 'F':
+      if (opt_capath)
+	ncprint(NCPRINT_ERROR | NCPRINT_EXIT,
+		_("Cannot specify `-F' option double"));
+      opt_capath = strdup(optarg);
+      break;
+    case 'R':
+      if (opt_certfile)
+	ncprint(NCPRINT_ERROR | NCPRINT_EXIT,
+		_("Cannot specify `-R' option double"));
+      opt_certfile = strdup(optarg);
+      break;
+    case 'k':
+      if (opt_keyfile)
+	ncprint(NCPRINT_ERROR | NCPRINT_EXIT,
+		_("Cannot specify `-k' option double"));
+      opt_keyfile = strdup(optarg);
+      break;
+    case 'K':
+      opt_dontcheckhost = 1;
+      break;
+#endif
     case 'G':			/* srcrt gateways pointer val */
       break;
     case 'g':			/* srcroute hop[s] */
@@ -357,6 +417,9 @@
   if (opt_zero && opt_exec)
     ncprint(NCPRINT_ERROR | NCPRINT_EXIT,
 		_("`-e' and `-z' options are incompatible"));
+  if (opt_tls && (opt_proto == NETCAT_PROTO_UDP) )
+    ncprint(NCPRINT_ERROR | NCPRINT_EXIT,
+		_("`-u' and `-E' options are incompatible"));
 
   /* initialize the flag buffer to keep track of the specified ports */
   netcat_flag_init(65535);
@@ -392,10 +455,10 @@
 
   /* try to get an hostname parameter */
   if (optind < argc) {
-    char *myhost = argv[optind++];
-    if (!netcat_resolvehost(&remote_host, myhost))
+    host = argv[optind++];
+    if (!netcat_resolvehost(&remote_host, host))
       ncprint(NCPRINT_ERROR | NCPRINT_EXIT, _("Couldn't resolve host \"%s\""),
-	      myhost);
+	      host);
   }
 
   /* now loop all the other (maybe optional) parameters for port-ranges */
@@ -492,11 +555,46 @@
        otherwise now it's the time to connect to the target host and tunnel
        them together (which means passing to the next section. */
     if (netcat_mode == NETCAT_LISTEN) {
+#ifdef HAVE_TLS
+      if (opt_tls) {
+        if (ssl_server_init(&ssl, &ctx, opt_certfile, opt_keyfile))
+          ncprint(NCPRINT_ERROR | NCPRINT_EXIT, _("ssl_server_init failed\n"));
+        if (ssl_server_handshake(ssl, listen_sock.fd))
+          ncprint(NCPRINT_ERROR | NCPRINT_EXIT, _("ssl_server_handshake failed\n"));
+      }
+      if (opt_exec && !opt_tls) {
+#else
       if (opt_exec) {
+#endif
 	ncprint(NCPRINT_VERB2, _("Passing control to the specified program"));
-	ncexec(&listen_sock);		/* this won't return */
+	ncexec(listen_sock.fd, listen_sock.fd);		/* this won't return */
+      }
+#ifdef HAVE_TLS
+      if (opt_tls) {
+        int p_read[2], p_write[2];
+	int pid;
+      	
+        if (opt_exec) {
+	  if (pipe(p_read) < 0)
+	    ncprint(NCPRINT_ERROR | NCPRINT_EXIT, _("%s\n"), strerror(errno));
+	  if (pipe(p_write) < 0)
+	    ncprint(NCPRINT_ERROR | NCPRINT_EXIT, _("%s\n"), strerror(errno));
+	  signal(SIGCHLD, SIG_IGN);
+	  if ((pid = fork()) == -1)
+	    ncprint(NCPRINT_ERROR | NCPRINT_EXIT, _("%s\n"), strerror(errno));
+	  if (pid == 0) {
+	    ncexec(p_write[0], p_read[1]);              /* this won't return */
+	  }
+	  close(p_write[0]);
+	  close(p_read[1]);
+	  ssl_read_write(ssl, p_read[0], p_write[1], listen_sock.fd);
+	} else
+          ssl_read_write(ssl, stdio_sock.fd, STDOUT_FILENO, listen_sock.fd);
+	ssl_shutdown(&ctx, &ssl);
       }
-      core_readwrite(&listen_sock, &stdio_sock);
+      else
+#endif
+        core_readwrite(&listen_sock, &stdio_sock);
       debug_dv(("Listen: EXIT"));
     }
     else {
@@ -583,6 +681,18 @@
       continue;			/* go with next port */
     }
 
+#ifdef HAVE_TLS
+    if (opt_tls) {
+      if (ssl_client_init (&ssl, &ctx, opt_cafile, opt_capath) < 0)
+	ncprint(NCPRINT_ERROR | NCPRINT_EXIT, _("ssl_client_init failed\n"));
+      if (ssl_client_handshake(ssl, connect_sock.fd)< 0)
+	ncprint(NCPRINT_ERROR | NCPRINT_EXIT, _("ssl_client_handshake failed\n"));
+      if (!opt_dontcheckhost)
+        if (ssl_check_hostname(ssl, host) < 0)
+          ncprint(NCPRINT_ERROR | NCPRINT_EXIT, _("ssl_check_hostname failed\n"));
+    }
+#endif
+
     /* when portscanning (or checking a single port) we are happy if AT LEAST
        ONE port is available. */
     glob_ret = EXIT_SUCCESS;
@@ -594,9 +704,16 @@
     else {
       if (opt_exec) {
 	ncprint(NCPRINT_VERB2, _("Passing control to the specified program"));
-	ncexec(&connect_sock);		/* this won't return */
+	ncexec(connect_sock.fd, connect_sock.fd);		/* this won't return */
       }
-      core_readwrite(&connect_sock, &stdio_sock);
+#ifdef HAVE_TLS
+      if (opt_tls) {
+      	ssl_read_write( ssl, stdio_sock.fd, 1, connect_sock.fd); 
+        ssl_shutdown(&ctx, &ssl);
+      }
+      else
+#endif
+        core_readwrite(&connect_sock, &stdio_sock);
       /* FIXME: add a small delay */
       debug_v(("Connect: EXIT"));
 
diff -ruN netcat-0.7.1/src/sslutils.c netcat-0.7.1.new/src/sslutils.c
--- netcat-0.7.1/src/sslutils.c	1969-12-31 21:00:00.000000000 -0300
+++ netcat-0.7.1.new/src/sslutils.c	2004-02-22 19:04:47.000000000 -0300
@@ -0,0 +1,395 @@
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <err.h>
+
+#include "sslutils.h"
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+
+static int tls_verify_cb( int ok, X509_STORE_CTX *ctx );
+
+/* initialization for a SSL client */
+int	ssl_client_init (SSL **ssl, SSL_CTX **ctx, char *CAfile, char *CApath)
+{
+	/* loads errors string messages */
+	SSL_load_error_strings();
+
+	/* init library */
+	if (SSL_library_init() != 1) {
+		fprintf(stderr, "could not initialice SSL library\n");
+		return(-1);
+	}
+
+	/* create SSL context */
+	if((*ctx = SSL_CTX_new (SSLv23_client_method())) == NULL) {
+		fprintf (stderr, "could not initialize SSL_CTX structure\n");
+		return (-1);
+	}
+	SSL_CTX_set_mode(*ctx, SSL_MODE_AUTO_RETRY);
+  
+	/* loads certs to authenticate the peer */
+	if (CAfile || CApath) {
+		SSL_CTX_set_verify(*ctx, (SSL_VERIFY_PEER | SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT), tls_verify_cb);
+		if (!SSL_CTX_load_verify_locations(*ctx, CAfile, CApath))
+			fprintf(stderr, "could not initialize CA file/path");
+	}
+		
+	/* create SSL structure */
+	if(( *ssl = SSL_new (*ctx)) == NULL ) {
+		fprintf (stderr, "could not initialize SSL structure\n");
+		return (-1);
+	}
+
+	return(0);
+}
+
+/* initialization for a SSL server */
+int	ssl_server_init(SSL **ssl, SSL_CTX **ctx, char *certfile, char *keyfile)
+{
+	/* loads errors string messages */
+	SSL_load_error_strings();
+
+	/* init library */
+	if (SSL_library_init() != 1) {
+		fprintf(stderr, "could not initialice SSL library\n");
+		return(-1);
+	}
+
+	
+	/* create SSL context */
+	if((*ctx = SSL_CTX_new (SSLv23_server_method())) == NULL) {
+		fprintf (stderr, "could not initialize SSL_CTX structure\n");
+		return (-1);
+	}
+
+	SSL_CTX_set_quiet_shutdown (*ctx,1);
+	SSL_CTX_set_session_cache_mode (*ctx,SSL_SESS_CACHE_OFF);
+
+	if (certfile && keyfile) {
+		if ( (SSL_CTX_use_certificate_file(*ctx, certfile, SSL_FILETYPE_PEM)) != 1) {
+			fprintf(stderr, "Error loading certificate file\n");
+			return(-1);
+		}
+		if ( (SSL_CTX_use_PrivateKey_file(*ctx, keyfile, SSL_FILETYPE_PEM)) != 1) {
+			fprintf(stderr, "Error loading private key file\n");
+			return(-1);
+		}
+if (!SSL_CTX_check_private_key (*ctx))
+           {
+                fprintf(stderr, "private key from [%s] is not valid\n", keyfile);
+                return (-1);
+           }
+
+	}
+
+	/* create SSL structure */
+	if(( *ssl = SSL_new (*ctx)) == NULL ) {
+		fprintf (stderr, "could not initialize SSL structure\n");
+		return (-1);
+	}
+  	return(0);
+}
+
+int ssl_client_handshake2(SSL *ssl, int socket) {
+	int ret;
+
+	if ( (ret = SSL_set_fd (ssl, socket)) != 1) {
+		fprintf(stderr, "ERROR SSL_set_fd\n");
+		return(-1);
+	}
+
+	SSL_set_connect_state (ssl);
+
+	fprintf(stderr, "mode: %ld\n", SSL_get_mode(ssl));
+	ret = SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+	fprintf(stderr, "mode: %ld\n", SSL_get_mode(ssl));
+
+	if ( (ret = SSL_do_handshake(ssl)) != 1 ) {
+		ret = ERR_get_error();
+		fprintf(stderr, "ERR in SSL_do_handshake (%d)\n", ret);
+		fprintf(stderr, "\t%s\n", ERR_error_string(ret, NULL));
+		return(-1);
+	}
+
+	return(0);
+}
+
+int ssl_client_handshake(SSL *ssl, int socket)
+{
+	int oldflags = 0, ret;
+
+	if ( (ret = SSL_set_fd (ssl, socket)) != 1) {
+		fprintf(stderr, "ERROR SSL_set_fd\n");
+		return(-1);
+	}
+
+	SSL_set_connect_state (ssl);
+
+	if ( (oldflags = set_nonblocking_mode (socket)) < 0)
+		return (-1);
+
+	/* on local connections, SSL_do_handshake may finish */
+	ret = SSL_do_handshake(ssl);
+
+	if ( (unset_nonblocking_mode (socket, oldflags)) < 0)
+		return (-1);
+
+	/* on remote connections, wait for handshake answer and finish ssl connect */
+	if (!SSL_is_init_finished (ssl)) {
+	//if (data_available (socket, timeout) < 0)
+      		//return (-1);
+	ret = SSL_connect(ssl);
+	}
+	switch (ret) {
+		default:
+		case (-1):
+			fprintf (stderr, "TLS/SSL handshake failed.\n");
+			return (-1);
+		case (0):
+			fprintf (stderr, "TLS/SSL handshake failed cleanly.\n");
+			return (-1);
+		case (1):
+			return (0);
+	}
+}
+
+int ssl_server_handshake(SSL *ssl, int sock) {
+	int ret;
+
+	if ( (ret = SSL_set_fd(ssl, sock)) != 1) {
+		fprintf(stderr, "ERROR SSL_set_fd\n");
+		return(-1);
+	}
+
+	SSL_set_accept_state(ssl);
+	SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
+
+	if ( (ret = SSL_accept(ssl)) == -1) {
+		ret = SSL_get_error(ssl, ret);
+		fprintf(stderr, "%s\n", ERR_error_string(ret, NULL));
+		return (-1);
+	}
+	return(0);
+}
+
+int set_nonblocking_mode (int fd) {
+  int sockflag;
+  sockflag = fcntl (fd, F_GETFL, 0);
+
+  if (fcntl (fd, F_SETFL, sockflag | O_NONBLOCK) == -1) {
+    fprintf(stderr, "could not set O_NONBLOCK on socket\n");
+    return (-1);
+  }
+  return (sockflag);
+}
+
+int unset_nonblocking_mode (int fd, int oldflags) {
+  if (fcntl (fd, F_SETFL, oldflags&(~O_NONBLOCK)) == -1) {
+    fprintf(stderr, "could not unset O_NONBLOCK on socket\n");
+    return (-1);
+  }
+  return (0);
+}
+
+void ssl_shutdown(SSL_CTX **ctx, SSL **ssl) {
+	if (*ssl) {
+		SSL_shutdown(*ssl);
+		SSL_free(*ssl);
+		*ssl = NULL;
+	}
+	if (*ctx) {
+		SSL_CTX_free(*ctx);
+		*ctx = NULL;
+	}
+}
+
+int ssl_read_write(SSL *ssl, int sockin, int sockprint, int sockout) {
+  int                     num, nw, fdhigh, inclose = 0;
+  unsigned char           buf[4096];
+  fd_set                  fdread;
+
+  fdhigh = (sockin <= sockout) ? sockout : sockin;
+
+  while (1) {
+    /* empty the buffer */
+    if (SSL_pending (ssl)) {
+      num = SSL_read (ssl, buf, sizeof (buf));
+      if (num <= 0) {
+      	fprintf(stderr, "SSL_read returns %d\n", num);
+        return -1;
+      }
+      for (nw = 0; num; num -= nw)
+      	if ((nw = write (sockin, buf, num)) < 0) {
+	  err(1, "file descriptor %d", sockin);
+	  return -1;
+	}
+    }
+
+    FD_ZERO (&fdread);
+    FD_SET  (sockout, &fdread);
+    if (!inclose) {
+      FD_SET  (sockin,  &fdread);
+      fdhigh = (sockin <= sockout) ? sockout : sockin;
+    } else
+      fdhigh = sockout;
+
+    select (fdhigh+1, &fdread, NULL, NULL, NULL);
+    if ( FD_ISSET (sockout, &fdread) ) {
+      num = SSL_read (ssl, buf, sizeof (buf));
+      if (num <= 0)
+        return -1; 
+      for (nw = 0; num; num -= nw)
+        if ((nw = write (sockprint, buf, num)) < 0) {
+	  err(1, "file descriptor %d", sockprint);
+	  return -1;
+	}
+    }
+
+    if ( FD_ISSET (sockin, &fdread) ) {
+      num = read (sockin, buf, sizeof (buf));
+      if (num <= 0)
+        if (sockin == STDIN_FILENO)
+          inclose = 1;
+        else
+          return -1;
+      else {
+        num = SSL_write (ssl, buf, num);
+        if (num <= 0)
+          return -1;
+      }
+    }
+
+  } /* while */
+        return 0;
+}
+
+/* verify_callback based on libldap (openldap) library */
+static int
+tls_verify_cb( int ok, X509_STORE_CTX *ctx )
+{
+	X509 *cert;
+	int errnum;
+	int errdepth;
+	X509_NAME *subject;
+	X509_NAME *issuer;
+	char *sname;
+	char *iname;
+
+	if (!ok) {
+		cert = X509_STORE_CTX_get_current_cert( ctx );
+		errnum = X509_STORE_CTX_get_error( ctx );
+		errdepth = X509_STORE_CTX_get_error_depth( ctx );
+
+		/*
+	 	* X509_get_*_name return pointers to the internal copies of
+	 	* those things requested.  So do not free them.
+	 	*/
+		subject = X509_get_subject_name( cert );
+		issuer = X509_get_issuer_name( cert );
+		/* X509_NAME_oneline, if passed a NULL buf, allocate memomry */
+		sname = X509_NAME_oneline( subject, NULL, 0 );
+		iname = X509_NAME_oneline( issuer, NULL, 0 );
+		fprintf(stderr, 
+	       "TLS certificate verification: depth: %d, subject: %s, issuer: %s, error: %s\n",
+	       errdepth,
+	       sname ? sname : "-unknown-",
+	       iname ? iname : "-unknown-",
+	       X509_verify_cert_error_string(errnum));
+		if ( sname )
+			CRYPTO_free ( sname );
+		if ( iname )
+			CRYPTO_free ( iname );
+	}
+	return ok;
+}
+
+
+int ssl_check_hostname(SSL *ssl, char *host)
+{
+    X509      *cert;
+    X509_NAME *subj;
+    char      data[256];
+    int       extcount;
+    int       ok = 0;
+ 
+    /* Checking the return from SSL_get_peer_certificate here is not strictly
+     * necessary.  With our example programs, it is not possible for it to return
+     * NULL.  However, it is good form to check the return since it can return NULL
+     * if the examples are modified to enable anonymous ciphers or for the server
+     * to not require a client certificate.
+     */
+    if (!(cert = SSL_get_peer_certificate(ssl)) || !host) {
+    	fprintf(stderr, "%s\n", X509_verify_cert_error_string(X509_V_ERR_APPLICATION_VERIFICATION));
+	return -1;
+    }
+    if ((extcount = X509_get_ext_count(cert)) > 0)
+    {
+        int i;
+ 
+        for (i = 0;  i < extcount;  i++)
+        {
+            const char        *extstr;
+            X509_EXTENSION    *ext;
+ 
+            ext = X509_get_ext(cert, i);
+            extstr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
+ 
+            if (!strcmp(extstr, "subjectAltName"))
+            {
+                int                  j;
+                unsigned char        *data;
+                STACK_OF(CONF_VALUE) *val;
+                CONF_VALUE           *nval;
+                X509V3_EXT_METHOD    *meth;
+                void                 *ext_str = NULL;
+ 
+                if (!(meth = X509V3_EXT_get(ext)))
+                    break;
+                data = ext->value->data;
+ 
+#if (OPENSSL_VERSION_NUMBER > 0x00907000L)     
+                if (meth->it)
+                  ext_str = ASN1_item_d2i(NULL, &data, ext->value->length,
+                                          ASN1_ITEM_ptr(meth->it));
+                else
+                  ext_str = meth->d2i(NULL, &data, ext->value->length);
+#else
+                ext_str = meth->d2i(NULL, &data, ext->value->length);
+#endif
+                val = meth->i2v(meth, ext_str, NULL);
+                for (j = 0;  j < sk_CONF_VALUE_num(val);  j++)
+                {
+                    nval = sk_CONF_VALUE_value(val, j);
+                    if (!strcmp(nval->name, "DNS") && !strcmp(nval->value, host))
+                    {
+                        ok = 1;
+                        break;
+                    }
+                }
+            }
+            if (ok)
+                break;
+        }
+    }
+ 
+    if (!ok && (subj = X509_get_subject_name(cert)) &&
+        X509_NAME_get_text_by_NID(subj, NID_commonName, data, 256) > 0)
+    {
+        data[255] = 0;
+        if (strcasecmp(data, host) == 0)
+            ok = 1;
+    }
+ 
+    if (cert)
+    	X509_free(cert);
+
+    if (ok)
+    	return 1;
+    else {
+    	fprintf(stderr, "FQDN (%s) verification failed\n", host);
+    	return -1;
+    }
+}
diff -ruN netcat-0.7.1/src/sslutils.h netcat-0.7.1.new/src/sslutils.h
--- netcat-0.7.1/src/sslutils.h	1969-12-31 21:00:00.000000000 -0300
+++ netcat-0.7.1.new/src/sslutils.h	2004-02-22 15:34:14.000000000 -0300
@@ -0,0 +1,15 @@
+#ifndef SSLUT_H
+#define SSLUT_H
+
+#include "openssl/ssl.h"
+
+int     ssl_client_init (SSL **ssl, SSL_CTX **ctx, char *CAfile, char *CApath);
+int     ssl_server_init (SSL **ssl, SSL_CTX **ctx, char *certfile, char *keyfile);
+int     ssl_client_handshake(SSL *ssl, int socket);
+int     ssl_server_handshake(SSL *ssl, int socket);
+int	ssl_read_write(SSL *ssl, int sockin, int sockprint, int sockout);
+int	ssl_check_hostname(SSL *ssl, char *host);
+void	ssl_shutdown(SSL_CTX **ctx, SSL **ssl);
+
+#endif
+
