OLD | NEW |
(Empty) | |
| 1 diff --git a/net/third_party/nss/ssl/SSLerrs.h b/net/third_party/nss/ssl/SSLerrs
.h |
| 2 index 4ff0b7d..3f0078c 100644 |
| 3 --- a/net/third_party/nss/ssl/SSLerrs.h |
| 4 +++ b/net/third_party/nss/ssl/SSLerrs.h |
| 5 @@ -413,16 +413,22 @@ ER3(SSL_ERROR_DIGEST_FAILURE, (SSL_ERROR_BASE + 127), |
| 6 ER3(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM, (SSL_ERROR_BASE + 128), |
| 7 "Incorrect signature algorithm specified in a digitally-signed element.") |
| 8 |
| 9 -ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 129), |
| 10 -"SSL received a malformed TLS Channel ID extension.") |
| 11 +ER3(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK, (SSL_ERROR_BASE + 129), |
| 12 +"The next protocol negotiation extension was enabled, but the callback was clea
red prior to being needed.") |
| 13 |
| 14 -ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 130), |
| 15 -"The application provided an invalid TLS Channel ID key.") |
| 16 +ER3(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL, (SSL_ERROR_BASE + 130), |
| 17 +"The server supports no protocols that the client advertises in the ALPN extens
ion.") |
| 18 |
| 19 -ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 131), |
| 20 -"The application could not get a TLS Channel ID.") |
| 21 - |
| 22 -ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 132), |
| 23 +ER3(SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT, (SSL_ERROR_BASE + 131), |
| 24 "The connection was using a lesser TLS version as a result of a previous" |
| 25 " handshake failure, but the server indicated that it should not have been" |
| 26 " needed.") |
| 27 + |
| 28 +ER3(SSL_ERROR_BAD_CHANNEL_ID_DATA, (SSL_ERROR_BASE + 132), |
| 29 +"SSL received a malformed TLS Channel ID extension.") |
| 30 + |
| 31 +ER3(SSL_ERROR_INVALID_CHANNEL_ID_KEY, (SSL_ERROR_BASE + 133), |
| 32 +"The application provided an invalid TLS Channel ID key.") |
| 33 + |
| 34 +ER3(SSL_ERROR_GET_CHANNEL_ID_FAILED, (SSL_ERROR_BASE + 134), |
| 35 +"The application could not get a TLS Channel ID.") |
| 36 diff --git a/net/third_party/nss/ssl/ssl3ext.c b/net/third_party/nss/ssl/ssl3ext
.c |
| 37 index 523e49a..f6530fe 100644 |
| 38 --- a/net/third_party/nss/ssl/ssl3ext.c |
| 39 +++ b/net/third_party/nss/ssl/ssl3ext.c |
| 40 @@ -56,10 +56,14 @@ static SECStatus ssl3_ClientHandleAppProtoXtn(sslSocket *ss, |
| 41 PRUint16 ex_type, SECItem *data); |
| 42 static SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, |
| 43 PRUint16 ex_type, SECItem *data); |
| 44 +static SECStatus ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, |
| 45 + SECItem *data); |
| 46 +static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, |
| 47 + PRUint32 maxBytes); |
| 48 static PRInt32 ssl3_ClientSendAppProtoXtn(sslSocket *ss, PRBool append, |
| 49 PRUint32 maxBytes); |
| 50 -static PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, |
| 51 - PRUint32 maxBytes); |
| 52 +static PRInt32 ssl3_ServerSendAppProtoXtn(sslSocket *ss, PRBool append, |
| 53 + PRUint32 maxBytes); |
| 54 static PRInt32 ssl3_SendUseSRTPXtn(sslSocket *ss, PRBool append, |
| 55 PRUint32 maxBytes); |
| 56 static SECStatus ssl3_HandleUseSRTPXtn(sslSocket * ss, PRUint16 ex_type, |
| 57 @@ -247,6 +251,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[]
= { |
| 58 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, |
| 59 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 60 { ssl_next_proto_nego_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, |
| 61 + { ssl_app_layer_protocol_xtn, &ssl3_ServerHandleAppProtoXtn }, |
| 62 { ssl_use_srtp_xtn, &ssl3_HandleUseSRTPXtn }, |
| 63 { ssl_cert_status_xtn, &ssl3_ServerHandleStatusRequestXtn }, |
| 64 { ssl_signature_algorithms_xtn, &ssl3_ServerHandleSigAlgsXtn }, |
| 65 @@ -578,7 +583,8 @@ ssl3_SendSessionTicketXtn( |
| 66 |
| 67 /* handle an incoming Next Protocol Negotiation extension. */ |
| 68 static SECStatus |
| 69 -ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *da
ta) |
| 70 +ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, |
| 71 + SECItem *data) |
| 72 { |
| 73 if (ss->firstHsDone || data->len != 0) { |
| 74 /* Clients MUST send an empty NPN extension, if any. */ |
| 75 @@ -623,14 +629,93 @@ ssl3_ValidateNextProtoNego(const unsigned char* data, unsi
gned int length) |
| 76 return SECSuccess; |
| 77 } |
| 78 |
| 79 +/* protocol selection handler for ALPN (server side) and NPN (client side) */ |
| 80 static SECStatus |
| 81 -ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, |
| 82 - SECItem *data) |
| 83 +ssl3_SelectAppProtocol(sslSocket *ss, PRUint16 ex_type, SECItem *data) |
| 84 { |
| 85 SECStatus rv; |
| 86 unsigned char resultBuffer[255]; |
| 87 SECItem result = { siBuffer, resultBuffer, 0 }; |
| 88 |
| 89 + rv = ssl3_ValidateNextProtoNego(data->data, data->len); |
| 90 + if (rv != SECSuccess) |
| 91 + return rv; |
| 92 + |
| 93 + PORT_Assert(ss->nextProtoCallback); |
| 94 + rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len, |
| 95 + result.data, &result.len, sizeof resultBuffer); |
| 96 + if (rv != SECSuccess) |
| 97 + return rv; |
| 98 + /* If the callback wrote more than allowed to |result| it has corrupted our |
| 99 + * stack. */ |
| 100 + if (result.len > sizeof resultBuffer) { |
| 101 + PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
| 102 + return SECFailure; |
| 103 + } |
| 104 + |
| 105 + if (ex_type == ssl_app_layer_protocol_xtn && |
| 106 + ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NEGOTIATED) { |
| 107 + /* The callback might say OK, but then it's picked a default. |
| 108 + * That's OK for NPN, but not ALPN. */ |
| 109 + SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); |
| 110 + PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL); |
| 111 + (void)SSL3_SendAlert(ss, alert_fatal, no_application_protocol); |
| 112 + return SECFailure; |
| 113 + } |
| 114 + |
| 115 + ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
| 116 + |
| 117 + SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); |
| 118 + return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); |
| 119 +} |
| 120 + |
| 121 +/* handle an incoming ALPN extension at the server */ |
| 122 +static SECStatus |
| 123 +ssl3_ServerHandleAppProtoXtn(sslSocket *ss, PRUint16 ex_type, SECItem *data) |
| 124 +{ |
| 125 + int count; |
| 126 + SECStatus rv; |
| 127 + |
| 128 + /* We expressly don't want to allow ALPN on renegotiation, |
| 129 + * despite it being permitted by the spec. */ |
| 130 + if (ss->firstHsDone || data->len == 0) { |
| 131 + /* Clients MUST send a non-empty ALPN extension. */ |
| 132 + PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); |
| 133 + return SECFailure; |
| 134 + } |
| 135 + |
| 136 + /* unlike NPN, ALPN has extra redundant length information so that |
| 137 + * the extension is the same in both ClientHello and ServerHello */ |
| 138 + count = ssl3_ConsumeHandshakeNumber(ss, 2, &data->data, &data->len); |
| 139 + if (count < 0) { |
| 140 + return SECFailure; /* fatal alert was sent */ |
| 141 + } |
| 142 + if (count != data->len) { |
| 143 + return ssl3_DecodeError(ss); |
| 144 + } |
| 145 + |
| 146 + if (!ss->nextProtoCallback) { |
| 147 + /* we're not configured for it */ |
| 148 + return SECSuccess; |
| 149 + } |
| 150 + |
| 151 + rv = ssl3_SelectAppProtocol(ss, ex_type, data); |
| 152 + if (rv != SECSuccess) { |
| 153 + return rv; |
| 154 + } |
| 155 + |
| 156 + /* prepare to send back a response, if we negotiated */ |
| 157 + if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED) { |
| 158 + return ssl3_RegisterServerHelloExtensionSender( |
| 159 + ss, ex_type, ssl3_ServerSendAppProtoXtn); |
| 160 + } |
| 161 + return SECSuccess; |
| 162 +} |
| 163 + |
| 164 +static SECStatus |
| 165 +ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, |
| 166 + SECItem *data) |
| 167 +{ |
| 168 PORT_Assert(!ss->firstHsDone); |
| 169 |
| 170 if (ssl3_ExtensionNegotiated(ss, ssl_app_layer_protocol_xtn)) { |
| 171 @@ -643,37 +728,16 @@ ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16
ex_type, |
| 172 return SECFailure; |
| 173 } |
| 174 |
| 175 - rv = ssl3_ValidateNextProtoNego(data->data, data->len); |
| 176 - if (rv != SECSuccess) |
| 177 - return rv; |
| 178 - |
| 179 - /* ss->nextProtoCallback cannot normally be NULL if we negotiated the |
| 180 - * extension. However, It is possible that an application erroneously |
| 181 - * cleared the callback between the time we sent the ClientHello and now. |
| 182 - */ |
| 183 - PORT_Assert(ss->nextProtoCallback != NULL); |
| 184 + /* We should only get this call if we sent the extension, so |
| 185 + * ss->nextProtoCallback needs to be non-NULL. However, it is possible |
| 186 + * that an application erroneously cleared the callback between the time |
| 187 + * we sent the ClientHello and now. */ |
| 188 if (!ss->nextProtoCallback) { |
| 189 - /* XXX Use a better error code. This is an application error, not an |
| 190 - * NSS bug. */ |
| 191 - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); |
| 192 + PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK); |
| 193 return SECFailure; |
| 194 } |
| 195 |
| 196 - rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, data->data, data->len, |
| 197 - result.data, &result.len, sizeof resultBuffer); |
| 198 - if (rv != SECSuccess) |
| 199 - return rv; |
| 200 - /* If the callback wrote more than allowed to |result| it has corrupted our |
| 201 - * stack. */ |
| 202 - if (result.len > sizeof resultBuffer) { |
| 203 - PORT_SetError(SEC_ERROR_OUTPUT_LEN); |
| 204 - return SECFailure; |
| 205 - } |
| 206 - |
| 207 - ss->xtnData.negotiated[ss->xtnData.numNegotiated++] = ex_type; |
| 208 - |
| 209 - SECITEM_FreeItem(&ss->ssl3.nextProto, PR_FALSE); |
| 210 - return SECITEM_CopyItem(NULL, &ss->ssl3.nextProto, &result); |
| 211 + return ssl3_SelectAppProtocol(ss, ex_type, data); |
| 212 } |
| 213 |
| 214 static SECStatus |
| 215 @@ -814,6 +878,47 @@ loser: |
| 216 return -1; |
| 217 } |
| 218 |
| 219 +static PRInt32 |
| 220 +ssl3_ServerSendAppProtoXtn(sslSocket * ss, PRBool append, PRUint32 maxBytes) |
| 221 +{ |
| 222 + PRInt32 extension_length; |
| 223 + |
| 224 + PORT_Assert(ss->opt.enableALPN); |
| 225 + PORT_Assert(ss->ssl3.nextProto.data); |
| 226 + PORT_Assert(ss->ssl3.nextProto.len > 0); |
| 227 + PORT_Assert(ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NEGOTIATED); |
| 228 + PORT_Assert(!ss->firstHsDone); |
| 229 + |
| 230 + extension_length = 2 /* extension type */ + 2 /* extension length */ + |
| 231 + 2 /* protocol name list */ + 1 /* name length */ + |
| 232 + ss->ssl3.nextProto.len; |
| 233 + |
| 234 + if (append && maxBytes >= extension_length) { |
| 235 + SECStatus rv; |
| 236 + rv = ssl3_AppendHandshakeNumber(ss, ssl_app_layer_protocol_xtn, 2); |
| 237 + if (rv != SECSuccess) { |
| 238 + return -1; |
| 239 + } |
| 240 + rv = ssl3_AppendHandshakeNumber(ss, extension_length - 4, 2); |
| 241 + if (rv != SECSuccess) { |
| 242 + return -1; |
| 243 + } |
| 244 + rv = ssl3_AppendHandshakeNumber(ss, ss->ssl3.nextProto.len + 1, 2); |
| 245 + if (rv != SECSuccess) { |
| 246 + return -1; |
| 247 + } |
| 248 + rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data, |
| 249 + ss->ssl3.nextProto.len, 1); |
| 250 + if (rv != SECSuccess) { |
| 251 + return -1; |
| 252 + } |
| 253 + } else if (maxBytes < extension_length) { |
| 254 + return 0; |
| 255 + } |
| 256 + |
| 257 + return extension_length; |
| 258 +} |
| 259 + |
| 260 static SECStatus |
| 261 ssl3_ClientHandleChannelIDXtn(sslSocket *ss, PRUint16 ex_type, |
| 262 SECItem *data) |
| 263 diff --git a/net/third_party/nss/ssl/ssl3prot.h b/net/third_party/nss/ssl/ssl3pr
ot.h |
| 264 index 4c19ade..d32be38 100644 |
| 265 --- a/net/third_party/nss/ssl/ssl3prot.h |
| 266 +++ b/net/third_party/nss/ssl/ssl3prot.h |
| 267 @@ -107,7 +107,8 @@ typedef enum { |
| 268 certificate_unobtainable = 111, |
| 269 unrecognized_name = 112, |
| 270 bad_certificate_status_response = 113, |
| 271 - bad_certificate_hash_value = 114 |
| 272 + bad_certificate_hash_value = 114, |
| 273 + no_application_protocol = 120 |
| 274 |
| 275 } SSL3AlertDescription; |
| 276 |
| 277 diff --git a/net/third_party/nss/ssl/sslerr.h b/net/third_party/nss/ssl/sslerr.h |
| 278 index 82ae7df..5184a6e 100644 |
| 279 --- a/net/third_party/nss/ssl/sslerr.h |
| 280 +++ b/net/third_party/nss/ssl/sslerr.h |
| 281 @@ -193,10 +193,14 @@ SSL_ERROR_UNSUPPORTED_HASH_ALGORITHM = (SSL_ERROR_BASE + 1
26), |
| 282 SSL_ERROR_DIGEST_FAILURE = (SSL_ERROR_BASE + 127), |
| 283 SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM = (SSL_ERROR_BASE + 128), |
| 284 |
| 285 -SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 129), |
| 286 -SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 130), |
| 287 -SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 131), |
| 288 -SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 132), |
| 289 +SSL_ERROR_NEXT_PROTOCOL_NO_CALLBACK = (SSL_ERROR_BASE + 129), |
| 290 +SSL_ERROR_NEXT_PROTOCOL_NO_PROTOCOL = (SSL_ERROR_BASE + 130), |
| 291 + |
| 292 +SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT = (SSL_ERROR_BASE + 131), |
| 293 + |
| 294 +SSL_ERROR_BAD_CHANNEL_ID_DATA = (SSL_ERROR_BASE + 132), |
| 295 +SSL_ERROR_INVALID_CHANNEL_ID_KEY = (SSL_ERROR_BASE + 133), |
| 296 +SSL_ERROR_GET_CHANNEL_ID_FAILED = (SSL_ERROR_BASE + 134), |
| 297 |
| 298 SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */ |
| 299 } SSLErrorCodes; |
| 300 diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock
.c |
| 301 index 028cd98..421ba21 100644 |
| 302 --- a/net/third_party/nss/ssl/sslsock.c |
| 303 +++ b/net/third_party/nss/ssl/sslsock.c |
| 304 @@ -1432,6 +1432,11 @@ DTLS_ImportFD(PRFileDesc *model, PRFileDesc *fd) |
| 305 return ssl_ImportFD(model, fd, ssl_variant_datagram); |
| 306 } |
| 307 |
| 308 +/* SSL_SetNextProtoCallback is used to select an application protocol |
| 309 + * for ALPN and NPN. For ALPN, this runs on the server; for NPN it |
| 310 + * runs on the client. */ |
| 311 +/* Note: The ALPN version doesn't allow for the use of a default, setting a |
| 312 + * status of SSL_NEXT_PROTO_NO_OVERLAP is treated as a failure. */ |
| 313 SECStatus |
| 314 SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallback callback, |
| 315 void *arg) |
| 316 @@ -1452,7 +1457,7 @@ SSL_SetNextProtoCallback(PRFileDesc *fd, SSLNextProtoCallb
ack callback, |
| 317 return SECSuccess; |
| 318 } |
| 319 |
| 320 -/* ssl_NextProtoNegoCallback is set as an NPN callback for the case when |
| 321 +/* ssl_NextProtoNegoCallback is set as an ALPN/NPN callback when |
| 322 * SSL_SetNextProtoNego is used. |
| 323 */ |
| 324 static SECStatus |
| 325 @@ -1471,12 +1476,6 @@ ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd, |
| 326 return SECFailure; |
| 327 } |
| 328 |
| 329 - if (protos_len == 0) { |
| 330 - /* The server supports the extension, but doesn't have any protocols |
| 331 - * configured. In this case we request our favoured protocol. */ |
| 332 - goto pick_first; |
| 333 - } |
| 334 - |
| 335 /* For each protocol in server preference, see if we support it. */ |
| 336 for (i = 0; i < protos_len; ) { |
| 337 for (j = 0; j < ss->opt.nextProtoNego.len; ) { |
| 338 @@ -1493,7 +1492,10 @@ ssl_NextProtoNegoCallback(void *arg, PRFileDesc *fd, |
| 339 i += 1 + (unsigned int)protos[i]; |
| 340 } |
| 341 |
| 342 -pick_first: |
| 343 + /* The other side supports the extension, and either doesn't have any |
| 344 + * protocols configured, or none of its options match ours. In this case we |
| 345 + * request our favoured protocol. */ |
| 346 + /* This will be treated as a failure for ALPN. */ |
| 347 ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP; |
| 348 result = ss->opt.nextProtoNego.data; |
| 349 |
OLD | NEW |