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 |