Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: net/third_party/nss/patches/nextproto.patch

Issue 8156001: net: rework the NPN patch. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ... Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 From 6b594dc531e7a1d1d5bca2f0f78e7bc0ac3ff937 Mon Sep 17 00:00:00 2001 1 From 3caa0f573d2637bfed99dcc0e5887fe3a52462ba 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 01/15] 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 | 51 ++++++++++++
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 | 104 ++++++++++++++++++++++++-
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/sslerr.h | 2 +
13 mozilla/security/nss/lib/ssl/sslimpl.h | 24 ++++++ 13 mozilla/security/nss/lib/ssl/sslimpl.h | 21 +++++
14 mozilla/security/nss/lib/ssl/sslsock.c | 74 +++++++++++++++++ 14 mozilla/security/nss/lib/ssl/sslsock.c | 131 +++++++++++++++++++++++++++++++
15 mozilla/security/nss/lib/ssl/sslt.h | 3 +- 15 mozilla/security/nss/lib/ssl/sslt.h | 3 +-
16 9 files changed, 302 insertions(+), 3 deletions(-) 16 9 files changed, 372 insertions(+), 3 deletions(-)
17 17
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 18 diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl /ssl.def
36 index d3f455c..a1f4b51 100644 19 index d3f455c..5256ae2 100644
37 --- a/mozilla/security/nss/lib/ssl/ssl.def 20 --- a/mozilla/security/nss/lib/ssl/ssl.def
38 +++ b/mozilla/security/nss/lib/ssl/ssl.def 21 +++ b/mozilla/security/nss/lib/ssl/ssl.def
39 @@ -152,3 +152,10 @@ SSL_SNISocketConfigHook; 22 @@ -152,3 +152,9 @@ SSL_SNISocketConfigHook;
40 ;+ local: 23 ;+ local:
41 ;+*; 24 ;+*;
42 ;+}; 25 ;+};
43 +;+NSS_CHROMIUM { 26 +;+NSS_CHROMIUM {
44 +;+ global: 27 +;+ global:
45 +SSL_GetNextProto; 28 +SSL_SetNextProtoCallback;
46 +SSL_SetNextProtoNego;
47 +;+ local: 29 +;+ local:
48 +;+*; 30 +;+*;
49 +;+}; 31 +;+};
50 diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/s sl.h 32 diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/s sl.h
51 index 4a9e89d..ffa973c 100644 33 index 4a9e89d..2cf777d 100644
52 --- a/mozilla/security/nss/lib/ssl/ssl.h 34 --- a/mozilla/security/nss/lib/ssl/ssl.h
53 +++ b/mozilla/security/nss/lib/ssl/ssl.h 35 +++ b/mozilla/security/nss/lib/ssl/ssl.h
54 @@ -153,6 +153,18 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, P RBool on); 36 @@ -153,6 +153,57 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, P RBool on);
55 SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on); 37 SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on);
56 SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHa ndle); 38 SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHa ndle);
57 39
40 +/* SSLNextProtoCallback is called, during the handshake, when the server has
41 + * sent a Next Protocol Negotiation extension. |protos| and |protosLen| define
42 + * a buffer which contains the server's advertisement. This data is guaranteed
43 + * to be well formed per the NPN spec. |protoOut| is a buffer provided by the
44 + * caller, of length 255 (the maximum allowed by the protocol).
45 + * On successful return, the protocol to be announced to the server will be in
46 + * |protoOut| and its length in |protoOutLen|. */
47 +typedef SECStatus (PR_CALLBACK *SSLNextProtoCallback)(
48 + void *arg,
49 + PRFileDesc *fd,
50 + const unsigned char* protos,
51 + unsigned int protosLen,
52 + unsigned char* protoOut,
53 + unsigned int* 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);
60 +
61 +/* SSL_SetNextProtoNego can be used as an alternative to
62 + * SSL_SetNextProtoCallback. It also causes a client to advertise NPN and
63 + * installs a default callback function which selects the first supported
64 + * protocol in server-preference order. If no matching protocol is found it
65 + * selects the first supported protocol.
66 + *
67 + * The supported protocols are specified in |data| in wire-format (8-bit
68 + * length-prefixed). For example: "\010http/1.1\006spdy/2". */
58 +SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd, 69 +SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd,
59 + const unsigned char *data, 70 + const unsigned char *data,
60 +» » » » » unsigned short length); 71 +» » » » » unsigned int length);
72 +/* SSL_GetNextProto can be used after a handshake on a socket where
73 + * SSL_SetNextProtoNego was called to retrieve the result of the Next Protocol
74 + * negotiation.
75 + *
76 + * state is set to one of the SSL_NEXT_PROTO_* constants. The negotiated
77 + * protocol, if any, is written into buf, which must be at least buf_len bytes
78 + * long. If the negotiated protocol is longer than this, it is truncated. The
79 + * number of bytes copied is written into *length. */
61 +SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd, 80 +SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd,
62 + int *state, 81 + int *state,
63 + unsigned char *buf, 82 + unsigned char *buf,
64 +» » » » unsigned *length, 83 +» » » » unsigned int *length,
65 +» » » » unsigned buf_len); 84 +» » » » unsigned int buf_len);
85 +
86 +// TODO(wtc): it may be a good idea to define these as an enum type.
66 +#define SSL_NEXT_PROTO_NO_SUPPORT 0 /* No peer support */ 87 +#define SSL_NEXT_PROTO_NO_SUPPORT 0 /* No peer support */
67 +#define SSL_NEXT_PROTO_NEGOTIATED 1 /* Mutual agreement */ 88 +#define SSL_NEXT_PROTO_NEGOTIATED 1 /* Mutual agreement */
68 +#define SSL_NEXT_PROTO_NO_OVERLAP 2 /* No protocol overlap found */ 89 +#define SSL_NEXT_PROTO_NO_OVERLAP 2 /* No protocol overlap found */
69 + 90 +
70 /* 91 /*
71 ** Control ciphers that SSL uses. If on is non-zero then the named cipher 92 ** Control ciphers that SSL uses. If on is non-zero then the named cipher
72 ** is enabled, otherwise it is disabled. 93 ** 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 94 diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/s sl/ssl3con.c
74 index 8048913..e0cb4e9 100644 95 index 8048913..8f860a9 100644
75 --- a/mozilla/security/nss/lib/ssl/ssl3con.c 96 --- a/mozilla/security/nss/lib/ssl/ssl3con.c
76 +++ b/mozilla/security/nss/lib/ssl/ssl3con.c 97 +++ b/mozilla/security/nss/lib/ssl/ssl3con.c
77 @@ -81,6 +81,7 @@ static SECStatus ssl3_InitState( sslSocket *ss); 98 @@ -81,6 +81,7 @@ static SECStatus ssl3_InitState( sslSocket *ss);
78 static SECStatus ssl3_SendCertificate( sslSocket *ss); 99 static SECStatus ssl3_SendCertificate( sslSocket *ss);
79 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); 100 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss);
80 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); 101 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
81 +static SECStatus ssl3_SendNextProto( sslSocket *ss); 102 +static SECStatus ssl3_SendNextProto( sslSocket *ss);
82 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); 103 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags);
83 static SECStatus ssl3_SendServerHello( sslSocket *ss); 104 static SECStatus ssl3_SendServerHello( sslSocket *ss);
84 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); 105 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss);
(...skipping 15 matching lines...) Expand all
100 121
101 /* called from ssl3_HandleServerHelloDone 122 /* called from ssl3_HandleServerHelloDone
102 + */ 123 + */
103 +static SECStatus 124 +static SECStatus
104 +ssl3_SendNextProto(sslSocket *ss) 125 +ssl3_SendNextProto(sslSocket *ss)
105 +{ 126 +{
106 + SECStatus rv; 127 + SECStatus rv;
107 + int padding_len; 128 + int padding_len;
108 + static const unsigned char padding[32] = {0}; 129 + static const unsigned char padding[32] = {0};
109 + 130 +
110 + if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NO_SUPPORT) 131 + if (ss->ssl3.nextProto.len == 0)
111 + return SECSuccess; 132 + return SECSuccess;
112 + 133 +
113 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); 134 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
114 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); 135 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
115 + 136 +
116 + padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32); 137 + padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32);
117 + 138 +
118 + rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len + 139 + rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len +
119 + 2 + padding_len); 140 + 2 + padding_len);
120 + if (rv != SECSuccess) { 141 + if (rv != SECSuccess) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 ss->ssl3.initialized = PR_FALSE; 178 ss->ssl3.initialized = PR_FALSE;
158 + 179 +
159 + if (ss->ssl3.nextProto.data) { 180 + if (ss->ssl3.nextProto.data) {
160 + PORT_Free(ss->ssl3.nextProto.data); 181 + PORT_Free(ss->ssl3.nextProto.data);
161 + ss->ssl3.nextProto.data = NULL; 182 + ss->ssl3.nextProto.data = NULL;
162 + } 183 + }
163 } 184 }
164 185
165 /* End of ssl3con.c */ 186 /* End of ssl3con.c */
166 diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/s sl/ssl3ext.c 187 diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/s sl/ssl3ext.c
167 index becbfe9..fbd5a91 100644 188 index becbfe9..36ac4de 100644
168 --- a/mozilla/security/nss/lib/ssl/ssl3ext.c 189 --- a/mozilla/security/nss/lib/ssl/ssl3ext.c
169 +++ b/mozilla/security/nss/lib/ssl/ssl3ext.c 190 +++ b/mozilla/security/nss/lib/ssl/ssl3ext.c
170 @@ -235,6 +235,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = { 191 @@ -235,6 +235,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
171 #endif 192 #endif
172 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, 193 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
173 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 194 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
174 + { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, 195 + { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
175 { -1, NULL } 196 { -1, NULL }
176 }; 197 };
177 198
178 @@ -245,6 +246,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTL S[] = { 199 @@ -245,6 +246,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTL S[] = {
179 /* TODO: add a handler for ssl_ec_point_formats_xtn */ 200 /* TODO: add a handler for ssl_ec_point_formats_xtn */
180 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, 201 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
181 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, 202 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
182 + { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, 203 + { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
183 { -1, NULL } 204 { -1, NULL }
184 }; 205 };
185 206
186 @@ -267,7 +269,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTEN SIONS] = { 207 @@ -267,7 +269,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTEN SIONS] = {
187 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, 208 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
188 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, 209 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
189 #endif 210 #endif
190 - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn } 211 - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }
191 + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, 212 + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
192 + { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn } 213 + { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }
193 /* any extra entries will appear as { 0, NULL } */ 214 /* any extra entries will appear as { 0, NULL } */
194 }; 215 };
195 216
196 @@ -534,6 +537,123 @@ ssl3_SendSessionTicketXtn( 217 @@ -534,6 +537,105 @@ ssl3_SendSessionTicketXtn(
197 return -1; 218 return -1;
198 } 219 }
199 220
200 +/* handle an incoming Next Protocol Negotiation extension. */ 221 +/* handle an incoming Next Protocol Negotiation extension. */
201 +SECStatus 222 +SECStatus
202 +ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *da ta) 223 +ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *da ta)
203 +{ 224 +{
204 + if (data->len != 0) { 225 + if (data->len != 0) {
205 + /* Clients MUST send an empty NPN extension, if any. */ 226 + /* Clients MUST send an empty NPN extension, if any. */
206 + return SECFailure; 227 + return SECFailure;
207 + } 228 + }
208 + 229 +
209 + ss->ssl3.hs.nextProtoNego = PR_TRUE;
210 + return SECSuccess; 230 + return SECSuccess;
211 +} 231 +}
212 + 232 +
213 +/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: non e 233 +/* 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 234 + * of the lengths may be 0 and the sum of the lengths must equal the length of
215 + * the block. */ 235 + * the block. */
216 +SECStatus 236 +SECStatus
217 +ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) 237 +ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length)
218 +{ 238 +{
219 + unsigned int offset = 0; 239 + unsigned int offset = 0;
220 + 240 +
221 + while (offset < length) { 241 + while (offset < length) {
222 + if (data[offset] == 0) { 242 + if (data[offset] == 0) {
243 + PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
223 + return SECFailure; 244 + return SECFailure;
224 + } 245 + }
225 + offset += (unsigned int)data[offset] + 1; 246 + offset += (unsigned int)data[offset] + 1;
226 + } 247 + }
227 + 248 +
228 + if (offset > length) 249 + if (offset > length) {
250 +» PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
229 + return SECFailure; 251 + return SECFailure;
252 + }
230 + 253 +
231 + return SECSuccess; 254 + return SECSuccess;
232 +} 255 +}
233 + 256 +
234 +SECStatus 257 +SECStatus
235 +ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, 258 +ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
236 + SECItem *data) 259 + SECItem *data)
237 +{ 260 +{
238 + unsigned int i, j;
239 + SECStatus rv; 261 + SECStatus rv;
240 + unsigned char *result; 262 + unsigned char result[255];
241 + 263 + unsigned int 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 + 264 +
249 + rv = ssl3_ValidateNextProtoNego(data->data, data->len); 265 + rv = ssl3_ValidateNextProtoNego(data->data, data->len);
250 + if (rv != SECSuccess) 266 + if (rv != SECSuccess)
251 + return rv; 267 + return rv;
252 + 268 +
253 + /* For each protocol in server preference order, see if we support it. */ 269 + rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd,
254 + for (i = 0; i < data->len; ) { 270 + data->data, data->len,
255 +» for (j = 0; j < ss->opt.nextProtoNego.len; ) { 271 + result, &result_len);
256 +» if (data->data[i] == ss->opt.nextProtoNego.data[j] && 272 + if (rv != SECSuccess)
257 +» » memcmp(&data->data[i+1], &ss->opt.nextProtoNego.data[j+1], 273 +» return rv;
258 +» » data->data[i]) == 0) { 274 + // If the callback wrote more than allowed to |result| it has corrupted our
259 +» » /* We found a match */ 275 + // stack.
260 +» » ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; 276 + PORT_Assert(result_len <= sizeof(result));
261 +» » result = &data->data[i];
262 +» » goto found;
263 +» }
264 +» j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1;
265 +» }
266 + 277 +
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) 278 + if (ss->ssl3.nextProto.data)
276 + PORT_Free(ss->ssl3.nextProto.data); 279 + PORT_Free(ss->ssl3.nextProto.data);
277 + ss->ssl3.nextProto.data = PORT_Alloc(result[0]); 280 + ss->ssl3.nextProto.data = PORT_Alloc(result_len);
278 + PORT_Memcpy(ss->ssl3.nextProto.data, result + 1, result[0]); 281 + PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len);
279 + ss->ssl3.nextProto.len = result[0]; 282 + ss->ssl3.nextProto.len = result_len;
280 + return SECSuccess; 283 + return SECSuccess;
281 +} 284 +}
282 + 285 +
283 +PRInt32 286 +PRInt32
284 +ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, 287 +ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss,
285 + PRBool append, 288 + PRBool append,
286 + PRUint32 maxBytes) 289 + PRUint32 maxBytes)
287 +{ 290 +{
288 + PRInt32 extension_length; 291 + PRInt32 extension_length;
289 + 292 +
290 + /* Renegotiations do not send this extension. */ 293 + /* Renegotiations do not send this extension. */
291 + if (ss->opt.nextProtoNego.len == 0 || ss->firstHsDone) { 294 + if (!ss->nextProtoCallback || ss->firstHsDone) {
292 + return 0; 295 + return 0;
293 + } 296 + }
294 + 297 +
295 + extension_length = 4; 298 + extension_length = 4;
296 + 299 +
297 + if (append && maxBytes >= extension_length) { 300 + if (append && maxBytes >= extension_length) {
298 + SECStatus rv; 301 + SECStatus rv;
299 + rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); 302 + rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2);
300 + if (rv != SECSuccess) 303 + if (rv != SECSuccess)
301 + goto loser; 304 + goto loser;
(...skipping 22 matching lines...) Expand all
324 @@ -157,7 +157,8 @@ typedef enum { 327 @@ -157,7 +157,8 @@ typedef enum {
325 server_hello_done = 14, 328 server_hello_done = 14,
326 certificate_verify = 15, 329 certificate_verify = 15,
327 client_key_exchange = 16, 330 client_key_exchange = 16,
328 - finished = 20 331 - finished = 20
329 + finished = 20, 332 + finished = 20,
330 + next_proto = 67 333 + next_proto = 67
331 } SSL3HandshakeType; 334 } SSL3HandshakeType;
332 335
333 typedef struct { 336 typedef struct {
337 diff --git a/mozilla/security/nss/lib/ssl/sslerr.h b/mozilla/security/nss/lib/ss l/sslerr.h
338 index a2f6524..c76ffa9 100644
339 --- a/mozilla/security/nss/lib/ssl/sslerr.h
340 +++ b/mozilla/security/nss/lib/ssl/sslerr.h
341 @@ -203,6 +203,8 @@ SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD = (SSL_ERROR_BAS E + 114),
342
343 SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY = (SSL_ERROR_BASE + 115),
344
345 +SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID = (SSL_ERROR_BASE + 117),
346 +
347 SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
348 } SSLErrorCodes;
349 #endif /* NO_SECURITY_ERROR_ENUM */
334 diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/s sl/sslimpl.h 350 diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/s sl/sslimpl.h
335 index 9af471d..d1c1181 100644 351 index 9af471d..199c573 100644
336 --- a/mozilla/security/nss/lib/ssl/sslimpl.h 352 --- a/mozilla/security/nss/lib/ssl/sslimpl.h
337 +++ b/mozilla/security/nss/lib/ssl/sslimpl.h 353 +++ b/mozilla/security/nss/lib/ssl/sslimpl.h
338 @@ -313,6 +313,11 @@ typedef struct { 354 @@ -313,6 +313,10 @@ typedef struct {
339 #endif /* NSS_ENABLE_ECC */ 355 #endif /* NSS_ENABLE_ECC */
340 356
341 typedef struct sslOptionsStr { 357 typedef struct sslOptionsStr {
342 + /* For clients, this is a validated list of protocols in preference order 358 + /* If SSL_SetNextProtoNego has been called, then this contains the
343 + * and wire format. For servers, this is the list of support protocols, 359 + * list of supported protocols. */
344 + * also in wire format. */
345 + SECItem nextProtoNego; 360 + SECItem nextProtoNego;
346 + 361 +
347 unsigned int useSecurity : 1; /* 1 */ 362 unsigned int useSecurity : 1; /* 1 */
348 unsigned int useSocks : 1; /* 2 */ 363 unsigned int useSocks : 1; /* 2 */
349 unsigned int requestCertificate : 1; /* 3 */ 364 unsigned int requestCertificate : 1; /* 3 */
350 @@ -786,6 +791,7 @@ const ssl3CipherSuiteDef *suite_def; 365 @@ -827,6 +831,13 @@ struct ssl3StateStr {
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; 366 PRBool initialized;
360 SSL3HandshakeState hs; 367 SSL3HandshakeState hs;
361 ssl3CipherSpec specs[2]; /* one is current, one is pending. */ 368 ssl3CipherSpec specs[2]; /* one is current, one is pending. */
362 + 369 +
363 + /* In a client: if the server supports Next Protocol Negotiation, then 370 + /* In a client: if the server supports Next Protocol Negotiation, then
364 + * this is the protocol that was requested. 371 + * this is the protocol that was negotiated.
365 + * In a server: this is the protocol that the client requested via Next
366 + * Protocol Negotiation.
367 + * 372 + *
368 + * In either case, if the data pointer is non-NULL, then it is malloced 373 + * If the data pointer is non-NULL, then it is malloced data. */
369 + * data. */
370 + SECItem nextProto; 374 + SECItem nextProto;
371 + int» » » nextProtoState;»/* See SSL_NEXT_PROTO_* defines */ 375 + int» » » nextProtoState; /* See NEXT_PROTO_* defines */
372 }; 376 };
373 377
374 typedef struct { 378 typedef struct {
375 @@ -1494,8 +1510,12 @@ extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslS ocket * ss, 379 @@ -1058,6 +1069,8 @@ const unsigned char * preferredCipher;
380 SSLHandshakeCallback handshakeCallback;
381 void *handshakeCallbackData;
382 void *pkcs11PinArg;
383 + SSLNextProtoCallback nextProtoCallback;
384 + void *nextProtoArg;
385
386 PRIntervalTime rTimeout; /* timeout for NSPR I/O */
387 PRIntervalTime wTimeout; /* timeout for NSPR I/O */
388 @@ -1494,8 +1507,12 @@ extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslS ocket * ss,
376 PRUint16 ex_type, SECItem *data); 389 PRUint16 ex_type, SECItem *data);
377 extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss, 390 extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss,
378 PRUint16 ex_type, SECItem *data); 391 PRUint16 ex_type, SECItem *data);
379 +extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, 392 +extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
380 + PRUint16 ex_type, SECItem *data); 393 + PRUint16 ex_type, SECItem *data);
381 extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss, 394 extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss,
382 PRUint16 ex_type, SECItem *data); 395 PRUint16 ex_type, SECItem *data);
383 +extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss, 396 +extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
384 + PRUint16 ex_type, SECItem *data); 397 + PRUint16 ex_type, SECItem *data);
385 398
386 /* ClientHello and ServerHello extension senders. 399 /* ClientHello and ServerHello extension senders.
387 * Note that not all extension senders are exposed here; only those that 400 * Note that not all extension senders are exposed here; only those that
388 @@ -1526,6 +1546,10 @@ extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss, 401 @@ -1526,6 +1543,10 @@ extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss,
389 extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss, 402 extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss,
390 PRBool append, PRUint32 maxBytes); 403 PRBool append, PRUint32 maxBytes);
391 #endif 404 #endif
392 +extern PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append, 405 +extern PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
393 + PRUint32 maxBytes); 406 + PRUint32 maxBytes);
394 +extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data, 407 +extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data,
395 + unsigned short length); 408 + unsigned short length);
396 409
397 /* call the registered extension handlers. */ 410 /* call the registered extension handlers. */
398 extern SECStatus ssl3_HandleHelloExtensions(sslSocket *ss, 411 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 412 diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/s sl/sslsock.c
400 index bc770a1..4c8fbfd 100644 413 index bc770a1..769ea0a 100644
401 --- a/mozilla/security/nss/lib/ssl/sslsock.c 414 --- a/mozilla/security/nss/lib/ssl/sslsock.c
402 +++ b/mozilla/security/nss/lib/ssl/sslsock.c 415 +++ b/mozilla/security/nss/lib/ssl/sslsock.c
403 @@ -163,6 +163,7 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */ 416 @@ -163,6 +163,7 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */
404 ** default settings for socket enables 417 ** default settings for socket enables
405 */ 418 */
406 static sslOptions ssl_defaults = { 419 static sslOptions ssl_defaults = {
407 + { siBuffer, NULL, 0 }, /* nextProtoNego */ 420 + { siBuffer, NULL, 0 }, /* nextProtoNego */
408 PR_TRUE, /* useSecurity */ 421 PR_TRUE, /* useSecurity */
409 PR_FALSE, /* useSocks */ 422 PR_FALSE, /* useSocks */
410 PR_FALSE, /* requestCertificate */ 423 PR_FALSE, /* requestCertificate */
411 @@ -438,6 +439,10 @@ ssl_DestroySocketContents(sslSocket *ss) 424 @@ -438,6 +439,10 @@ ssl_DestroySocketContents(sslSocket *ss)
412 ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair); 425 ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
413 ss->ephemeralECDHKeyPair = NULL; 426 ss->ephemeralECDHKeyPair = NULL;
414 } 427 }
415 + if (ss->opt.nextProtoNego.data) { 428 + if (ss->opt.nextProtoNego.data) {
416 + PORT_Free(ss->opt.nextProtoNego.data); 429 + PORT_Free(ss->opt.nextProtoNego.data);
417 + ss->opt.nextProtoNego.data = NULL; 430 + ss->opt.nextProtoNego.data = NULL;
418 + } 431 + }
419 PORT_Assert(!ss->xtnData.sniNameArr); 432 PORT_Assert(!ss->xtnData.sniNameArr);
420 if (ss->xtnData.sniNameArr) { 433 if (ss->xtnData.sniNameArr) {
421 PORT_Free(ss->xtnData.sniNameArr); 434 PORT_Free(ss->xtnData.sniNameArr);
422 @@ -1266,6 +1271,75 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd) 435 @@ -1266,6 +1271,132 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
423 return fd; 436 return fd;
424 } 437 }
425 438
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 439 +SECStatus
429 +SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data, 440 +SSL_SetNextProtoCallback(PRFileDesc *fd,
430 +» » unsigned short length) 441 + SSLNextProtoCallback callback,
431 +{ 442 + void *arg) {
432 + sslSocket *ss = ssl_FindSocket(fd); 443 + sslSocket *ss = ssl_FindSocket(fd);
433 + 444 +
434 + if (!ss) { 445 + if (!ss) {
435 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", SSL_GETPID() , 446 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", SSL_GETPID() ,
436 + fd)); 447 + fd));
437 + return SECFailure; 448 + return SECFailure;
438 + } 449 + }
439 + 450 +
451 + ssl_GetSSL3HandshakeLock(ss);
452 + ss->nextProtoCallback = callback;
453 + ss->nextProtoArg = arg;
454 + ssl_ReleaseSSL3HandshakeLock(ss);
455 +}
456 +
457 +/* NextProtoStandardCallback is set as an NPN callback for the case when the
458 + * user of the sockets wants the standard selection algorithm. */
459 +static SECStatus
460 +NextProtoStandardCallback(void *arg,
461 + PRFileDesc *fd,
462 + const unsigned char *protos,
463 + unsigned int protos_len,
464 + unsigned char *protoOut,
465 + unsigned int *protoOutLen)
466 +{
467 + unsigned int i, j;
468 + const unsigned char *result;
469 +
470 + sslSocket *ss = ssl_FindSocket(fd);
471 + PORT_Assert(ss);
472 +
473 + if (protos_len == 0) {
474 + /* The server supports the extension, but doesn't have any protocols
475 + * configured. In this case we request our favoured protocol. */
476 + goto pick_first;
477 + }
478 +
479 + /* For each protocol in server preference, see if we support it. */
480 + for (i = 0; i < protos_len; ) {
481 + for (j = 0; j < ss->opt.nextProtoNego.len; ) {
482 + if (protos[i] == ss->opt.nextProtoNego.data[j] &&
483 + memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1],
484 + protos[i]) == 0) {
485 + /* We found a match. */
486 + ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
487 + result = &protos[i];
488 + goto found;
489 + }
490 + j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1;
491 + }
492 + i += (unsigned int)protos[i] + 1;
493 + }
494 +
495 +pick_first:
496 + ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
497 + result = ss->opt.nextProtoNego.data;
498 +
499 +found:
500 + memcpy(protoOut, result + 1, result[0]);
501 + *protoOutLen = result[0];
502 + return SECSuccess;
503 +}
504 +
505 +SECStatus
506 +SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
507 + unsigned int length)
508 +{
509 + SECStatus rv;
510 +
511 + sslSocket *ss = ssl_FindSocket(fd);
512 +
513 + if (!ss) {
514 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego",
515 + SSL_GETPID(), fd));
516 + return SECFailure;
517 + }
518 +
440 + if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess) 519 + if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess)
441 + return SECFailure; 520 + return SECFailure;
442 + 521 +
443 + ssl_GetSSL3HandshakeLock(ss); 522 + ssl_GetSSL3HandshakeLock(ss);
444 + if (ss->opt.nextProtoNego.data) 523 + if (ss->opt.nextProtoNego.data)
445 + PORT_Free(ss->opt.nextProtoNego.data); 524 + PORT_Free(ss->opt.nextProtoNego.data);
446 + ss->opt.nextProtoNego.data = PORT_Alloc(length); 525 + ss->opt.nextProtoNego.data = PORT_Alloc(length);
447 + if (!ss->opt.nextProtoNego.data) { 526 + if (!ss->opt.nextProtoNego.data) {
448 + ssl_ReleaseSSL3HandshakeLock(ss); 527 + ssl_ReleaseSSL3HandshakeLock(ss);
449 + return SECFailure; 528 + return SECFailure;
450 + } 529 + }
451 + memcpy(ss->opt.nextProtoNego.data, data, length); 530 + memcpy(ss->opt.nextProtoNego.data, data, length);
452 + ss->opt.nextProtoNego.len = length; 531 + ss->opt.nextProtoNego.len = length;
453 + ss->opt.nextProtoNego.type = siBuffer; 532 + ss->opt.nextProtoNego.type = siBuffer;
454 + ssl_ReleaseSSL3HandshakeLock(ss); 533 + ssl_ReleaseSSL3HandshakeLock(ss);
455 + 534 +
456 + return SECSuccess; 535 + return SSL_SetNextProtoCallback(fd, NextProtoStandardCallback, NULL);
457 +} 536 +}
458 + 537 +
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 538 +SECStatus
469 +SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf, 539 +SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf,
470 + unsigned int *length, unsigned int buf_len) 540 + unsigned int *length, unsigned int buf_len)
471 +{ 541 +{
472 + sslSocket *ss = ssl_FindSocket(fd); 542 + sslSocket *ss = ssl_FindSocket(fd);
473 + 543 +
474 + if (!ss) { 544 + if (!ss) {
475 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(), 545 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(),
476 + fd)); 546 + fd));
477 + return SECFailure; 547 + return SECFailure;
(...skipping 26 matching lines...) Expand all
504 #endif 574 #endif
505 ssl_session_ticket_xtn = 35, 575 ssl_session_ticket_xtn = 35,
506 + ssl_next_proto_neg_xtn = 13172, 576 + ssl_next_proto_neg_xtn = 13172,
507 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ 577 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
508 } SSLExtensionType; 578 } SSLExtensionType;
509 579
510 -#define SSL_MAX_EXTENSIONS 5 580 -#define SSL_MAX_EXTENSIONS 5
511 +#define SSL_MAX_EXTENSIONS 6 581 +#define SSL_MAX_EXTENSIONS 6
512 582
513 #endif /* __sslt_h_ */ 583 #endif /* __sslt_h_ */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698