OLD | NEW |
1 From 6b594dc531e7a1d1d5bca2f0f78e7bc0ac3ff937 Mon Sep 17 00:00:00 2001 | 1 From 85ecb73392e484ebd783e9414a968a1f5668d87b Mon Sep 17 00:00:00 2001 |
2 From: Adam Langley <agl@chromium.org> | 2 From: Adam Langley <agl@chromium.org> |
3 Date: Mon, 3 Oct 2011 12:19:28 -0400 | 3 Date: Mon, 3 Oct 2011 12:19:28 -0400 |
4 Subject: [PATCH] nextproto.patch | 4 Subject: [PATCH] nextproto.patch |
5 | 5 |
6 --- | 6 --- |
7 mozilla/security/nss/cmd/tstclnt/tstclnt.c | 6 ++ | 7 mozilla/security/nss/lib/ssl/ssl.def | 6 ++ |
8 mozilla/security/nss/lib/ssl/ssl.def | 7 ++ | 8 mozilla/security/nss/lib/ssl/ssl.h | 22 +++++++ |
9 mozilla/security/nss/lib/ssl/ssl.h | 12 +++ | 9 mozilla/security/nss/lib/ssl/ssl3con.c | 54 +++++++++++++++++ |
10 mozilla/security/nss/lib/ssl/ssl3con.c | 54 ++++++++++++ | 10 mozilla/security/nss/lib/ssl/ssl3ext.c | 98 ++++++++++++++++++++++++++++++- |
11 mozilla/security/nss/lib/ssl/ssl3ext.c | 122 +++++++++++++++++++++++++++- | 11 mozilla/security/nss/lib/ssl/ssl3prot.h | 3 +- |
12 mozilla/security/nss/lib/ssl/ssl3prot.h | 3 +- | 12 mozilla/security/nss/lib/ssl/sslimpl.h | 16 +++++ |
13 mozilla/security/nss/lib/ssl/sslimpl.h | 24 ++++++ | 13 mozilla/security/nss/lib/ssl/sslsock.c | 18 ++++++ |
14 mozilla/security/nss/lib/ssl/sslsock.c | 74 +++++++++++++++++ | 14 mozilla/security/nss/lib/ssl/sslt.h | 3 +- |
15 mozilla/security/nss/lib/ssl/sslt.h | 3 +- | 15 8 files changed, 217 insertions(+), 3 deletions(-) |
16 9 files changed, 302 insertions(+), 3 deletions(-) | |
17 | 16 |
18 diff --git a/mozilla/security/nss/cmd/tstclnt/tstclnt.c b/mozilla/security/nss/c
md/tstclnt/tstclnt.c | |
19 index 55684e6..d209a33 100644 | |
20 --- a/mozilla/security/nss/cmd/tstclnt/tstclnt.c | |
21 +++ b/mozilla/security/nss/cmd/tstclnt/tstclnt.c | |
22 @@ -868,6 +868,12 @@ int main(int argc, char **argv) | |
23 return 1; | |
24 } | |
25 | |
26 + rv = SSL_SetNextProtoNego(s, "\004flip\004http1.1", 10); | |
27 + if (rv != SECSuccess) { | |
28 + SECU_PrintError(progName, "error enabling next protocol negotiation"); | |
29 + return 1; | |
30 + } | |
31 + | |
32 /* enable false start. */ | |
33 rv = SSL_OptionSet(s, SSL_ENABLE_FALSE_START, enableFalseStart); | |
34 if (rv != SECSuccess) { | |
35 diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl
/ssl.def | 17 diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl
/ssl.def |
36 index d3f455c..a1f4b51 100644 | 18 index d3f455c..5256ae2 100644 |
37 --- a/mozilla/security/nss/lib/ssl/ssl.def | 19 --- a/mozilla/security/nss/lib/ssl/ssl.def |
38 +++ b/mozilla/security/nss/lib/ssl/ssl.def | 20 +++ b/mozilla/security/nss/lib/ssl/ssl.def |
39 @@ -152,3 +152,10 @@ SSL_SNISocketConfigHook; | 21 @@ -152,3 +152,9 @@ SSL_SNISocketConfigHook; |
40 ;+ local: | 22 ;+ local: |
41 ;+*; | 23 ;+*; |
42 ;+}; | 24 ;+}; |
43 +;+NSS_CHROMIUM { | 25 +;+NSS_CHROMIUM { |
44 +;+ global: | 26 +;+ global: |
45 +SSL_GetNextProto; | 27 +SSL_SetNextProtoCallback; |
46 +SSL_SetNextProtoNego; | |
47 +;+ local: | 28 +;+ local: |
48 +;+*; | 29 +;+*; |
49 +;+}; | 30 +;+}; |
50 diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/s
sl.h | 31 diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/s
sl.h |
51 index 4a9e89d..ffa973c 100644 | 32 index 4a9e89d..5fbb676 100644 |
52 --- a/mozilla/security/nss/lib/ssl/ssl.h | 33 --- a/mozilla/security/nss/lib/ssl/ssl.h |
53 +++ b/mozilla/security/nss/lib/ssl/ssl.h | 34 +++ b/mozilla/security/nss/lib/ssl/ssl.h |
54 @@ -153,6 +153,18 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, P
RBool on); | 35 @@ -153,6 +153,28 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, P
RBool on); |
55 SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on); | 36 SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on); |
56 SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHa
ndle); | 37 SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHa
ndle); |
57 | 38 |
58 +SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd, | 39 +#define SSL_NEXT_PROTO_NEGOTIATION_SUPPORTED 1 |
59 +» » » » » const unsigned char *data, | 40 + |
60 +» » » » » unsigned short length); | 41 +/* SSLNextProtoCallback is called, during the handshake, when the server has |
61 +SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd, | 42 + * sent a Next Protocol Negotiation extension. |protos| and |protosLen| define |
62 +» » » » int *state, | 43 + * a buffer which contains the server's advertisement. This data is guaranteed |
63 +» » » » unsigned char *buf, | 44 + * to be well formed per the NPN spec. |protoOut| is a buffer of length 255 |
64 +» » » » unsigned *length, | 45 + * (the maximum allowed by the protocol) which, on successful return, must |
65 +» » » » unsigned buf_len); | 46 + * contain the protocol to be announced to the server. */ |
66 +#define SSL_NEXT_PROTO_NO_SUPPORT» 0 /* No peer support */ | 47 +typedef SECStatus (PR_CALLBACK *SSLNextProtoCallback)( |
67 +#define SSL_NEXT_PROTO_NEGOTIATED» 1 /* Mutual agreement */ | 48 + void *arg, |
68 +#define SSL_NEXT_PROTO_NO_OVERLAP» 2 /* No protocol overlap found */ | 49 + PRFileDesc *fd, |
| 50 + const unsigned char* protos, |
| 51 + unsigned short protosLen, |
| 52 + unsigned char* protoOut, |
| 53 + unsigned char* protoOutLen); |
| 54 + |
| 55 +/* SSL_SetNextProtoCallback sets a callback function to handle Next Protocol |
| 56 + * Negotiation. It causes a client to advertise NPN. */ |
| 57 +SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd, |
| 58 + SSLNextProtoCallback callback, |
| 59 + void *arg); |
69 + | 60 + |
70 /* | 61 /* |
71 ** Control ciphers that SSL uses. If on is non-zero then the named cipher | 62 ** Control ciphers that SSL uses. If on is non-zero then the named cipher |
72 ** is enabled, otherwise it is disabled. | 63 ** is enabled, otherwise it is disabled. |
73 diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/s
sl/ssl3con.c | 64 diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/s
sl/ssl3con.c |
74 index 8048913..e0cb4e9 100644 | 65 index 8048913..8f860a9 100644 |
75 --- a/mozilla/security/nss/lib/ssl/ssl3con.c | 66 --- a/mozilla/security/nss/lib/ssl/ssl3con.c |
76 +++ b/mozilla/security/nss/lib/ssl/ssl3con.c | 67 +++ b/mozilla/security/nss/lib/ssl/ssl3con.c |
77 @@ -81,6 +81,7 @@ static SECStatus ssl3_InitState( sslSocket *ss); | 68 @@ -81,6 +81,7 @@ static SECStatus ssl3_InitState( sslSocket *ss); |
78 static SECStatus ssl3_SendCertificate( sslSocket *ss); | 69 static SECStatus ssl3_SendCertificate( sslSocket *ss); |
79 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); | 70 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); |
80 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); | 71 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); |
81 +static SECStatus ssl3_SendNextProto( sslSocket *ss); | 72 +static SECStatus ssl3_SendNextProto( sslSocket *ss); |
82 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); | 73 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); |
83 static SECStatus ssl3_SendServerHello( sslSocket *ss); | 74 static SECStatus ssl3_SendServerHello( sslSocket *ss); |
84 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); | 75 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); |
(...skipping 15 matching lines...) Expand all Loading... |
100 | 91 |
101 /* called from ssl3_HandleServerHelloDone | 92 /* called from ssl3_HandleServerHelloDone |
102 + */ | 93 + */ |
103 +static SECStatus | 94 +static SECStatus |
104 +ssl3_SendNextProto(sslSocket *ss) | 95 +ssl3_SendNextProto(sslSocket *ss) |
105 +{ | 96 +{ |
106 + SECStatus rv; | 97 + SECStatus rv; |
107 + int padding_len; | 98 + int padding_len; |
108 + static const unsigned char padding[32] = {0}; | 99 + static const unsigned char padding[32] = {0}; |
109 + | 100 + |
110 + if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NO_SUPPORT) | 101 + if (ss->ssl3.nextProto.len == 0) |
111 + return SECSuccess; | 102 + return SECSuccess; |
112 + | 103 + |
113 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | 104 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
114 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | 105 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
115 + | 106 + |
116 + padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32); | 107 + padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32); |
117 + | 108 + |
118 + rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len + | 109 + rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len + |
119 + 2 + padding_len); | 110 + 2 + padding_len); |
120 + if (rv != SECSuccess) { | 111 + if (rv != SECSuccess) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 ss->ssl3.initialized = PR_FALSE; | 148 ss->ssl3.initialized = PR_FALSE; |
158 + | 149 + |
159 + if (ss->ssl3.nextProto.data) { | 150 + if (ss->ssl3.nextProto.data) { |
160 + PORT_Free(ss->ssl3.nextProto.data); | 151 + PORT_Free(ss->ssl3.nextProto.data); |
161 + ss->ssl3.nextProto.data = NULL; | 152 + ss->ssl3.nextProto.data = NULL; |
162 + } | 153 + } |
163 } | 154 } |
164 | 155 |
165 /* End of ssl3con.c */ | 156 /* End of ssl3con.c */ |
166 diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/s
sl/ssl3ext.c | 157 diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/s
sl/ssl3ext.c |
167 index becbfe9..fbd5a91 100644 | 158 index becbfe9..e5311e6 100644 |
168 --- a/mozilla/security/nss/lib/ssl/ssl3ext.c | 159 --- a/mozilla/security/nss/lib/ssl/ssl3ext.c |
169 +++ b/mozilla/security/nss/lib/ssl/ssl3ext.c | 160 +++ b/mozilla/security/nss/lib/ssl/ssl3ext.c |
170 @@ -235,6 +235,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[]
= { | 161 @@ -235,6 +235,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[]
= { |
171 #endif | 162 #endif |
172 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, | 163 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, |
173 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 164 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
174 + { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, | 165 + { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, |
175 { -1, NULL } | 166 { -1, NULL } |
176 }; | 167 }; |
177 | 168 |
178 @@ -245,6 +246,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTL
S[] = { | 169 @@ -245,6 +246,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTL
S[] = { |
179 /* TODO: add a handler for ssl_ec_point_formats_xtn */ | 170 /* TODO: add a handler for ssl_ec_point_formats_xtn */ |
180 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, | 171 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, |
181 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 172 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
182 + { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, | 173 + { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, |
183 { -1, NULL } | 174 { -1, NULL } |
184 }; | 175 }; |
185 | 176 |
186 @@ -267,7 +269,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTEN
SIONS] = { | 177 @@ -267,7 +269,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTEN
SIONS] = { |
187 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, | 178 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, |
188 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, | 179 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, |
189 #endif | 180 #endif |
190 - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn } | 181 - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn } |
191 + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, | 182 + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, |
192 + { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn } | 183 + { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn } |
193 /* any extra entries will appear as { 0, NULL } */ | 184 /* any extra entries will appear as { 0, NULL } */ |
194 }; | 185 }; |
195 | 186 |
196 @@ -534,6 +537,123 @@ ssl3_SendSessionTicketXtn( | 187 @@ -534,6 +537,99 @@ ssl3_SendSessionTicketXtn( |
197 return -1; | 188 return -1; |
198 } | 189 } |
199 | 190 |
200 +/* handle an incoming Next Protocol Negotiation extension. */ | 191 +/* handle an incoming Next Protocol Negotiation extension. */ |
201 +SECStatus | 192 +SECStatus |
202 +ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *da
ta) | 193 +ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *da
ta) |
203 +{ | 194 +{ |
204 + if (data->len != 0) { | 195 + if (data->len != 0) { |
205 + /* Clients MUST send an empty NPN extension, if any. */ | 196 + /* Clients MUST send an empty NPN extension, if any. */ |
206 + return SECFailure; | 197 + return SECFailure; |
207 + } | 198 + } |
208 + | 199 + |
209 + ss->ssl3.hs.nextProtoNego = PR_TRUE; | |
210 + return SECSuccess; | 200 + return SECSuccess; |
211 +} | 201 +} |
212 + | 202 + |
213 +/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: non
e | 203 +/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: non
e |
214 + * of the length may be 0 and the sum of the lengths must equal the length of | 204 + * of the lengths may be 0 and the sum of the lengths must equal the length of |
215 + * the block. */ | 205 + * the block. */ |
216 +SECStatus | 206 +SECStatus |
217 +ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) | 207 +ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) |
218 +{ | 208 +{ |
219 + unsigned int offset = 0; | 209 + unsigned int offset = 0; |
220 + | 210 + |
221 + while (offset < length) { | 211 + while (offset < length) { |
222 + if (data[offset] == 0) { | 212 + if (data[offset] == 0) { |
223 + return SECFailure; | 213 + return SECFailure; |
224 + } | 214 + } |
225 + offset += (unsigned int)data[offset] + 1; | 215 + offset += (unsigned int)data[offset] + 1; |
226 + } | 216 + } |
227 + | 217 + |
228 + if (offset > length) | 218 + if (offset > length) |
229 + return SECFailure; | 219 + return SECFailure; |
230 + | 220 + |
231 + return SECSuccess; | 221 + return SECSuccess; |
232 +} | 222 +} |
233 + | 223 + |
234 +SECStatus | 224 +SECStatus |
235 +ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, | 225 +ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, |
236 + SECItem *data) | 226 + SECItem *data) |
237 +{ | 227 +{ |
238 + unsigned int i, j; | |
239 + SECStatus rv; | 228 + SECStatus rv; |
240 + unsigned char *result; | 229 + unsigned char result[255]; |
241 + | 230 + unsigned char result_len; |
242 + if (data->len == 0) { | |
243 +» /* The server supports the extension, but doesn't have any | |
244 +» * protocols configured. In this case we request our favoured | |
245 +» * protocol. */ | |
246 +» goto pick_first; | |
247 + } | |
248 + | 231 + |
249 + rv = ssl3_ValidateNextProtoNego(data->data, data->len); | 232 + rv = ssl3_ValidateNextProtoNego(data->data, data->len); |
250 + if (rv != SECSuccess) | 233 + if (rv != SECSuccess) |
251 + return rv; | 234 + return rv; |
252 + | 235 + |
253 + /* For each protocol in server preference order, see if we support it. */ | 236 + rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, |
254 + for (i = 0; i < data->len; ) { | 237 + data->data, data->len, |
255 +» for (j = 0; j < ss->opt.nextProtoNego.len; ) { | 238 + result, &result_len); |
256 +» if (data->data[i] == ss->opt.nextProtoNego.data[j] && | 239 + if (rv != SECSuccess) |
257 +» » memcmp(&data->data[i+1], &ss->opt.nextProtoNego.data[j+1], | 240 +» return rv; |
258 +» » data->data[i]) == 0) { | |
259 +» » /* We found a match */ | |
260 +» » ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; | |
261 +» » result = &data->data[i]; | |
262 +» » goto found; | |
263 +» } | |
264 +» j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1; | |
265 +» } | |
266 + | 241 + |
267 + i += (unsigned int)data->data[i] + 1; | |
268 + } | |
269 + | |
270 + pick_first: | |
271 + ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP; | |
272 + result = ss->opt.nextProtoNego.data; | |
273 + | |
274 + found: | |
275 + if (ss->ssl3.nextProto.data) | 242 + if (ss->ssl3.nextProto.data) |
276 + PORT_Free(ss->ssl3.nextProto.data); | 243 + PORT_Free(ss->ssl3.nextProto.data); |
277 + ss->ssl3.nextProto.data = PORT_Alloc(result[0]); | 244 + ss->ssl3.nextProto.data = PORT_Alloc(result_len); |
278 + PORT_Memcpy(ss->ssl3.nextProto.data, result + 1, result[0]); | 245 + PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len); |
279 + ss->ssl3.nextProto.len = result[0]; | 246 + ss->ssl3.nextProto.len = result_len; |
280 + return SECSuccess; | 247 + return SECSuccess; |
281 +} | 248 +} |
282 + | 249 + |
283 +PRInt32 | 250 +PRInt32 |
284 +ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, | 251 +ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, |
285 + PRBool append, | 252 + PRBool append, |
286 + PRUint32 maxBytes) | 253 + PRUint32 maxBytes) |
287 +{ | 254 +{ |
288 + PRInt32 extension_length; | 255 + PRInt32 extension_length; |
289 + | 256 + |
290 + /* Renegotiations do not send this extension. */ | 257 + /* Renegotiations do not send this extension. */ |
291 + if (ss->opt.nextProtoNego.len == 0 || ss->firstHsDone) { | 258 + if (!ss->nextProtoCallback || ss->firstHsDone) { |
292 + return 0; | 259 + return 0; |
293 + } | 260 + } |
294 + | 261 + |
295 + extension_length = 4; | 262 + extension_length = 4; |
296 + | 263 + |
297 + if (append && maxBytes >= extension_length) { | 264 + if (append && maxBytes >= extension_length) { |
298 + SECStatus rv; | 265 + SECStatus rv; |
299 + rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); | 266 + rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); |
300 + if (rv != SECSuccess) | 267 + if (rv != SECSuccess) |
301 + goto loser; | 268 + goto loser; |
(...skipping 23 matching lines...) Expand all Loading... |
325 server_hello_done = 14, | 292 server_hello_done = 14, |
326 certificate_verify = 15, | 293 certificate_verify = 15, |
327 client_key_exchange = 16, | 294 client_key_exchange = 16, |
328 - finished = 20 | 295 - finished = 20 |
329 + finished = 20, | 296 + finished = 20, |
330 + next_proto = 67 | 297 + next_proto = 67 |
331 } SSL3HandshakeType; | 298 } SSL3HandshakeType; |
332 | 299 |
333 typedef struct { | 300 typedef struct { |
334 diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/s
sl/sslimpl.h | 301 diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/s
sl/sslimpl.h |
335 index 9af471d..d1c1181 100644 | 302 index 9af471d..cc39a0d 100644 |
336 --- a/mozilla/security/nss/lib/ssl/sslimpl.h | 303 --- a/mozilla/security/nss/lib/ssl/sslimpl.h |
337 +++ b/mozilla/security/nss/lib/ssl/sslimpl.h | 304 +++ b/mozilla/security/nss/lib/ssl/sslimpl.h |
338 @@ -313,6 +313,11 @@ typedef struct { | 305 @@ -827,6 +827,12 @@ struct ssl3StateStr { |
339 #endif /* NSS_ENABLE_ECC */ | |
340 | |
341 typedef struct sslOptionsStr { | |
342 + /* For clients, this is a validated list of protocols in preference order | |
343 + * and wire format. For servers, this is the list of support protocols, | |
344 + * also in wire format. */ | |
345 + SECItem nextProtoNego; | |
346 + | |
347 unsigned int useSecurity» » : 1; /* 1 */ | |
348 unsigned int useSocks» » : 1; /* 2 */ | |
349 unsigned int requestCertificate» : 1; /* 3 */ | |
350 @@ -786,6 +791,7 @@ const ssl3CipherSuiteDef *suite_def; | |
351 #ifdef NSS_ENABLE_ECC | |
352 PRUint32 negotiatedECCurves; /* bit mask */ | |
353 #endif /* NSS_ENABLE_ECC */ | |
354 + PRBool nextProtoNego;/* Our peer has sent this extension */ | |
355 } SSL3HandshakeState; | |
356 | |
357 | |
358 @@ -827,6 +833,16 @@ struct ssl3StateStr { | |
359 PRBool initialized; | 306 PRBool initialized; |
360 SSL3HandshakeState hs; | 307 SSL3HandshakeState hs; |
361 ssl3CipherSpec specs[2]; /* one is current, one is pending. */ | 308 ssl3CipherSpec specs[2]; /* one is current, one is pending. */ |
362 + | 309 + |
363 + /* In a client: if the server supports Next Protocol Negotiation, then | 310 + /* In a client: if the server supports Next Protocol Negotiation, then |
364 + * this is the protocol that was requested. | 311 + * this is the protocol that was requested. |
365 + * In a server: this is the protocol that the client requested via Next | |
366 + * Protocol Negotiation. | |
367 + * | 312 + * |
368 + * In either case, if the data pointer is non-NULL, then it is malloced | 313 + * If the data pointer is non-NULL, then it is malloced data. */ |
369 + * data. */ | |
370 + SECItem nextProto; | 314 + SECItem nextProto; |
371 + int nextProtoState; /* See SSL_NEXT_PROTO_* defines
*/ | |
372 }; | 315 }; |
373 | 316 |
374 typedef struct { | 317 typedef struct { |
375 @@ -1494,8 +1510,12 @@ extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslS
ocket * ss, | 318 @@ -1058,6 +1064,8 @@ const unsigned char * preferredCipher; |
| 319 SSLHandshakeCallback handshakeCallback; |
| 320 void *handshakeCallbackData; |
| 321 void *pkcs11PinArg; |
| 322 + SSLNextProtoCallback nextProtoCallback; |
| 323 + void *nextProtoArg; |
| 324 |
| 325 PRIntervalTime rTimeout; /* timeout for NSPR I/O */ |
| 326 PRIntervalTime wTimeout; /* timeout for NSPR I/O */ |
| 327 @@ -1494,8 +1502,12 @@ extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslS
ocket * ss, |
376 PRUint16 ex_type, SECItem *data); | 328 PRUint16 ex_type, SECItem *data); |
377 extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, | 329 extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, |
378 PRUint16 ex_type, SECItem *data); | 330 PRUint16 ex_type, SECItem *data); |
379 +extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, | 331 +extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, |
380 + PRUint16 ex_type, SECItem *data); | 332 + PRUint16 ex_type, SECItem *data); |
381 extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, | 333 extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, |
382 PRUint16 ex_type, SECItem *data); | 334 PRUint16 ex_type, SECItem *data); |
383 +extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, | 335 +extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, |
384 + PRUint16 ex_type, SECItem *data); | 336 + PRUint16 ex_type, SECItem *data); |
385 | 337 |
386 /* ClientHello and ServerHello extension senders. | 338 /* ClientHello and ServerHello extension senders. |
387 * Note that not all extension senders are exposed here; only those that | 339 * Note that not all extension senders are exposed here; only those that |
388 @@ -1526,6 +1546,10 @@ extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss, | 340 @@ -1526,6 +1538,10 @@ extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss, |
389 extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss, | 341 extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss, |
390 PRBool append, PRUint32 maxBytes); | 342 PRBool append, PRUint32 maxBytes); |
391 #endif | 343 #endif |
392 +extern PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, | 344 +extern PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, |
393 + PRUint32 maxBytes); | 345 + PRUint32 maxBytes); |
394 +extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data, | 346 +extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data, |
395 + unsigned short length); | 347 + unsigned short length); |
396 | 348 |
397 /* call the registered extension handlers. */ | 349 /* call the registered extension handlers. */ |
398 extern SECStatus ssl3_HandleHelloExtensions(sslSocket *ss, | 350 extern SECStatus ssl3_HandleHelloExtensions(sslSocket *ss, |
399 diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/s
sl/sslsock.c | 351 diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/s
sl/sslsock.c |
400 index bc770a1..4c8fbfd 100644 | 352 index bc770a1..0d92ff7 100644 |
401 --- a/mozilla/security/nss/lib/ssl/sslsock.c | 353 --- a/mozilla/security/nss/lib/ssl/sslsock.c |
402 +++ b/mozilla/security/nss/lib/ssl/sslsock.c | 354 +++ b/mozilla/security/nss/lib/ssl/sslsock.c |
403 @@ -163,6 +163,7 @@ static const sslSocketOps ssl_secure_ops = {» /* SSL.
*/ | 355 @@ -1266,6 +1266,24 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd) |
404 ** default settings for socket enables | |
405 */ | |
406 static sslOptions ssl_defaults = { | |
407 + { siBuffer, NULL, 0 },» /* nextProtoNego */ | |
408 PR_TRUE, » /* useSecurity */ | |
409 PR_FALSE,» /* useSocks */ | |
410 PR_FALSE,» /* requestCertificate */ | |
411 @@ -438,6 +439,10 @@ ssl_DestroySocketContents(sslSocket *ss) | |
412 » ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); | |
413 » ss->ephemeralECDHKeyPair = NULL; | |
414 } | |
415 + if (ss->opt.nextProtoNego.data) { | |
416 +» PORT_Free(ss->opt.nextProtoNego.data); | |
417 +» ss->opt.nextProtoNego.data = NULL; | |
418 + } | |
419 PORT_Assert(!ss->xtnData.sniNameArr); | |
420 if (ss->xtnData.sniNameArr) { | |
421 PORT_Free(ss->xtnData.sniNameArr); | |
422 @@ -1266,6 +1271,75 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd) | |
423 return fd; | 356 return fd; |
424 } | 357 } |
425 | 358 |
426 +/* SSL_SetNextProtoNego sets the list of supported protocols for the given | |
427 + * socket. The list is a series of 8-bit, length prefixed strings. */ | |
428 +SECStatus | 359 +SECStatus |
429 +SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data, | 360 +SSL_SetNextProtoCallback(PRFileDesc *fd, |
430 +» » unsigned short length) | 361 + SSLNextProtoCallback callback, |
431 +{ | 362 + void *arg) { |
432 + sslSocket *ss = ssl_FindSocket(fd); | 363 + sslSocket *ss = ssl_FindSocket(fd); |
433 + | 364 + |
434 + if (!ss) { | 365 + if (!ss) { |
435 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", SSL_GETPID()
, | 366 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", SSL_GETPID()
, |
436 + fd)); | 367 + fd)); |
437 + return SECFailure; | 368 + return SECFailure; |
438 + } | 369 + } |
439 + | 370 + |
440 + if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess) | |
441 + return SECFailure; | |
442 + | |
443 + ssl_GetSSL3HandshakeLock(ss); | 371 + ssl_GetSSL3HandshakeLock(ss); |
444 + if (ss->opt.nextProtoNego.data) | 372 + ss->nextProtoCallback = callback; |
445 +» PORT_Free(ss->opt.nextProtoNego.data); | 373 + ss->nextProtoArg = arg; |
446 + ss->opt.nextProtoNego.data = PORT_Alloc(length); | |
447 + if (!ss->opt.nextProtoNego.data) { | |
448 +» ssl_ReleaseSSL3HandshakeLock(ss); | |
449 +» return SECFailure; | |
450 + } | |
451 + memcpy(ss->opt.nextProtoNego.data, data, length); | |
452 + ss->opt.nextProtoNego.len = length; | |
453 + ss->opt.nextProtoNego.type = siBuffer; | |
454 + ssl_ReleaseSSL3HandshakeLock(ss); | 374 + ssl_ReleaseSSL3HandshakeLock(ss); |
455 + | |
456 + return SECSuccess; | |
457 +} | |
458 + | |
459 +/* SSL_GetNextProto reads the resulting Next Protocol Negotiation result for | |
460 + * the given socket. It's only valid to call this once the handshake has | |
461 + * completed. | |
462 + * | |
463 + * state is set to one of the SSL_NEXT_PROTO_* constants. The negotiated | |
464 + * protocol, if any, is written into buf, which must be at least buf_len | |
465 + * bytes long. If the negotiated protocol is longer than this, it is truncated. | |
466 + * The number of bytes copied is written into length. | |
467 + */ | |
468 +SECStatus | |
469 +SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf, | |
470 + unsigned int *length, unsigned int buf_len) | |
471 +{ | |
472 + sslSocket *ss = ssl_FindSocket(fd); | |
473 + | |
474 + if (!ss) { | |
475 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(), | |
476 + fd)); | |
477 + return SECFailure; | |
478 + } | |
479 + | |
480 + *state = ss->ssl3.nextProtoState; | |
481 + | |
482 + if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT && | |
483 + ss->ssl3.nextProto.data) { | |
484 + *length = ss->ssl3.nextProto.len; | |
485 + if (*length > buf_len) | |
486 + *length = buf_len; | |
487 + PORT_Memcpy(buf, ss->ssl3.nextProto.data, *length); | |
488 + } else { | |
489 + *length = 0; | |
490 + } | |
491 + | |
492 + return SECSuccess; | |
493 +} | 375 +} |
494 + | 376 + |
495 PRFileDesc * | 377 PRFileDesc * |
496 SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) | 378 SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd) |
497 { | 379 { |
498 diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/
sslt.h | 380 diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/
sslt.h |
499 index c7d4553..f6e0b62 100644 | 381 index c7d4553..f6e0b62 100644 |
500 --- a/mozilla/security/nss/lib/ssl/sslt.h | 382 --- a/mozilla/security/nss/lib/ssl/sslt.h |
501 +++ b/mozilla/security/nss/lib/ssl/sslt.h | 383 +++ b/mozilla/security/nss/lib/ssl/sslt.h |
502 @@ -203,9 +203,10 @@ typedef enum { | 384 @@ -203,9 +203,10 @@ typedef enum { |
503 ssl_ec_point_formats_xtn = 11, | 385 ssl_ec_point_formats_xtn = 11, |
504 #endif | 386 #endif |
505 ssl_session_ticket_xtn = 35, | 387 ssl_session_ticket_xtn = 35, |
506 + ssl_next_proto_neg_xtn = 13172, | 388 + ssl_next_proto_neg_xtn = 13172, |
507 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ | 389 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ |
508 } SSLExtensionType; | 390 } SSLExtensionType; |
509 | 391 |
510 -#define SSL_MAX_EXTENSIONS 5 | 392 -#define SSL_MAX_EXTENSIONS 5 |
511 +#define SSL_MAX_EXTENSIONS 6 | 393 +#define SSL_MAX_EXTENSIONS 6 |
512 | 394 |
513 #endif /* __sslt_h_ */ | 395 #endif /* __sslt_h_ */ |
OLD | NEW |