Skip to content

Instantly share code, notes, and snippets.

@franziskuskiefer
Last active July 16, 2016 13:28
Show Gist options
  • Save franziskuskiefer/ae09cfc0909922e6122de2cf61a237d0 to your computer and use it in GitHub Desktop.
Save franziskuskiefer/ae09cfc0909922e6122de2cf61a237d0 to your computer and use it in GitHub Desktop.
TLS 1.3 for mod_nss
diff --git a/Makefile.am b/Makefile.am
index c57cd09..b3e8451 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,7 +22,7 @@ libmodnss_la_LDFLAGS = -module -avoid-version
## Set the includes and libraries needed
AM_CPPFLAGS = -I@apache_inc@ @nspr_inc@ @nss_inc@ @apr_inc@
-LIBS = @nspr_lib@ @nss_lib@ -lssl3 -lsmime3 -lnss3 -lplc4 -lplds4 -lnspr4
+LIBS = @nspr_lib@ @nss_lib@ -lssl3 -lsmime3 -lnss3 -lplc4 -lplds4 -lnspr4 -lnssutil3
EXTRA_CPPFLAGS=@extra_cppflags@
install-libLTLIBRARIES: libmodnss.la
diff --git a/nss_engine_cipher.c b/nss_engine_cipher.c
index 714c4ed..94b53e8 100644
--- a/nss_engine_cipher.c
+++ b/nss_engine_cipher.c
@@ -165,11 +165,11 @@ int nss_parse_ciphers(server_rec *s, char *ciphers, PRBool cipher_list[ciphernum
rv = parse_nss_ciphers(s, ciphers, cipher_list);
} else {
rv = parse_openssl_ciphers(s, ciphers, cipher_list);
- if (rv == 0 && 0 == countciphers(cipher_list, SSLV3|TLSV1|TLSV1_2)) {
+ if (rv == 0 && 0 == countciphers(cipher_list, SSLV3|TLSV1|TLSV1_2|TLSV1_3)) {
rv = parse_nss_ciphers(s, ciphers, cipher_list);
}
}
- if (0 == countciphers(cipher_list, SSLV3|TLSV1|TLSV1_2)) {
+ if (0 == countciphers(cipher_list, SSLV3|TLSV1|TLSV1_2|TLSV1_3)) {
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
"no cipher match");
}
@@ -399,6 +399,8 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis
protocol |= TLSV1;
} else if (!strcmp(cipher, "TLSv1.2")) {
protocol |= TLSV1_2;
+ } else if (!strcmp(cipher, "TLSv1.3")) {
+ protocol |= TLSV1_3;
} else if (!strcmp(cipher, "HIGH")) {
strength |= SSL_HIGH;
} else if (!strcmp(cipher, "MEDIUM")) {
@@ -486,7 +488,7 @@ static int parse_openssl_ciphers(server_rec *s, char *ciphers, PRBool cipher_lis
cipher = ciphers;
}
- if (found && 0 == countciphers(cipher_list, SSLV3|TLSV1|TLSV1_2))
+ if (found && 0 == countciphers(cipher_list, SSLV3|TLSV1|TLSV1_2|TLSV1_3))
return 1; /* no matching ciphers */
return 0;
}
diff --git a/nss_engine_cipher.h b/nss_engine_cipher.h
index f76099f..b7819be 100644
--- a/nss_engine_cipher.h
+++ b/nss_engine_cipher.h
@@ -83,6 +83,7 @@ typedef struct
#define SSLV3 0x00000002L
#define TLSV1 SSLV3
#define TLSV1_2 0x00000004L
+#define TLSV1_3 0x00000005L
/* the table itself is defined in nss_engine_cipher.c */
#if 0
diff --git a/nss_engine_init.c b/nss_engine_init.c
index cd71989..5cfb7ca 100644
--- a/nss_engine_init.c
+++ b/nss_engine_init.c
@@ -669,6 +669,7 @@ static void nss_init_ctx_socket(server_rec *s,
nss_die();
}
}
+
#ifdef SSL_ENABLE_RENEGOTIATION
if (SSL_OptionSet(mctx->model, SSL_ENABLE_RENEGOTIATION,
mctx->enablerenegotiation ?
@@ -694,13 +695,13 @@ static void nss_init_ctx_protocol(server_rec *s,
apr_pool_t *ptemp,
modnss_ctx_t *mctx)
{
- int ssl3, tls, tls1_1, tls1_2;
+ int ssl3, tls, tls1_1, tls1_2, tls1_3;
char *protocol_marker = NULL;
char *lprotocols = NULL;
SECStatus stat;
SSLVersionRange enabledVersions;
- ssl3 = tls = tls1_1 = tls1_2 = 0;
+ ssl3 = tls = tls1_1 = tls1_2 = tls1_3 = 0;
/*
* Since this routine will be invoked individually for every thread
@@ -718,15 +719,15 @@ static void nss_init_ctx_protocol(server_rec *s,
if (mctx->auth.protocols == NULL) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
- "%s value not set; using: TLSv1.0, TLSv1.1 and TLSv1.2",
+ "%s value not set; using: TLSv1.0, TLSv1.1, TLSv1.2, and TLSv1.3",
protocol_marker);
- tls = tls1_1 = tls1_2 = 1;
+ tls = tls1_1 = tls1_2 = tls1_3 = 1;
} else {
lprotocols = strdup(mctx->auth.protocols);
ap_str_tolower(lprotocols);
if (strstr(lprotocols, "all") != NULL) {
- ssl3 = tls = tls1_1 = tls1_2 = 1;
+ ssl3 = tls = tls1_1 = tls1_2 = tls1_3 = 1;
} else {
char *protocol_list = NULL;
char *saveptr = NULL;
@@ -774,6 +775,11 @@ static void nss_init_ctx_protocol(server_rec *s,
"%s: Enabling TLSv1.2",
protocol_marker);
tls1_2 = 1;
+ } else if (strcmp(token, "tlsv1.3") == 0) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "%s: Enabling TLSv1.3",
+ protocol_marker);
+ tls1_3 = 1;
} else {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
"%s: Unknown protocol '%s' not supported",
@@ -788,11 +794,11 @@ static void nss_init_ctx_protocol(server_rec *s,
* if FIPS mode is enabled with no TLS protocols,
* enable ALL TLS protocols.
*/
- if ((mctx->sc->fips) && (tls == 0) && (tls1_1 == 0) && (tls1_2 == 0)) {
+ if ((mctx->sc->fips) && (tls == 0) && (tls1_1 == 0) && (tls1_2 == 0) && (tls1_3 == 0)) {
ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
"%s: FIPS mode no valid protocols set, enabling TLSv1.0, TLSv1.1 and TLSv1.2",
protocol_marker);
- tls = tls1_1 = tls1_2 = 1;
+ tls = tls1_1 = tls1_2 = tls1_3 = 1;
}
}
@@ -820,7 +826,7 @@ static void nss_init_ctx_protocol(server_rec *s,
if (stat == SECSuccess) {
/* Set minimum protocol version (lowest -> highest)
*
- * SSL 3.0 -> TLS 1.0 -> TLS 1.1 -> TLS 1.2
+ * SSL 3.0 -> TLS 1.0 -> TLS 1.1 -> TLS 1.2 -> TLS 1.3
*/
if (ssl3 == 1) {
enabledVersions.min = SSL_LIBRARY_VERSION_3_0;
@@ -842,6 +848,11 @@ static void nss_init_ctx_protocol(server_rec *s,
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"%s: [TLS 1.2] (minimum)",
protocol_marker);
+ } else if (tls1_3 == 1) {
+ enabledVersions.min = SSL_LIBRARY_VERSION_TLS_1_3;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "%s: [TLS 1.3] (minimum)",
+ protocol_marker);
} else {
/* Set default minimum protocol version to SSL 3.0 */
enabledVersions.min = SSL_LIBRARY_VERSION_3_0;
@@ -852,9 +863,14 @@ static void nss_init_ctx_protocol(server_rec *s,
/* Set maximum protocol version (highest -> lowest)
*
- * TLS 1.2 -> TLS 1.1 -> TLS 1.0 -> SSL 3.0
+ * TLS 1.3 -> TLS 1.2 -> TLS 1.1 -> TLS 1.0 -> SSL 3.0
*/
- if (tls1_2 == 1) {
+ if (tls1_3 == 1) {
+ enabledVersions.max = SSL_LIBRARY_VERSION_TLS_1_3;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "%s: [TLS 1.3] (maximum)",
+ protocol_marker);
+ } else if (tls1_2 == 1) {
enabledVersions.max = SSL_LIBRARY_VERSION_TLS_1_2;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"%s: [TLS 1.2] (maximum)",
@@ -894,7 +910,7 @@ static void nss_init_ctx_protocol(server_rec *s,
}
mctx->ssl3 = ssl3;
- mctx->tls = tls || tls1_1 || tls1_2;
+ mctx->tls = tls || tls1_1 || tls1_2 || tls1_3;
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"%sabling TLS Session Tickets", mctx->sc->session_tickets == PR_TRUE ? "En" : "Dis");
@@ -905,6 +921,17 @@ static void nss_init_ctx_protocol(server_rec *s,
nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
nss_die();
}
+
+ /* always enable 0-RTT for TLS 1.3 */
+ if (enabledVersions.max >= SSL_LIBRARY_VERSION_TLS_1_3) {
+ if (SSL_OptionSet(mctx->model, SSL_ENABLE_0RTT_DATA, PR_TRUE) != SECSuccess) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ "Unable to enable 0-RTT");
+ nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
+ nss_die();
+ }
+ }
+
#ifdef ENABLE_SERVER_DHE
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"Enabling DHE key exchange");
diff --git a/nss_engine_vars.c b/nss_engine_vars.c
index d434646..01bfaab 100644
--- a/nss_engine_vars.c
+++ b/nss_engine_vars.c
@@ -775,6 +775,9 @@ static char *nss_var_lookup_protocol_version(apr_pool_t *p, conn_rec *c)
case SSL_LIBRARY_VERSION_TLS_1_2:
result = "TLSv1.2";
break;
+ case SSL_LIBRARY_VERSION_TLS_1_3:
+ result = "TLSv1.3";
+ break;
}
}
}
@franziskuskiefer
Copy link
Author

franziskuskiefer commented Jul 16, 2016

Get mod_nss, apply this patch, configure and build it.

autoreconf -ivf
./configure --with-apxs[=/path/to/apxs/] --with-nspr=/path/to/nspr/ --with-nss=/path/to/nss/
gmake all install

Make sure

  • -DENABLE_GCM is set in the Makefile after running configure
  • a recent enough version of NSS is installed

Write a config (or use make tests to get one generated)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment