| 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 |