| OLD | NEW |
| 1 From 6b594dc531e7a1d1d5bca2f0f78e7bc0ac3ff937 Mon Sep 17 00:00:00 2001 | 1 From eea4c5e3cedfbe9eca1026487098aa236b7dcc17 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 | 49 ++++++++++++ |
| 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 | 4 + |
| 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 | 130 +++++++++++++++++++++++++++++++ |
| 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, 371 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..5b80efa 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,55 @@ 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 of length 255 |
| 44 + * (the maximum allowed by the protocol) which, on successful return, must |
| 45 + * contain the protocol to be announced to the server. */ |
| 46 +typedef SECStatus (PR_CALLBACK *SSLNextProtoCallback)( |
| 47 + void *arg, |
| 48 + PRFileDesc *fd, |
| 49 + const unsigned char* protos, |
| 50 + unsigned int protosLen, |
| 51 + unsigned char* protoOut, |
| 52 + unsigned int* protoOutLen); |
| 53 + |
| 54 +/* SSL_SetNextProtoCallback sets a callback function to handle Next Protocol |
| 55 + * Negotiation. It causes a client to advertise NPN. */ |
| 56 +SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd, |
| 57 + SSLNextProtoCallback callback, |
| 58 + void *arg); |
| 59 + |
| 60 +/* SSL_SetNextProtoNego can be used as an alternative to |
| 61 + * SSL_SetNextProtoCallback. It also causes a client to advertise NPN and |
| 62 + * installs a default callback function which selects the first supported |
| 63 + * protocol in server-preference order. Otherwise it selects the first |
| 64 + * supported protocol. |
| 65 + * |
| 66 + * The supported protocols are specified in |data| in wire-format (8-bit |
| 67 + * length-prefixed). For example: "\010http/1.1\006spdy/2". */ |
| 58 +SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd, | 68 +SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd, |
| 59 + const unsigned char *data, | 69 + const unsigned char *data, |
| 60 +» » » » » unsigned short length); | 70 +» » » » » unsigned int length); |
| 71 +/* SSL_GetNextProto can be used after a handshake on a socket where |
| 72 + * SSL_SetNextProtoNego was called to retrieve the result of the Next Protocol |
| 73 + * negotiation. |
| 74 + * |
| 75 + * state is set to one of the SSL_NEXT_PROTO_* constants. The negotiated |
| 76 + * protocol, if any, is written into buf, which must be at least buf_len bytes |
| 77 + * long. If the negotiated protocol is longer than this, it is truncated. The |
| 78 + * number of bytes copied is written into length. */ |
| 61 +SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd, | 79 +SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd, |
| 62 + int *state, | 80 + int *state, |
| 63 + unsigned char *buf, | 81 + unsigned char *buf, |
| 64 + unsigned *length, | 82 + unsigned *length, |
| 65 + unsigned buf_len); | 83 + unsigned buf_len); |
| 84 + |
| 66 +#define SSL_NEXT_PROTO_NO_SUPPORT 0 /* No peer support */ | 85 +#define SSL_NEXT_PROTO_NO_SUPPORT 0 /* No peer support */ |
| 67 +#define SSL_NEXT_PROTO_NEGOTIATED 1 /* Mutual agreement */ | 86 +#define SSL_NEXT_PROTO_NEGOTIATED 1 /* Mutual agreement */ |
| 68 +#define SSL_NEXT_PROTO_NO_OVERLAP 2 /* No protocol overlap found */ | 87 +#define SSL_NEXT_PROTO_NO_OVERLAP 2 /* No protocol overlap found */ |
| 69 + | 88 + |
| 70 /* | 89 /* |
| 71 ** Control ciphers that SSL uses. If on is non-zero then the named cipher | 90 ** Control ciphers that SSL uses. If on is non-zero then the named cipher |
| 72 ** is enabled, otherwise it is disabled. | 91 ** 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 | 92 diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/s
sl/ssl3con.c |
| 74 index 8048913..e0cb4e9 100644 | 93 index 8048913..8f860a9 100644 |
| 75 --- a/mozilla/security/nss/lib/ssl/ssl3con.c | 94 --- a/mozilla/security/nss/lib/ssl/ssl3con.c |
| 76 +++ b/mozilla/security/nss/lib/ssl/ssl3con.c | 95 +++ b/mozilla/security/nss/lib/ssl/ssl3con.c |
| 77 @@ -81,6 +81,7 @@ static SECStatus ssl3_InitState( sslSocket *ss); | 96 @@ -81,6 +81,7 @@ static SECStatus ssl3_InitState( sslSocket *ss); |
| 78 static SECStatus ssl3_SendCertificate( sslSocket *ss); | 97 static SECStatus ssl3_SendCertificate( sslSocket *ss); |
| 79 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); | 98 static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss); |
| 80 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); | 99 static SECStatus ssl3_SendCertificateRequest(sslSocket *ss); |
| 81 +static SECStatus ssl3_SendNextProto( sslSocket *ss); | 100 +static SECStatus ssl3_SendNextProto( sslSocket *ss); |
| 82 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); | 101 static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags); |
| 83 static SECStatus ssl3_SendServerHello( sslSocket *ss); | 102 static SECStatus ssl3_SendServerHello( sslSocket *ss); |
| 84 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); | 103 static SECStatus ssl3_SendServerHelloDone( sslSocket *ss); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 100 | 119 |
| 101 /* called from ssl3_HandleServerHelloDone | 120 /* called from ssl3_HandleServerHelloDone |
| 102 + */ | 121 + */ |
| 103 +static SECStatus | 122 +static SECStatus |
| 104 +ssl3_SendNextProto(sslSocket *ss) | 123 +ssl3_SendNextProto(sslSocket *ss) |
| 105 +{ | 124 +{ |
| 106 + SECStatus rv; | 125 + SECStatus rv; |
| 107 + int padding_len; | 126 + int padding_len; |
| 108 + static const unsigned char padding[32] = {0}; | 127 + static const unsigned char padding[32] = {0}; |
| 109 + | 128 + |
| 110 + if (ss->ssl3.nextProtoState == SSL_NEXT_PROTO_NO_SUPPORT) | 129 + if (ss->ssl3.nextProto.len == 0) |
| 111 + return SECSuccess; | 130 + return SECSuccess; |
| 112 + | 131 + |
| 113 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); | 132 + PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss)); |
| 114 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); | 133 + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss)); |
| 115 + | 134 + |
| 116 + padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32); | 135 + padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32); |
| 117 + | 136 + |
| 118 + rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len + | 137 + rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len + |
| 119 + 2 + padding_len); | 138 + 2 + padding_len); |
| 120 + if (rv != SECSuccess) { | 139 + if (rv != SECSuccess) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 ss->ssl3.initialized = PR_FALSE; | 176 ss->ssl3.initialized = PR_FALSE; |
| 158 + | 177 + |
| 159 + if (ss->ssl3.nextProto.data) { | 178 + if (ss->ssl3.nextProto.data) { |
| 160 + PORT_Free(ss->ssl3.nextProto.data); | 179 + PORT_Free(ss->ssl3.nextProto.data); |
| 161 + ss->ssl3.nextProto.data = NULL; | 180 + ss->ssl3.nextProto.data = NULL; |
| 162 + } | 181 + } |
| 163 } | 182 } |
| 164 | 183 |
| 165 /* End of ssl3con.c */ | 184 /* End of ssl3con.c */ |
| 166 diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/s
sl/ssl3ext.c | 185 diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/s
sl/ssl3ext.c |
| 167 index becbfe9..fbd5a91 100644 | 186 index becbfe9..36ac4de 100644 |
| 168 --- a/mozilla/security/nss/lib/ssl/ssl3ext.c | 187 --- a/mozilla/security/nss/lib/ssl/ssl3ext.c |
| 169 +++ b/mozilla/security/nss/lib/ssl/ssl3ext.c | 188 +++ b/mozilla/security/nss/lib/ssl/ssl3ext.c |
| 170 @@ -235,6 +235,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[]
= { | 189 @@ -235,6 +235,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[]
= { |
| 171 #endif | 190 #endif |
| 172 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, | 191 { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn }, |
| 173 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 192 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 174 + { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, | 193 + { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn }, |
| 175 { -1, NULL } | 194 { -1, NULL } |
| 176 }; | 195 }; |
| 177 | 196 |
| 178 @@ -245,6 +246,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTL
S[] = { | 197 @@ -245,6 +246,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTL
S[] = { |
| 179 /* TODO: add a handler for ssl_ec_point_formats_xtn */ | 198 /* TODO: add a handler for ssl_ec_point_formats_xtn */ |
| 180 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, | 199 { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn }, |
| 181 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, | 200 { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn }, |
| 182 + { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, | 201 + { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn }, |
| 183 { -1, NULL } | 202 { -1, NULL } |
| 184 }; | 203 }; |
| 185 | 204 |
| 186 @@ -267,7 +269,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTEN
SIONS] = { | 205 @@ -267,7 +269,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTEN
SIONS] = { |
| 187 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, | 206 { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn }, |
| 188 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, | 207 { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn }, |
| 189 #endif | 208 #endif |
| 190 - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn } | 209 - { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn } |
| 191 + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, | 210 + { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }, |
| 192 + { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn } | 211 + { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn } |
| 193 /* any extra entries will appear as { 0, NULL } */ | 212 /* any extra entries will appear as { 0, NULL } */ |
| 194 }; | 213 }; |
| 195 | 214 |
| 196 @@ -534,6 +537,123 @@ ssl3_SendSessionTicketXtn( | 215 @@ -534,6 +537,105 @@ ssl3_SendSessionTicketXtn( |
| 197 return -1; | 216 return -1; |
| 198 } | 217 } |
| 199 | 218 |
| 200 +/* handle an incoming Next Protocol Negotiation extension. */ | 219 +/* handle an incoming Next Protocol Negotiation extension. */ |
| 201 +SECStatus | 220 +SECStatus |
| 202 +ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *da
ta) | 221 +ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *da
ta) |
| 203 +{ | 222 +{ |
| 204 + if (data->len != 0) { | 223 + if (data->len != 0) { |
| 205 + /* Clients MUST send an empty NPN extension, if any. */ | 224 + /* Clients MUST send an empty NPN extension, if any. */ |
| 206 + return SECFailure; | 225 + return SECFailure; |
| 207 + } | 226 + } |
| 208 + | 227 + |
| 209 + ss->ssl3.hs.nextProtoNego = PR_TRUE; | |
| 210 + return SECSuccess; | 228 + return SECSuccess; |
| 211 +} | 229 +} |
| 212 + | 230 + |
| 213 +/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: non
e | 231 +/* 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 | 232 + * of the lengths may be 0 and the sum of the lengths must equal the length of |
| 215 + * the block. */ | 233 + * the block. */ |
| 216 +SECStatus | 234 +SECStatus |
| 217 +ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) | 235 +ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length) |
| 218 +{ | 236 +{ |
| 219 + unsigned int offset = 0; | 237 + unsigned int offset = 0; |
| 220 + | 238 + |
| 221 + while (offset < length) { | 239 + while (offset < length) { |
| 222 + if (data[offset] == 0) { | 240 + if (data[offset] == 0) { |
| 241 + PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); |
| 223 + return SECFailure; | 242 + return SECFailure; |
| 224 + } | 243 + } |
| 225 + offset += (unsigned int)data[offset] + 1; | 244 + offset += (unsigned int)data[offset] + 1; |
| 226 + } | 245 + } |
| 227 + | 246 + |
| 228 + if (offset > length) | 247 + if (offset > length) { |
| 248 +» PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID); |
| 229 + return SECFailure; | 249 + return SECFailure; |
| 250 + } |
| 230 + | 251 + |
| 231 + return SECSuccess; | 252 + return SECSuccess; |
| 232 +} | 253 +} |
| 233 + | 254 + |
| 234 +SECStatus | 255 +SECStatus |
| 235 +ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, | 256 +ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type, |
| 236 + SECItem *data) | 257 + SECItem *data) |
| 237 +{ | 258 +{ |
| 238 + unsigned int i, j; | |
| 239 + SECStatus rv; | 259 + SECStatus rv; |
| 240 + unsigned char *result; | 260 + unsigned char result[255]; |
| 241 + | 261 + 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 + | 262 + |
| 249 + rv = ssl3_ValidateNextProtoNego(data->data, data->len); | 263 + rv = ssl3_ValidateNextProtoNego(data->data, data->len); |
| 250 + if (rv != SECSuccess) | 264 + if (rv != SECSuccess) |
| 251 + return rv; | 265 + return rv; |
| 252 + | 266 + |
| 253 + /* For each protocol in server preference order, see if we support it. */ | 267 + rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd, |
| 254 + for (i = 0; i < data->len; ) { | 268 + data->data, data->len, |
| 255 +» for (j = 0; j < ss->opt.nextProtoNego.len; ) { | 269 + result, &result_len); |
| 256 +» if (data->data[i] == ss->opt.nextProtoNego.data[j] && | 270 + if (rv != SECSuccess) |
| 257 +» » memcmp(&data->data[i+1], &ss->opt.nextProtoNego.data[j+1], | 271 +» return rv; |
| 258 +» » data->data[i]) == 0) { | 272 + // If the callback wrote more than allowed to |result| it has corrupted our |
| 259 +» » /* We found a match */ | 273 + // stack. |
| 260 +» » ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; | 274 + 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 + | 275 + |
| 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) | 276 + if (ss->ssl3.nextProto.data) |
| 276 + PORT_Free(ss->ssl3.nextProto.data); | 277 + PORT_Free(ss->ssl3.nextProto.data); |
| 277 + ss->ssl3.nextProto.data = PORT_Alloc(result[0]); | 278 + ss->ssl3.nextProto.data = PORT_Alloc(result_len); |
| 278 + PORT_Memcpy(ss->ssl3.nextProto.data, result + 1, result[0]); | 279 + PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len); |
| 279 + ss->ssl3.nextProto.len = result[0]; | 280 + ss->ssl3.nextProto.len = result_len; |
| 280 + return SECSuccess; | 281 + return SECSuccess; |
| 281 +} | 282 +} |
| 282 + | 283 + |
| 283 +PRInt32 | 284 +PRInt32 |
| 284 +ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, | 285 +ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss, |
| 285 + PRBool append, | 286 + PRBool append, |
| 286 + PRUint32 maxBytes) | 287 + PRUint32 maxBytes) |
| 287 +{ | 288 +{ |
| 288 + PRInt32 extension_length; | 289 + PRInt32 extension_length; |
| 289 + | 290 + |
| 290 + /* Renegotiations do not send this extension. */ | 291 + /* Renegotiations do not send this extension. */ |
| 291 + if (ss->opt.nextProtoNego.len == 0 || ss->firstHsDone) { | 292 + if (!ss->nextProtoCallback || ss->firstHsDone) { |
| 292 + return 0; | 293 + return 0; |
| 293 + } | 294 + } |
| 294 + | 295 + |
| 295 + extension_length = 4; | 296 + extension_length = 4; |
| 296 + | 297 + |
| 297 + if (append && maxBytes >= extension_length) { | 298 + if (append && maxBytes >= extension_length) { |
| 298 + SECStatus rv; | 299 + SECStatus rv; |
| 299 + rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); | 300 + rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2); |
| 300 + if (rv != SECSuccess) | 301 + if (rv != SECSuccess) |
| 301 + goto loser; | 302 + goto loser; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 324 @@ -157,7 +157,8 @@ typedef enum { | 325 @@ -157,7 +157,8 @@ typedef enum { |
| 325 server_hello_done = 14, | 326 server_hello_done = 14, |
| 326 certificate_verify = 15, | 327 certificate_verify = 15, |
| 327 client_key_exchange = 16, | 328 client_key_exchange = 16, |
| 328 - finished = 20 | 329 - finished = 20 |
| 329 + finished = 20, | 330 + finished = 20, |
| 330 + next_proto = 67 | 331 + next_proto = 67 |
| 331 } SSL3HandshakeType; | 332 } SSL3HandshakeType; |
| 332 | 333 |
| 333 typedef struct { | 334 typedef struct { |
| 335 diff --git a/mozilla/security/nss/lib/ssl/sslerr.h b/mozilla/security/nss/lib/ss
l/sslerr.h |
| 336 index a2f6524..2f984d4 100644 |
| 337 --- a/mozilla/security/nss/lib/ssl/sslerr.h |
| 338 +++ b/mozilla/security/nss/lib/ssl/sslerr.h |
| 339 @@ -203,6 +203,10 @@ SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD = (SSL_E
RROR_BASE + 114), |
| 340 |
| 341 SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY = (SSL_ERROR_BASE + 115), |
| 342 |
| 343 +// SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID results if the peer sends invalid next |
| 344 +// protocol information during a handshake. |
| 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..0da3c63 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,131 @@ 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], protos[i]
) == 0) { |
| 484 + /* We found a match. */ |
| 485 + ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED; |
| 486 + result = &protos[i]; |
| 487 + goto found; |
| 488 + } |
| 489 + j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1; |
| 490 + } |
| 491 + i += (unsigned int)protos[i] + 1; |
| 492 + } |
| 493 + |
| 494 + pick_first: |
| 495 + ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP; |
| 496 + result = ss->opt.nextProtoNego.data; |
| 497 + |
| 498 + found: |
| 499 + memcpy(protoOut, result + 1, result[0]); |
| 500 + *protoOutLen = result[0]; |
| 501 + return SECSuccess; |
| 502 +} |
| 503 + |
| 504 +SECStatus |
| 505 +SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data, |
| 506 + unsigned int length) |
| 507 +{ |
| 508 + SECStatus rv; |
| 509 + |
| 510 + sslSocket *ss = ssl_FindSocket(fd); |
| 511 + |
| 512 + if (!ss) { |
| 513 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", |
| 514 + SSL_GETPID(), fd)); |
| 515 + return SECFailure; |
| 516 + } |
| 517 + |
| 440 + if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess) | 518 + if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess) |
| 441 + return SECFailure; | 519 + return SECFailure; |
| 442 + | 520 + |
| 443 + ssl_GetSSL3HandshakeLock(ss); | 521 + ssl_GetSSL3HandshakeLock(ss); |
| 444 + if (ss->opt.nextProtoNego.data) | 522 + if (ss->opt.nextProtoNego.data) |
| 445 + PORT_Free(ss->opt.nextProtoNego.data); | 523 + PORT_Free(ss->opt.nextProtoNego.data); |
| 446 + ss->opt.nextProtoNego.data = PORT_Alloc(length); | 524 + ss->opt.nextProtoNego.data = PORT_Alloc(length); |
| 447 + if (!ss->opt.nextProtoNego.data) { | 525 + if (!ss->opt.nextProtoNego.data) { |
| 448 + ssl_ReleaseSSL3HandshakeLock(ss); | 526 + ssl_ReleaseSSL3HandshakeLock(ss); |
| 449 + return SECFailure; | 527 + return SECFailure; |
| 450 + } | 528 + } |
| 451 + memcpy(ss->opt.nextProtoNego.data, data, length); | 529 + memcpy(ss->opt.nextProtoNego.data, data, length); |
| 452 + ss->opt.nextProtoNego.len = length; | 530 + ss->opt.nextProtoNego.len = length; |
| 453 + ss->opt.nextProtoNego.type = siBuffer; | 531 + ss->opt.nextProtoNego.type = siBuffer; |
| 454 + ssl_ReleaseSSL3HandshakeLock(ss); | 532 + ssl_ReleaseSSL3HandshakeLock(ss); |
| 455 + | 533 + |
| 456 + return SECSuccess; | 534 + return SSL_SetNextProtoCallback(fd, NextProtoStandardCallback, NULL); |
| 457 +} | 535 +} |
| 458 + | 536 + |
| 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 | 537 +SECStatus |
| 469 +SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf, | 538 +SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf, |
| 470 + unsigned int *length, unsigned int buf_len) | 539 + unsigned int *length, unsigned int buf_len) |
| 471 +{ | 540 +{ |
| 472 + sslSocket *ss = ssl_FindSocket(fd); | 541 + sslSocket *ss = ssl_FindSocket(fd); |
| 473 + | 542 + |
| 474 + if (!ss) { | 543 + if (!ss) { |
| 475 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(), | 544 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(), |
| 476 + fd)); | 545 + fd)); |
| 477 + return SECFailure; | 546 + return SECFailure; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 504 #endif | 573 #endif |
| 505 ssl_session_ticket_xtn = 35, | 574 ssl_session_ticket_xtn = 35, |
| 506 + ssl_next_proto_neg_xtn = 13172, | 575 + ssl_next_proto_neg_xtn = 13172, |
| 507 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ | 576 ssl_renegotiation_info_xtn = 0xff01 /* experimental number */ |
| 508 } SSLExtensionType; | 577 } SSLExtensionType; |
| 509 | 578 |
| 510 -#define SSL_MAX_EXTENSIONS 5 | 579 -#define SSL_MAX_EXTENSIONS 5 |
| 511 +#define SSL_MAX_EXTENSIONS 6 | 580 +#define SSL_MAX_EXTENSIONS 6 |
| 512 | 581 |
| 513 #endif /* __sslt_h_ */ | 582 #endif /* __sslt_h_ */ |
| OLD | NEW |