• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff -pu a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c
2--- a/nss/lib/ssl/ssl3con.c	2014-01-17 18:46:51.999581198 -0800
3+++ b/nss/lib/ssl/ssl3con.c	2014-01-17 18:47:05.509804656 -0800
4@@ -3473,6 +3473,9 @@ ssl3_HandleAlert(sslSocket *ss, sslBuffe
5     case certificate_unknown: 	error = SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT;
6 			        					  break;
7     case illegal_parameter: 	error = SSL_ERROR_ILLEGAL_PARAMETER_ALERT;break;
8+    case inappropriate_fallback:
9+        error = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
10+        break;
11
12     /* All alerts below are TLS only. */
13     case unknown_ca: 		error = SSL_ERROR_UNKNOWN_CA_ALERT;       break;
14@@ -4986,6 +4989,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
15     int              num_suites;
16     int              actual_count = 0;
17     PRBool           isTLS = PR_FALSE;
18+    PRBool           requestingResume = PR_FALSE, fallbackSCSV = PR_FALSE;
19     PRInt32          total_exten_len = 0;
20     unsigned         paddingExtensionLen;
21     unsigned         numCompressionMethods;
22@@ -5128,6 +5132,7 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
23     }
24
25     if (sid) {
26+	requestingResume = PR_TRUE;
27 	SSL_AtomicIncrementLong(& ssl3stats.sch_sid_cache_hits );
28
29 	PRINT_BUF(4, (ss, "client, found session-id:", sid->u.ssl3.sessionID,
30@@ -5246,8 +5251,15 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
31     	if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
32     	return SECFailure;	/* count_cipher_suites has set error code. */
33     }
34+
35+    fallbackSCSV = ss->opt.enableFallbackSCSV && (!requestingResume ||
36+						  ss->version < sid->version);
37+    /* make room for SCSV */
38     if (ss->ssl3.hs.sendingSCSV) {
39-	++num_suites;   /* make room for SCSV */
40+	++num_suites;
41+    }
42+    if (fallbackSCSV) {
43+	++num_suites;
44     }
45
46     /* count compression methods */
47@@ -5353,6 +5365,15 @@ ssl3_SendClientHello(sslSocket *ss, PRBo
48 	}
49 	actual_count++;
50     }
51+    if (fallbackSCSV) {
52+	rv = ssl3_AppendHandshakeNumber(ss, TLS_FALLBACK_SCSV,
53+					sizeof(ssl3CipherSuite));
54+	if (rv != SECSuccess) {
55+	    if (sid->u.ssl3.lock) { PR_RWLock_Unlock(sid->u.ssl3.lock); }
56+	    return rv;	/* err set by ssl3_AppendHandshake* */
57+	}
58+	actual_count++;
59+    }
60     for (i = 0; i < ssl_V3_SUITES_IMPLEMENTED; i++) {
61 	ssl3CipherSuiteCfg *suite = &ss->cipherSuites[i];
62 	if (config_match(suite, ss->ssl3.policy, PR_TRUE, &ss->vrange)) {
63@@ -8084,6 +8105,19 @@ ssl3_HandleClientHello(sslSocket *ss, SS
64 	goto loser;		/* malformed */
65     }
66
67+    /* If the ClientHello version is less than our maximum version, check for a
68+     * TLS_FALLBACK_SCSV and reject the connection if found. */
69+    if (ss->vrange.max > ss->clientHelloVersion) {
70+	for (i = 0; i + 1 < suites.len; i += 2) {
71+	    PRUint16 suite_i = (suites.data[i] << 8) | suites.data[i + 1];
72+	    if (suite_i != TLS_FALLBACK_SCSV)
73+		continue;
74+	    desc = inappropriate_fallback;
75+	    errCode = SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT;
76+	    goto alert_loser;
77+	}
78+    }
79+
80     /* grab the list of compression methods. */
81     rv = ssl3_ConsumeHandshakeVariable(ss, &comps, 1, &b, &length);
82     if (rv != SECSuccess) {
83diff -pu a/nss/lib/ssl/ssl3prot.h b/nss/lib/ssl/ssl3prot.h
84--- a/nss/lib/ssl/ssl3prot.h	2014-01-17 17:59:03.242109996 -0800
85+++ b/nss/lib/ssl/ssl3prot.h	2014-01-17 18:47:05.509804656 -0800
86@@ -98,6 +98,7 @@ typedef enum {
87     protocol_version        = 70,
88     insufficient_security   = 71,
89     internal_error          = 80,
90+    inappropriate_fallback  = 86,	/* could also be sent for SSLv3 */
91     user_canceled           = 90,
92     no_renegotiation        = 100,
93
94diff -pu a/nss/lib/ssl/sslerr.h b/nss/lib/ssl/sslerr.h
95--- a/nss/lib/ssl/sslerr.h	2014-01-17 17:59:03.242109996 -0800
96+++ b/nss/lib/ssl/sslerr.h	2014-01-17 18:47:05.509804656 -0800
97@@ -196,6 +196,7 @@ SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM
98 SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 129),
99 SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 130),
100 SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 131),
101+SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 132),
102
103 SSL_ERROR_END_OF_LIST	/* let the c compiler determine the value of this. */
104 } SSLErrorCodes;
105diff -pu a/nss/lib/ssl/SSLerrs.h b/nss/lib/ssl/SSLerrs.h
106--- a/nss/lib/ssl/SSLerrs.h	2014-01-17 17:59:03.242109996 -0800
107+++ b/nss/lib/ssl/SSLerrs.h	2014-01-17 18:47:05.509804656 -0800
108@@ -421,3 +421,8 @@ ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (S
109
110 ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 131),
111 "The application could not get a TLS Channel ID.")
112+
113+ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 132),
114+"The connection was using a lesser TLS version as a result of a previous"
115+" handshake failure, but the server indicated that it should not have been"
116+" needed.")
117diff -pu a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h
118--- a/nss/lib/ssl/ssl.h	2014-01-17 18:46:51.999581198 -0800
119+++ b/nss/lib/ssl/ssl.h	2014-01-17 18:48:54.971613341 -0800
120@@ -183,6 +183,8 @@ SSL_IMPORT PRFileDesc *DTLS_ImportFD(PRF
121
122 /* Request Signed Certificate Timestamps via TLS extension (client) */
123 #define SSL_ENABLE_SIGNED_CERT_TIMESTAMPS 27
124+#define SSL_ENABLE_FALLBACK_SCSV       28 /* Send fallback SCSV in
125+                                           * handshakes. */
126
127 #ifdef SSL_DEPRECATED_FUNCTION
128 /* Old deprecated function names */
129diff -pu a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h
130--- a/nss/lib/ssl/sslimpl.h	2014-01-17 18:46:51.999581198 -0800
131+++ b/nss/lib/ssl/sslimpl.h	2014-01-17 18:51:17.963962287 -0800
132@@ -338,6 +338,7 @@ typedef struct sslOptionsStr {
133     unsigned int enableNPN              : 1;  /* 26 */
134     unsigned int enableALPN             : 1;  /* 27 */
135     unsigned int enableSignedCertTimestamps : 1;  /* 28 */
136+    unsigned int enableFallbackSCSV     : 1;  /* 29 */
137 } sslOptions;
138
139 typedef enum { sslHandshakingUndetermined = 0,
140diff -pu a/nss/lib/ssl/sslproto.h b/nss/lib/ssl/sslproto.h
141--- a/nss/lib/ssl/sslproto.h	2014-01-17 18:10:16.793281867 -0800
142+++ b/nss/lib/ssl/sslproto.h	2014-01-17 18:47:05.509804656 -0800
143@@ -172,6 +172,11 @@
144  */
145 #define TLS_EMPTY_RENEGOTIATION_INFO_SCSV	0x00FF
146
147+/* TLS_FALLBACK_SCSV is a signaling cipher suite value that indicates that a
148+ * handshake is the result of TLS version fallback. This value is not IANA
149+ * assigned. */
150+#define TLS_FALLBACK_SCSV			0x5600
151+
152 /* Cipher Suite Values starting with 0xC000 are defined in informational
153  * RFCs.
154  */
155diff -pu a/nss/lib/ssl/sslsock.c b/nss/lib/ssl/sslsock.c
156--- a/nss/lib/ssl/sslsock.c	2014-01-17 18:46:52.009581364 -0800
157+++ b/nss/lib/ssl/sslsock.c	2014-01-17 18:59:17.931852364 -0800
158@@ -88,7 +88,8 @@ static sslOptions ssl_defaults = {
159     PR_FALSE,   /* enableOCSPStapling */
160     PR_TRUE,    /* enableNPN          */
161     PR_FALSE,   /* enableALPN         */
162-    PR_FALSE    /* enableSignedCertTimestamps */
163+    PR_FALSE,   /* enableSignedCertTimestamps */
164+    PR_FALSE    /* enableFallbackSCSV */
165 };
166
167 /*
168@@ -792,6 +793,10 @@ SSL_OptionSet(PRFileDesc *fd, PRInt32 wh
169 	ss->opt.enableSignedCertTimestamps = on;
170 	break;
171
172+      case SSL_ENABLE_FALLBACK_SCSV:
173+       ss->opt.enableFallbackSCSV = on;
174+       break;
175+
176       default:
177 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
178 	rv = SECFailure;
179@@ -867,6 +872,7 @@ SSL_OptionGet(PRFileDesc *fd, PRInt32 wh
180     case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
181 	on = ss->opt.enableSignedCertTimestamps;
182 	break;
183+    case SSL_ENABLE_FALLBACK_SCSV: on = ss->opt.enableFallbackSCSV; break;
184
185     default:
186 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
187@@ -933,6 +939,9 @@ SSL_OptionGetDefault(PRInt32 which, PRBo
188     case SSL_ENABLE_SIGNED_CERT_TIMESTAMPS:
189 	on = ssl_defaults.enableSignedCertTimestamps;
190 	break;
191+    case SSL_ENABLE_FALLBACK_SCSV:
192+	on = ssl_defaults.enableFallbackSCSV;
193+	break;
194
195     default:
196 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
197@@ -1112,6 +1121,10 @@ SSL_OptionSetDefault(PRInt32 which, PRBo
198 	ssl_defaults.enableSignedCertTimestamps = on;
199 	break;
200
201+      case SSL_ENABLE_FALLBACK_SCSV:
202+       ssl_defaults.enableFallbackSCSV = on;
203+       break;
204+
205       default:
206 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
207 	return SECFailure;
208