Index: tclOpts.h
==================================================================
--- tclOpts.h
+++ tclOpts.h
@@ -42,10 +42,15 @@
     if (Tcl_GetBooleanFromObj(interp, objv[idx],\
 	    &(var)) != TCL_OK) {		\
 	    return TCL_ERROR;			\
     }						\
     OPT_POSTLOG()
+
+#define OPTBYTE(option, var, lvar)			\
+    OPT_PROLOG(option)				\
+    var = Tcl_GetByteArrayFromObj(objv[idx], &(lvar));\
+    OPT_POSTLOG()
 
 #define OPTBAD(type, list)			\
     Tcl_AppendResult(interp, "bad ", (type),	\
 		" \"", opt, "\": must be ",	\
 		(list), (char *) NULL)

Index: tls.c
==================================================================
--- tls.c
+++ tls.c
@@ -60,12 +60,13 @@
 
 static int	UnimportObjCmd(ClientData clientData,
 			Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
 
 static SSL_CTX *CTX_Init(State *statePtr, int isServer, int proto, char *key,
-			char *cert, char *CAdir, char *CAfile, char *ciphers,
-			char *DHparams);
+			char *certfile, unsigned char *key_asn1, unsigned char *cert_asn1,
+			int key_asn1_len, int cert_asn1_len, char *CAdir, char *CAfile,
+      char *ciphers, char *DHparams);
 
 static int	TlsLibInit(int uninitialize);
 
 #define TLS_PROTO_SSL2		0x01
 #define TLS_PROTO_SSL3		0x02
@@ -727,26 +728,30 @@
     int objc;
     Tcl_Obj *CONST objv[];
 {
     Tcl_Channel chan;		/* The channel to set a mode on. */
     State *statePtr;		/* client state for ssl socket */
-    SSL_CTX *ctx	= NULL;
-    Tcl_Obj *script	= NULL;
-    Tcl_Obj *password	= NULL;
+    SSL_CTX *ctx	        = NULL;
+    Tcl_Obj *script	        = NULL;
+    Tcl_Obj *password	        = NULL;
     Tcl_DString upperChannelTranslation, upperChannelBlocking, upperChannelEncoding, upperChannelEOFChar;
     int idx, len;
-    int flags		= TLS_TCL_INIT;
-    int server		= 0;	/* is connection incoming or outgoing? */
-    char *key		= NULL;
-    char *cert		= NULL;
-    char *ciphers	= NULL;
-    char *CAfile	= NULL;
-    char *CAdir		= NULL;
-    char *DHparams	= NULL;
-    char *model		= NULL;
+    int flags		        = TLS_TCL_INIT;
+    int server		        = 0;	/* is connection incoming or outgoing? */
+    char *keyfile	        = NULL;
+    char *certfile	        = NULL;
+    unsigned char *key  	= NULL;
+    int key_len                 = 0;
+    unsigned char *cert         = NULL;
+    int cert_len                = 0;
+    char *ciphers	        = NULL;
+    char *CAfile	        = NULL;
+    char *CAdir		        = NULL;
+    char *DHparams	        = NULL;
+    char *model		        = NULL;
 #ifndef OPENSSL_NO_TLSEXT
-    char *servername	= NULL;	/* hostname for Server Name Indication */
+    char *servername	        = NULL;	/* hostname for Server Name Indication */
 #endif
     int ssl2 = 0, ssl3 = 0;
     int tls1 = 1, tls1_1 = 1, tls1_2 = 1, tls1_3 = 1;
     int proto = 0;
     int verify = 0, require = 0, request = 1;
@@ -793,15 +798,15 @@
 	if (opt[0] != '-')
 	    break;
 
 	OPTSTR( "-cadir", CAdir);
 	OPTSTR( "-cafile", CAfile);
-	OPTSTR( "-certfile", cert);
+	OPTSTR( "-certfile", certfile);
 	OPTSTR( "-cipher", ciphers);
 	OPTOBJ( "-command", script);
 	OPTSTR( "-dhparams", DHparams);
-	OPTSTR( "-keyfile", key);
+	OPTSTR( "-keyfile", keyfile);
 	OPTSTR( "-model", model);
 	OPTOBJ( "-password", password);
 	OPTBOOL( "-require", require);
 	OPTBOOL( "-request", request);
 	OPTBOOL( "-server", server);
@@ -813,12 +818,14 @@
 	OPTBOOL( "-ssl3", ssl3);
 	OPTBOOL( "-tls1", tls1);
 	OPTBOOL( "-tls1.1", tls1_1);
 	OPTBOOL( "-tls1.2", tls1_2);
 	OPTBOOL( "-tls1.3", tls1_3);
+  OPTBYTE("-cert", cert, cert_len);
+  OPTBYTE("-key", key, key_len);
 
-	OPTBAD( "option", "-cadir, -cafile, -certfile, -cipher, -command, -dhparams, -keyfile, -model, -password, -require, -request, -server, -servername, -ssl2, -ssl3, -tls1, -tls1.1, -tls1.2, or tls1.3");
+	OPTBAD( "option", "-cadir, -cafile, -cert, -certfile, -cipher, -command, -dhparams, -key, -keyfile, -model, -password, -require, -request, -server, -servername, -ssl2, -ssl3, -tls1, -tls1.1, -tls1.2, or tls1.3");
 
 	return TCL_ERROR;
     }
     if (request)	    verify |= SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_PEER;
     if (request && require) verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
@@ -830,16 +837,18 @@
     proto |= (tls1_1 ? TLS_PROTO_TLS1_1 : 0);
     proto |= (tls1_2 ? TLS_PROTO_TLS1_2 : 0);
     proto |= (tls1_3 ? TLS_PROTO_TLS1_3 : 0);
 
     /* reset to NULL if blank string provided */
-    if (cert && !*cert)		cert	 = NULL;
-    if (key && !*key)		key	 = NULL;
-    if (ciphers && !*ciphers)	ciphers	 = NULL;
-    if (CAfile && !*CAfile)	CAfile	 = NULL;
-    if (CAdir && !*CAdir)	CAdir	 = NULL;
-    if (DHparams && !*DHparams)	DHparams = NULL;
+    if (cert && !*cert)		        cert	        = NULL;
+    if (key && !*key)		        key	        = NULL;
+    if (certfile && !*certfile)         certfile	= NULL;
+    if (keyfile && !*keyfile)		keyfile	        = NULL;
+    if (ciphers && !*ciphers)	        ciphers	        = NULL;
+    if (CAfile && !*CAfile)	        CAfile	        = NULL;
+    if (CAdir && !*CAdir)	        CAdir	        = NULL;
+    if (DHparams && !*DHparams)	        DHparams        = NULL;
 
     /* new SSL state */
     statePtr		= (State *) ckalloc((unsigned) sizeof(State));
     memset(statePtr, 0, sizeof(State));
 
@@ -885,12 +894,13 @@
 	    Tls_Free((char *) statePtr);
 	    return TCL_ERROR;
 	}
 	ctx = ((State *)Tcl_GetChannelInstanceData(chan))->ctx;
     } else {
-	if ((ctx = CTX_Init(statePtr, server, proto, key, cert, CAdir, CAfile, ciphers,
-		DHparams)) == (SSL_CTX*)0) {
+	if ((ctx = CTX_Init(statePtr, server, proto, keyfile, certfile, key,
+    cert, key_len, cert_len, CAdir, CAfile, ciphers,
+    DHparams)) == (SSL_CTX*)0) {
 	    Tls_Free((char *) statePtr);
 	    return TCL_ERROR;
 	}
     }
 
@@ -1054,16 +1064,21 @@
  *
  *-------------------------------------------------------------------
  */
 
 static SSL_CTX *
-CTX_Init(statePtr, isServer, proto, key, cert, CAdir, CAfile, ciphers, DHparams)
+CTX_Init(statePtr, isServer, proto, keyfile, certfile, key, cert,
+         key_len, cert_len, CAdir, CAfile, ciphers, DHparams)
     State *statePtr;
     int isServer;
     int proto;
-    char *key;
-    char *cert;
+    char *keyfile;
+    char *certfile;
+    unsigned char *key;
+    unsigned char *cert;
+    int key_len;
+    int cert_len;
     char *CAdir;
     char *CAfile;
     char *ciphers;
     char *DHparams;
 {
@@ -1070,10 +1085,11 @@
     Tcl_Interp *interp = statePtr->interp;
     SSL_CTX *ctx = NULL;
     Tcl_DString ds;
     Tcl_DString ds1;
     int off = 0;
+    int load_private_key;
     const SSL_METHOD *method;
 
     dprintf("Called");
 
     if (!proto) {
@@ -1249,63 +1265,99 @@
 	DH_free(dh);
     }
 #endif
 
     /* set our certificate */
-    if (cert != NULL) {
-	Tcl_DStringInit(&ds);
-
-	if (SSL_CTX_use_certificate_file(ctx, F2N( cert, &ds),
-					SSL_FILETYPE_PEM) <= 0) {
-	    Tcl_DStringFree(&ds);
-	    Tcl_AppendResult(interp,
-			     "unable to set certificate file ", cert, ": ",
-			     REASON(), (char *) NULL);
-	    SSL_CTX_free(ctx);
-	    return (SSL_CTX *)0;
-	}
-
-	/* get the private key associated with this certificate */
-	if (key == NULL) key=cert;
-
-	if (SSL_CTX_use_PrivateKey_file(ctx, F2N( key, &ds),
-					SSL_FILETYPE_PEM) <= 0) {
-	    Tcl_DStringFree(&ds);
-	    /* flush the passphrase which might be left in the result */
-	    Tcl_SetResult(interp, NULL, TCL_STATIC);
-	    Tcl_AppendResult(interp,
-			     "unable to set public key file ", key, " ",
-			     REASON(), (char *) NULL);
-	    SSL_CTX_free(ctx);
-	    return (SSL_CTX *)0;
-	}
-	Tcl_DStringFree(&ds);
+    load_private_key = 0;
+    if (certfile != NULL) {
+	load_private_key = 1;
+
+	Tcl_DStringInit(&ds);
+
+	if (SSL_CTX_use_certificate_file(ctx, F2N( certfile, &ds),
+					SSL_FILETYPE_PEM) <= 0) {
+	    Tcl_DStringFree(&ds);
+	    Tcl_AppendResult(interp,
+			     "unable to set certificate file ", certfile, ": ",
+			     REASON(), (char *) NULL);
+	    SSL_CTX_free(ctx);
+	    return (SSL_CTX *)0;
+	}
+    } else if (cert != NULL) {
+	load_private_key = 1;
+	if (SSL_CTX_use_certificate_ASN1(ctx, cert_len, cert) <= 0) {
+	    Tcl_DStringFree(&ds);
+	    Tcl_AppendResult(interp,
+			     "unable to set certificate: ",
+			     REASON(), (char *) NULL);
+	    SSL_CTX_free(ctx);
+	    return (SSL_CTX *)0;
+	}
+    } else {
+	certfile = (char*)X509_get_default_cert_file();
+
+	if (SSL_CTX_use_certificate_file(ctx, certfile,
+					SSL_FILETYPE_PEM) <= 0) {
+#if 0
+	    Tcl_DStringFree(&ds);
+	    Tcl_AppendResult(interp,
+			     "unable to use default certificate file ", certfile, ": ",
+			     REASON(), (char *) NULL);
+	    SSL_CTX_free(ctx);
+	    return (SSL_CTX *)0;
+#endif
+	}
+    }
+
+    /* set our private key */
+    if (load_private_key) {
+	if (keyfile == NULL && key == NULL) {
+	    keyfile = certfile;
+	}
+
+	if (keyfile != NULL) {
+	    /* get the private key associated with this certificate */
+	    if (keyfile == NULL) {
+		keyfile = certfile;
+	    }
+
+	    if (SSL_CTX_use_PrivateKey_file(ctx, F2N( keyfile, &ds), SSL_FILETYPE_PEM) <= 0) {
+		Tcl_DStringFree(&ds);
+		/* flush the passphrase which might be left in the result */
+		Tcl_SetResult(interp, NULL, TCL_STATIC);
+		Tcl_AppendResult(interp,
+			         "unable to set public key file ", keyfile, " ",
+			         REASON(), (char *) NULL);
+		SSL_CTX_free(ctx);
+		return (SSL_CTX *)0;
+	    }
+
+	    Tcl_DStringFree(&ds);
+	} else if (key != NULL) {
+	    if (SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, ctx, key,key_len) <= 0) {
+		Tcl_DStringFree(&ds);
+		/* flush the passphrase which might be left in the result */
+		Tcl_SetResult(interp, NULL, TCL_STATIC);
+		Tcl_AppendResult(interp,
+		                 "unable to set public key: ",
+		                 REASON(), (char *) NULL);
+		SSL_CTX_free(ctx);
+		return (SSL_CTX *)0;
+	    }
+	}
 	/* Now we know that a key and cert have been set against
 	 * the SSL context */
 	if (!SSL_CTX_check_private_key(ctx)) {
 	    Tcl_AppendResult(interp,
 			     "private key does not match the certificate public key",
 			     (char *) NULL);
 	    SSL_CTX_free(ctx);
 	    return (SSL_CTX *)0;
 	}
-    } else {
-	cert = (char*)X509_get_default_cert_file();
-
-	if (SSL_CTX_use_certificate_file(ctx, cert,
-					SSL_FILETYPE_PEM) <= 0) {
-#if 0
-	    Tcl_DStringFree(&ds);
-	    Tcl_AppendResult(interp,
-			     "unable to use default certificate file ", cert, ": ",
-			     REASON(), (char *) NULL);
-	    SSL_CTX_free(ctx);
-	    return (SSL_CTX *)0;
-#endif
-	}
-    }
-	
+    }
+
+    /* Set verification CAs */
     Tcl_DStringInit(&ds);
     Tcl_DStringInit(&ds1);
     if (!SSL_CTX_load_verify_locations(ctx, F2N(CAfile, &ds), F2N(CAdir, &ds1)) ||
 	!SSL_CTX_set_default_verify_paths(ctx)) {
 #if 0
@@ -1318,10 +1370,11 @@
 	return (SSL_CTX *)0;
 #endif
     }
 
     /* https://sourceforge.net/p/tls/bugs/57/ */
+    /* XXX:TODO: Let the user supply values here instead of something that exists on the filesystem */
     if ( CAfile != NULL ) {
         STACK_OF(X509_NAME) *certNames = SSL_load_client_CA_file( F2N(CAfile, &ds) );
 	if ( certNames != NULL ) { 
 	    SSL_CTX_set_client_CA_list(ctx, certNames );
 	}

Index: tls.htm
==================================================================
--- tls.htm
+++ tls.htm
@@ -165,11 +165,13 @@
         <dt><strong>-cadir</strong> <em>dir</em></dt>
         <dd>Provide the directory containing the CA certificates.</dd>
         <dt><strong>-cafile </strong><em>filename</em></dt>
         <dd>Provide the CA file.</dd>
         <dt><strong>-certfile</strong> <em>filename</em></dt>
-        <dd>Provide the certificate to use.</dd>
+        <dd>Provide the name of a file containing certificate to use.</dd>
+        <dt><strong>-cert</strong> <em>filename</em></dt>
+        <dd>Provide the contents of a certificate to use, as a DER encoded binary value (X.509 DER).</dd>
         <dt><strong>-cipher </strong><em>string</em></dt>
         <dd>Provide the cipher suites to use. Syntax is as per
             OpenSSL.</dd>
         <dt><strong>-command</strong> <em>callback</em></dt>
         <dd>If specified, this callback will be invoked at several points
@@ -183,10 +185,12 @@
         <dt><strong>-dhparams </strong><em>filename</em></dt>
         <dd>Provide a Diffie-Hellman parameters file.</dd>
         <dt><strong>-keyfile</strong> <em>filename</em></dt>
         <dd>Provide the private key file. (<strong>default</strong>:
             value of -certfile)</dd>
+        <dt><strong>-key</strong> <em>filename</em></dt>
+        <dd>Provide the private key to use as a DER encoded value (PKCS#1 DER)</dd>
         <dt><strong>-model</strong> <em>channel</em></dt>
         <dd>This will force this channel to share the same <em><strong>SSL_CTX</strong></em>
             structure as the specified <em>channel</em>, and
             therefore share callbacks etc.</dd>
         <dt><strong>-password</strong> <em>callback</em></dt>

Index: tls.tcl
==================================================================
--- tls.tcl
+++ tls.tcl
@@ -32,14 +32,16 @@
         {* -myaddr sopts 1}
         {0 -myport sopts 1}
         {* -type sopts 1}
         {* -cadir iopts 1}
         {* -cafile iopts 1}
+        {* -cert iopts 1}
         {* -certfile iopts 1}
         {* -cipher iopts 1}
         {* -command iopts 1}
         {* -dhparams iopts 1}
+        {* -key iopts 1}
         {* -keyfile iopts 1}
         {* -password iopts 1}
         {* -request iopts 1}
         {* -require iopts 1}
         {* -autoservername discardOpts 1}