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