Check-in [737b9c0d46]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merged in TLS 1.3 support
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:737b9c0d466d2f2964a8b2beea2544c991e81ccc6b732b3f8572d322c135f8fa
User & Date: rkeene 2019-04-09 17:55:44
Context
2019-04-09
18:13
Document the "certificate" member of the dictionary returned by "tls::status" check-in: 3323193385 user: rkeene tags: trunk
17:56
Merged in changes from trunk check-in: 03a182febb user: rkeene tags: tls-1-7
17:55
Merged in TLS 1.3 support check-in: 737b9c0d46 user: rkeene tags: trunk
17:25
Better handling of reading certificate PEM data, resolves [2059171e7d] check-in: 8e0ed4e723 user: rkeene tags: trunk
17:04
Added remaining TLSv1.3 support Closed-Leaf check-in: 569c10f3b2 user: rkeene tags: enhancement/tls-1.3
Changes

Changes to aclocal/tcltls_openssl.m4.

     1      1   dnl $1 = Name of variable
     2      2   dnl $2 = Name of function to check for
     3      3   dnl $3 = Name of protocol
     4      4   dnl $4 = Name of CPP macro to define
            5  +dnl $5 = Name of CPP macro to check for instead of a function
     5      6   AC_DEFUN([TCLTLS_SSL_OPENSSL_CHECK_PROTO_VER], [
     6      7   	dnl Determine if particular SSL version is enabled
     7      8   	if test "[$]$1" = "true" -o "[$]$1" = "force"; then
     8         -		AC_CHECK_FUNC($2,, [
            9  +		proto_check='true'
           10  +		ifelse($5,, [
           11  +			AC_CHECK_FUNC($2,, [
           12  +				proto_check='false'
           13  +			])
           14  +		], [
           15  +			AC_LANG_PUSH(C)
           16  +			AC_MSG_CHECKING([for $3 protocol support])
           17  +			AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
           18  +#include <openssl/ssl.h>
           19  +#include <openssl/opensslv.h>
           20  +#if (SSLEAY_VERSION_NUMBER >= 0x0907000L)
           21  +# include <openssl/conf.h>
           22  +#endif
           23  +			], [
           24  +int x = $5;
           25  +			])], [
           26  +				AC_MSG_RESULT([yes])
           27  +			], [
           28  +				AC_MSG_RESULT([no])
           29  +
           30  +				proto_check='false'
           31  +			])
           32  +			AC_LANG_POP([C])
           33  +		])
           34  +
           35  +		if test "$proto_check" = 'false'; then
     9     36   			if test "[$]$1" = "force"; then
    10     37   				AC_MSG_ERROR([Unable to enable $3])
    11     38   			fi
    12     39   
    13     40   			$1='false'
    14         -		])
           41  +		fi
    15     42   	fi
    16     43   
    17     44   	if test "[$]$1" = "false"; then
    18     45   		AC_DEFINE($4, [1], [Define this to disable $3 in OpenSSL support])
    19     46   	fi
    20     47   
    21     48   ])
................................................................................
   151    178   		AC_MSG_RESULT([yes])
   152    179   	], [
   153    180   		AC_MSG_RESULT([no])
   154    181   		AC_MSG_ERROR([Unable to compile a basic program using OpenSSL])
   155    182   	])
   156    183   	AC_LANG_POP([C])
   157    184   
          185  +	AC_CHECK_FUNCS([TLS_method])
   158    186   	TCLTLS_SSL_OPENSSL_CHECK_PROTO_VER([tcltls_ssl_ssl2], [SSLv2_method], [sslv2], [NO_SSL2])
   159    187   	TCLTLS_SSL_OPENSSL_CHECK_PROTO_VER([tcltls_ssl_ssl3], [SSLv3_method], [sslv3], [NO_SSL3])
   160    188   	TCLTLS_SSL_OPENSSL_CHECK_PROTO_VER([tcltls_ssl_tls1_0], [TLSv1_method], [tlsv1.0], [NO_TLS1])
   161    189   	TCLTLS_SSL_OPENSSL_CHECK_PROTO_VER([tcltls_ssl_tls1_1], [TLSv1_1_method], [tlsv1.1], [NO_TLS1_1])
   162    190   	TCLTLS_SSL_OPENSSL_CHECK_PROTO_VER([tcltls_ssl_tls1_2], [TLSv1_2_method], [tlsv1.2], [NO_TLS1_2])
          191  +	TCLTLS_SSL_OPENSSL_CHECK_PROTO_VER([tcltls_ssl_tls1_3], [], [tlsv1.3], [NO_TLS1_3], [SSL_OP_NO_TLSv1_3])
   163    192   
   164    193   	AC_CACHE_VAL([tcltls_cv_func_tlsext_hostname], [
   165    194   		AC_LANG_PUSH(C)
   166    195   		AC_MSG_CHECKING([for SSL_set_tlsext_host_name])
   167    196   		AC_LINK_IFELSE([AC_LANG_PROGRAM([
   168    197   #include <openssl/ssl.h>
   169    198   #if (SSLEAY_VERSION_NUMBER >= 0x0907000L)

Changes to configure.ac.

   106    106   	if test "$enableval" = "yes"; then
   107    107   		tcltls_ssl_tls1_1='force'
   108    108   	else
   109    109   		tcltls_ssl_tls1_1='false'
   110    110   	fi
   111    111   ])
   112    112   
   113         -dnl ## TLSv1.1: Enabled by default
          113  +dnl ## TLSv1.2: Enabled by default
   114    114   tcltls_ssl_tls1_2='true'
   115    115   AC_ARG_ENABLE([tlsv1.2], AS_HELP_STRING([--disable-tlsv1.2], [disable TLSv1.2 protocol]), [
   116    116   	if test "$enableval" = "yes"; then
   117    117   		tcltls_ssl_tls1_2='force'
   118    118   	else
   119    119   		tcltls_ssl_tls1_2='false'
   120    120   	fi
   121    121   ])
          122  +
          123  +dnl ## TLSv1.3: Enabled by default
          124  +tcltls_ssl_tls1_3='true'
          125  +AC_ARG_ENABLE([tlsv1.3], AS_HELP_STRING([--disable-tlsv1.3], [disable TLSv1.3 protocol]), [
          126  +	if test "$enableval" = "yes"; then
          127  +		tcltls_ssl_tls1_3='force'
          128  +	else
          129  +		tcltls_ssl_tls1_3='false'
          130  +	fi
          131  +])
          132  +
   122    133   
   123    134   dnl Enable support for a debugging build
   124    135   tcltls_debug='false'
   125    136   AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [enable debugging parameters]), [
   126    137   	if test "$enableval" = "yes"; then
   127    138   		tcltls_debug='true'
   128    139   	fi

Changes to tls.c.

    57     57   
    58     58   static int	MiscObjCmd(ClientData clientData,
    59     59   			Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
    60     60   
    61     61   static int	UnimportObjCmd(ClientData clientData,
    62     62   			Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]);
    63     63   
    64         -static SSL_CTX *CTX_Init(State *statePtr, int proto, char *key,
           64  +static SSL_CTX *CTX_Init(State *statePtr, int isServer, int proto, char *key,
    65     65   			char *cert, char *CAdir, char *CAfile, char *ciphers,
    66     66   			char *DHparams);
    67     67   
    68     68   static int	TlsLibInit(int uninitialize);
    69     69   
    70     70   #define TLS_PROTO_SSL2		0x01
    71     71   #define TLS_PROTO_SSL3		0x02
    72     72   #define TLS_PROTO_TLS1		0x04
    73     73   #define TLS_PROTO_TLS1_1	0x08
    74     74   #define TLS_PROTO_TLS1_2	0x10
           75  +#define TLS_PROTO_TLS1_3	0x20
    75     76   #define ENABLED(flag, mask)	(((flag) & (mask)) == (mask))
    76     77   
    77     78   /*
    78     79    * Static data structures
    79     80    */
    80     81   
    81     82   #ifndef OPENSSL_NO_DH
................................................................................
   494    495   CiphersObjCmd(clientData, interp, objc, objv)
   495    496       ClientData clientData;	/* Not used. */
   496    497       Tcl_Interp *interp;
   497    498       int objc;
   498    499       Tcl_Obj	*CONST objv[];
   499    500   {
   500    501       static CONST84 char *protocols[] = {
   501         -	"ssl2",	"ssl3",	"tls1",	"tls1.1", "tls1.2", NULL
          502  +	"ssl2",	"ssl3",	"tls1",	"tls1.1", "tls1.2", "tls1.3", NULL
   502    503       };
   503    504       enum protocol {
   504         -	TLS_SSL2, TLS_SSL3, TLS_TLS1, TLS_TLS1_1, TLS_TLS1_2, TLS_NONE
          505  +	TLS_SSL2, TLS_SSL3, TLS_TLS1, TLS_TLS1_1, TLS_TLS1_2, TLS_TLS1_3, TLS_NONE
   505    506       };
   506    507       Tcl_Obj *objPtr;
   507    508       SSL_CTX *ctx = NULL;
   508    509       SSL *ssl = NULL;
   509    510       STACK_OF(SSL_CIPHER) *sk;
   510    511       char *cp, buf[BUFSIZ];
   511    512       int index, verbose = 0;
................................................................................
   556    557       case TLS_TLS1_2:
   557    558   #if defined(NO_TLS1_2)
   558    559   		Tcl_AppendResult(interp, "protocol not supported", NULL);
   559    560   		return TCL_ERROR;
   560    561   #else
   561    562   		ctx = SSL_CTX_new(TLSv1_2_method()); break;
   562    563   #endif
          564  +    case TLS_TLS1_3:
          565  +#if defined(NO_TLS1_3)
          566  +		Tcl_AppendResult(interp, "protocol not supported", NULL);
          567  +		return TCL_ERROR;
          568  +#else
          569  +		ctx = SSL_CTX_new(TLS_method()); break;
          570  +                SSL_CTX_set_min_proto_version (ctx, TLS1_3_VERSION);
          571  +                SSL_CTX_set_max_proto_version (ctx, TLS1_3_VERSION);
          572  +#endif
   563    573       default:
   564    574   		break;
   565    575       }
   566    576       if (ctx == NULL) {
   567    577   	Tcl_AppendResult(interp, REASON(), (char *) NULL);
   568    578   	return TCL_ERROR;
   569    579       }
................................................................................
   733    743       char *CAdir		= NULL;
   734    744       char *DHparams	= NULL;
   735    745       char *model		= NULL;
   736    746   #ifndef OPENSSL_NO_TLSEXT
   737    747       char *servername	= NULL;	/* hostname for Server Name Indication */
   738    748   #endif
   739    749       int ssl2 = 0, ssl3 = 0;
   740         -    int tls1 = 1, tls1_1 = 1, tls1_2 = 1;
          750  +    int tls1 = 1, tls1_1 = 1, tls1_2 = 1, tls1_3 = 1;
   741    751       int proto = 0;
   742    752       int verify = 0, require = 0, request = 1;
   743    753   
   744    754       dprintf("Called");
   745    755   
   746    756   #if defined(NO_TLS1) && defined(NO_TLS1_1) && defined(NO_TLS1_2) && defined(NO_SSL3) && !defined(NO_SSL2)
   747    757       ssl2 = 1;
................................................................................
   753    763       tls1 = 0;
   754    764   #endif
   755    765   #if defined(NO_TLS1_1)
   756    766       tls1_1 = 0;
   757    767   #endif
   758    768   #if defined(NO_TLS1_2)
   759    769       tls1_2 = 0;
          770  +#endif
          771  +#if defined(NO_TLS1_3)
          772  +    tls1_3 = 0;
   760    773   #endif
   761    774   
   762    775       if (objc < 2) {
   763    776   	Tcl_WrongNumArgs(interp, 1, objv, "channel ?options?");
   764    777   	return TCL_ERROR;
   765    778       }
   766    779   
................................................................................
   797    810   #endif
   798    811   
   799    812   	OPTBOOL( "-ssl2", ssl2);
   800    813   	OPTBOOL( "-ssl3", ssl3);
   801    814   	OPTBOOL( "-tls1", tls1);
   802    815   	OPTBOOL( "-tls1.1", tls1_1);
   803    816   	OPTBOOL( "-tls1.2", tls1_2);
          817  +	OPTBOOL( "-tls1.3", tls1_3);
   804    818   
   805         -	OPTBAD( "option", "-cadir, -cafile, -certfile, -cipher, -command, -dhparams, -keyfile, -model, -password, -require, -request, -server, -servername, -ssl2, -ssl3, -tls1, -tls1.1 or -tls1.2");
          819  +	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");
   806    820   
   807    821   	return TCL_ERROR;
   808    822       }
   809    823       if (request)	    verify |= SSL_VERIFY_CLIENT_ONCE | SSL_VERIFY_PEER;
   810    824       if (request && require) verify |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
   811    825       if (verify == 0)	verify = SSL_VERIFY_NONE;
   812    826   
   813    827       proto |= (ssl2 ? TLS_PROTO_SSL2 : 0);
   814    828       proto |= (ssl3 ? TLS_PROTO_SSL3 : 0);
   815    829       proto |= (tls1 ? TLS_PROTO_TLS1 : 0);
   816    830       proto |= (tls1_1 ? TLS_PROTO_TLS1_1 : 0);
   817    831       proto |= (tls1_2 ? TLS_PROTO_TLS1_2 : 0);
          832  +    proto |= (tls1_3 ? TLS_PROTO_TLS1_3 : 0);
   818    833   
   819    834       /* reset to NULL if blank string provided */
   820    835       if (cert && !*cert)		cert	 = NULL;
   821    836       if (key && !*key)		key	 = NULL;
   822    837       if (ciphers && !*ciphers)	ciphers	 = NULL;
   823    838       if (CAfile && !*CAfile)	CAfile	 = NULL;
   824    839       if (CAdir && !*CAdir)	CAdir	 = NULL;
................................................................................
   868    883   	    Tcl_AppendResult(interp, "bad channel \"",
   869    884   		    Tcl_GetChannelName(chan), "\": not a TLS channel", NULL);
   870    885   	    Tls_Free((char *) statePtr);
   871    886   	    return TCL_ERROR;
   872    887   	}
   873    888   	ctx = ((State *)Tcl_GetChannelInstanceData(chan))->ctx;
   874    889       } else {
   875         -	if ((ctx = CTX_Init(statePtr, proto, key, cert, CAdir, CAfile, ciphers,
          890  +	if ((ctx = CTX_Init(statePtr, server, proto, key, cert, CAdir, CAfile, ciphers,
   876    891   		DHparams)) == (SSL_CTX*)0) {
   877    892   	    Tls_Free((char *) statePtr);
   878    893   	    return TCL_ERROR;
   879    894   	}
   880    895       }
   881    896   
   882    897       statePtr->ctx = ctx;
................................................................................
  1037   1052    * Side effects:
  1038   1053    *	constructs SSL context (CTX)
  1039   1054    *
  1040   1055    *-------------------------------------------------------------------
  1041   1056    */
  1042   1057   
  1043   1058   static SSL_CTX *
  1044         -CTX_Init(statePtr, proto, key, cert, CAdir, CAfile, ciphers, DHparams)
         1059  +CTX_Init(statePtr, isServer, proto, key, cert, CAdir, CAfile, ciphers, DHparams)
  1045   1060       State *statePtr;
         1061  +    int isServer;
  1046   1062       int proto;
  1047   1063       char *key;
  1048   1064       char *cert;
  1049   1065       char *CAdir;
  1050   1066       char *CAfile;
  1051   1067       char *ciphers;
  1052   1068       char *DHparams;
................................................................................
  1092   1108   #endif
  1093   1109   #if defined(NO_TLS1_2)
  1094   1110       if (ENABLED(proto, TLS_PROTO_TLS1_2)) {
  1095   1111   	Tcl_AppendResult(interp, "protocol not supported", NULL);
  1096   1112   	return (SSL_CTX *)0;
  1097   1113       }
  1098   1114   #endif
         1115  +#if defined(NO_TLS1_3)
         1116  +    if (ENABLED(proto, TLS_PROTO_TLS1_3)) {
         1117  +	Tcl_AppendResult(interp, "protocol not supported", NULL);
         1118  +	return (SSL_CTX *)0;
         1119  +    }
         1120  +#endif
  1099   1121   
  1100   1122       switch (proto) {
  1101   1123   #if !defined(NO_SSL2)
  1102   1124       case TLS_PROTO_SSL2:
  1103   1125   	method = SSLv2_method ();
  1104   1126   	break;
  1105   1127   #endif
................................................................................
  1118   1140   	method = TLSv1_1_method ();
  1119   1141   	break;
  1120   1142   #endif
  1121   1143   #if !defined(NO_TLS1_2)
  1122   1144       case TLS_PROTO_TLS1_2:
  1123   1145   	method = TLSv1_2_method ();
  1124   1146   	break;
         1147  +#endif
         1148  +#if !defined(NO_TLS1_3)
         1149  +    case TLS_PROTO_TLS1_3:
         1150  +        /*
         1151  +         * The version range is constrained below,
         1152  +         * after the context is created.  Use the
         1153  +         * generic method here.
         1154  +         */
         1155  +	method = TLS_method ();
         1156  +	break;
  1125   1157   #endif
  1126   1158       default:
         1159  +#ifdef HAVE_TLS_METHOD
         1160  +        method = TLS_method ();
         1161  +#else
  1127   1162           method = SSLv23_method ();
         1163  +#endif
  1128   1164   #if !defined(NO_SSL2)
  1129   1165   	off |= (ENABLED(proto, TLS_PROTO_SSL2)   ? 0 : SSL_OP_NO_SSLv2);
  1130   1166   #endif
  1131   1167   #if !defined(NO_SSL3)
  1132   1168   	off |= (ENABLED(proto, TLS_PROTO_SSL3)   ? 0 : SSL_OP_NO_SSLv3);
  1133   1169   #endif
  1134   1170   #if !defined(NO_TLS1)
................................................................................
  1136   1172   #endif
  1137   1173   #if !defined(NO_TLS1_1)
  1138   1174   	off |= (ENABLED(proto, TLS_PROTO_TLS1_1) ? 0 : SSL_OP_NO_TLSv1_1);
  1139   1175   #endif
  1140   1176   #if !defined(NO_TLS1_2)
  1141   1177   	off |= (ENABLED(proto, TLS_PROTO_TLS1_2) ? 0 : SSL_OP_NO_TLSv1_2);
  1142   1178   #endif
         1179  +#if !defined(NO_TLS1_3)
         1180  +	off |= (ENABLED(proto, TLS_PROTO_TLS1_3) ? 0 : SSL_OP_NO_TLSv1_3);
         1181  +#endif
  1143   1182   	break;
  1144   1183       }
  1145   1184       
  1146   1185       ctx = SSL_CTX_new (method);
         1186  +
         1187  +    if (!ctx) {
         1188  +        return(NULL);
         1189  +    }
         1190  +
         1191  +#if !defined(NO_TLS1_3)
         1192  +    if (proto == TLS_PROTO_TLS1_3) {
         1193  +        SSL_CTX_set_min_proto_version (ctx, TLS1_3_VERSION);
         1194  +        SSL_CTX_set_max_proto_version (ctx, TLS1_3_VERSION);
         1195  +    }
         1196  +#endif
  1147   1197       
  1148   1198       SSL_CTX_set_app_data( ctx, (VOID*)interp);	/* remember the interpreter */
  1149   1199       SSL_CTX_set_options( ctx, SSL_OP_ALL);	/* all SSL bug workarounds */
  1150   1200       SSL_CTX_set_options( ctx, off);	/* all SSL bug workarounds */
  1151   1201       SSL_CTX_sess_set_cache_size( ctx, 128);
  1152   1202   
  1153   1203       if (ciphers != NULL)

Changes to tls.htm.

   217    217           <dd>Enable use of SSL v3. (<strong>default</strong>: <em>false</em>)</dd>
   218    218           <dt>-<strong>tls1</strong> <em>bool</em></dt>
   219    219           <dd>Enable use of TLS v1. (<strong>default</strong>: <em>true</em>)</dd>
   220    220           <dt>-<strong>tls1.1</strong> <em>bool</em></dt>
   221    221           <dd>Enable use of TLS v1.1 (<strong>default</strong>: <em>true</em>)</dd>
   222    222           <dt>-<strong>tls1.2</strong> <em>bool</em></dt>
   223    223           <dd>Enable use of TLS v1.2 (<strong>default</strong>: <em>true</em>)</dd>
          224  +        <dt>-<strong>tls1.3</strong> <em>bool</em></dt>
          225  +        <dd>Enable use of TLS v1.3 (<strong>default</strong>: <em>true</em>)</dd>
   224    226       </dl>
   225    227   </blockquote>
   226    228   
   227    229   <dl>
   228    230       <dt><a name="tls::unimport"><b>tls::unimport </b><i>channel</i></a></dt>
   229    231       <dd>Provided for symmetry to <strong>tls::import</strong>, this
   230    232         unstacks the SSL-enabling of a regular Tcl channel.  An error

Changes to tls.tcl.

    45     45           {* -autoservername discardOpts 1}
    46     46           {* -servername iopts 1}
    47     47           {* -ssl2 iopts 1}
    48     48           {* -ssl3 iopts 1}
    49     49           {* -tls1 iopts 1}
    50     50           {* -tls1.1 iopts 1}
    51     51           {* -tls1.2 iopts 1}
           52  +        {* -tls1.3 iopts 1}
    52     53       }
    53     54   
    54     55       # tls::socket and tls::init options as a humane readable string
    55     56       variable socketOptionsNoServer
    56     57       variable socketOptionsServer
    57     58   
    58     59       # Internal [switch] body to validate options