| Index: net/third_party/nss/patches/nextproto.patch
|
| ===================================================================
|
| --- net/third_party/nss/patches/nextproto.patch (revision 123842)
|
| +++ net/third_party/nss/patches/nextproto.patch (working copy)
|
| @@ -1,592 +0,0 @@
|
| -From 0c2f72b38711abdd4ada08ae8d7e96dce79a672b Mon Sep 17 00:00:00 2001
|
| -From: Adam Langley <agl@chromium.org>
|
| -Date: Mon, 3 Oct 2011 12:19:28 -0400
|
| -Subject: [PATCH 01/15] nextproto.patch
|
| -
|
| ----
|
| - mozilla/security/nss/lib/ssl/ssl.def | 8 ++
|
| - mozilla/security/nss/lib/ssl/ssl.h | 51 ++++++++++++
|
| - mozilla/security/nss/lib/ssl/ssl3con.c | 58 +++++++++++++
|
| - mozilla/security/nss/lib/ssl/ssl3ext.c | 104 ++++++++++++++++++++++++-
|
| - mozilla/security/nss/lib/ssl/ssl3prot.h | 3 +-
|
| - mozilla/security/nss/lib/ssl/sslerr.h | 2 +
|
| - mozilla/security/nss/lib/ssl/sslimpl.h | 21 +++++
|
| - mozilla/security/nss/lib/ssl/sslsock.c | 134 +++++++++++++++++++++++++++++++
|
| - mozilla/security/nss/lib/ssl/sslt.h | 3 +-
|
| - 9 files changed, 381 insertions(+), 3 deletions(-)
|
| -
|
| -diff --git a/mozilla/security/nss/lib/ssl/ssl.def b/mozilla/security/nss/lib/ssl/ssl.def
|
| -index d3f455c..6ea48c0 100644
|
| ---- a/mozilla/security/nss/lib/ssl/ssl.def
|
| -+++ b/mozilla/security/nss/lib/ssl/ssl.def
|
| -@@ -152,3 +152,11 @@ SSL_SNISocketConfigHook;
|
| - ;+ local:
|
| - ;+*;
|
| - ;+};
|
| -+;+NSS_CHROMIUM {
|
| -+;+ global:
|
| -+SSL_GetNextProto;
|
| -+SSL_SetNextProtoCallback;
|
| -+SSL_SetNextProtoNego;
|
| -+;+ local:
|
| -+;+*;
|
| -+;+};
|
| -diff --git a/mozilla/security/nss/lib/ssl/ssl.h b/mozilla/security/nss/lib/ssl/ssl.h
|
| -index 4a9e89d..f54eb09 100644
|
| ---- a/mozilla/security/nss/lib/ssl/ssl.h
|
| -+++ b/mozilla/security/nss/lib/ssl/ssl.h
|
| -@@ -153,6 +153,57 @@ SSL_IMPORT SECStatus SSL_OptionSetDefault(PRInt32 option, PRBool on);
|
| - SSL_IMPORT SECStatus SSL_OptionGetDefault(PRInt32 option, PRBool *on);
|
| - SSL_IMPORT SECStatus SSL_CertDBHandleSet(PRFileDesc *fd, CERTCertDBHandle *dbHandle);
|
| -
|
| -+/* SSLNextProtoCallback is called, during the handshake, when the server has
|
| -+ * sent a Next Protocol Negotiation extension. |protos| and |protosLen| define
|
| -+ * a buffer which contains the server's advertisement. This data is guaranteed
|
| -+ * to be well formed per the NPN spec. |protoOut| is a buffer provided by the
|
| -+ * caller, of length 255 (the maximum allowed by the protocol).
|
| -+ * On successful return, the protocol to be announced to the server will be in
|
| -+ * |protoOut| and its length in |*protoOutLen|. */
|
| -+typedef SECStatus (PR_CALLBACK *SSLNextProtoCallback)(
|
| -+ void *arg,
|
| -+ PRFileDesc *fd,
|
| -+ const unsigned char* protos,
|
| -+ unsigned int protosLen,
|
| -+ unsigned char* protoOut,
|
| -+ unsigned int* protoOutLen);
|
| -+
|
| -+/* SSL_SetNextProtoCallback sets a callback function to handle Next Protocol
|
| -+ * Negotiation. It causes a client to advertise NPN. */
|
| -+SSL_IMPORT SECStatus SSL_SetNextProtoCallback(PRFileDesc *fd,
|
| -+ SSLNextProtoCallback callback,
|
| -+ void *arg);
|
| -+
|
| -+/* SSL_SetNextProtoNego can be used as an alternative to
|
| -+ * SSL_SetNextProtoCallback. It also causes a client to advertise NPN and
|
| -+ * installs a default callback function which selects the first supported
|
| -+ * protocol in server-preference order. If no matching protocol is found it
|
| -+ * selects the first supported protocol.
|
| -+ *
|
| -+ * The supported protocols are specified in |data| in wire-format (8-bit
|
| -+ * length-prefixed). For example: "\010http/1.1\006spdy/2". */
|
| -+SSL_IMPORT SECStatus SSL_SetNextProtoNego(PRFileDesc *fd,
|
| -+ const unsigned char *data,
|
| -+ unsigned int length);
|
| -+/* SSL_GetNextProto can be used after a handshake on a socket where
|
| -+ * SSL_SetNextProtoNego was called to retrieve the result of the Next Protocol
|
| -+ * negotiation.
|
| -+ *
|
| -+ * state is set to one of the SSL_NEXT_PROTO_* constants. The negotiated
|
| -+ * protocol, if any, is written into buf, which must be at least buf_len bytes
|
| -+ * long. If the negotiated protocol is longer than this, it is truncated. The
|
| -+ * number of bytes copied is written into *length. */
|
| -+SSL_IMPORT SECStatus SSL_GetNextProto(PRFileDesc *fd,
|
| -+ int *state,
|
| -+ unsigned char *buf,
|
| -+ unsigned int *length,
|
| -+ unsigned int buf_len);
|
| -+
|
| -+/* TODO(wtc): it may be a good idea to define these as an enum type. */
|
| -+#define SSL_NEXT_PROTO_NO_SUPPORT 0 /* No peer support */
|
| -+#define SSL_NEXT_PROTO_NEGOTIATED 1 /* Mutual agreement */
|
| -+#define SSL_NEXT_PROTO_NO_OVERLAP 2 /* No protocol overlap found */
|
| -+
|
| - /*
|
| - ** Control ciphers that SSL uses. If on is non-zero then the named cipher
|
| - ** is enabled, otherwise it is disabled.
|
| -diff --git a/mozilla/security/nss/lib/ssl/ssl3con.c b/mozilla/security/nss/lib/ssl/ssl3con.c
|
| -index 8048913..d2d4f91 100644
|
| ---- a/mozilla/security/nss/lib/ssl/ssl3con.c
|
| -+++ b/mozilla/security/nss/lib/ssl/ssl3con.c
|
| -@@ -81,6 +81,7 @@ static SECStatus ssl3_InitState( sslSocket *ss);
|
| - static SECStatus ssl3_SendCertificate( sslSocket *ss);
|
| - static SECStatus ssl3_SendEmptyCertificate( sslSocket *ss);
|
| - static SECStatus ssl3_SendCertificateRequest(sslSocket *ss);
|
| -+static SECStatus ssl3_SendNextProto( sslSocket *ss);
|
| - static SECStatus ssl3_SendFinished( sslSocket *ss, PRInt32 flags);
|
| - static SECStatus ssl3_SendServerHello( sslSocket *ss);
|
| - static SECStatus ssl3_SendServerHelloDone( sslSocket *ss);
|
| -@@ -5742,6 +5743,16 @@ ssl3_HandleServerHelloDone(sslSocket *ss)
|
| - if (rv != SECSuccess) {
|
| - goto loser; /* err code was set. */
|
| - }
|
| -+
|
| -+ /* We don't send NPN in a renegotiation as it's explicitly disallowed by
|
| -+ * the spec. */
|
| -+ if (!ss->firstHsDone) {
|
| -+ rv = ssl3_SendNextProto(ss);
|
| -+ if (rv != SECSuccess) {
|
| -+ goto loser; /* err code was set. */
|
| -+ }
|
| -+ }
|
| -+
|
| - rv = ssl3_SendFinished(ss, 0);
|
| - if (rv != SECSuccess) {
|
| - goto loser; /* err code was set. */
|
| -@@ -8169,6 +8180,40 @@ ssl3_ComputeTLSFinished(ssl3CipherSpec *spec,
|
| - }
|
| -
|
| - /* called from ssl3_HandleServerHelloDone
|
| -+ */
|
| -+static SECStatus
|
| -+ssl3_SendNextProto(sslSocket *ss)
|
| -+{
|
| -+ SECStatus rv;
|
| -+ int padding_len;
|
| -+ static const unsigned char padding[32] = {0};
|
| -+
|
| -+ if (ss->ssl3.nextProto.len == 0)
|
| -+ return SECSuccess;
|
| -+
|
| -+ PORT_Assert( ss->opt.noLocks || ssl_HaveXmitBufLock(ss));
|
| -+ PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss));
|
| -+
|
| -+ padding_len = 32 - ((ss->ssl3.nextProto.len + 2) % 32);
|
| -+
|
| -+ rv = ssl3_AppendHandshakeHeader(ss, next_proto, ss->ssl3.nextProto.len +
|
| -+ 2 + padding_len);
|
| -+ if (rv != SECSuccess) {
|
| -+ return rv; /* error code set by AppendHandshakeHeader */
|
| -+ }
|
| -+ rv = ssl3_AppendHandshakeVariable(ss, ss->ssl3.nextProto.data,
|
| -+ ss->ssl3.nextProto.len, 1);
|
| -+ if (rv != SECSuccess) {
|
| -+ return rv; /* error code set by AppendHandshake */
|
| -+ }
|
| -+ rv = ssl3_AppendHandshakeVariable(ss, padding, padding_len, 1);
|
| -+ if (rv != SECSuccess) {
|
| -+ return rv; /* error code set by AppendHandshake */
|
| -+ }
|
| -+ return rv;
|
| -+}
|
| -+
|
| -+/* called from ssl3_HandleServerHelloDone
|
| - * ssl3_HandleClientHello
|
| - * ssl3_HandleFinished
|
| - */
|
| -@@ -8421,6 +8466,14 @@ ssl3_HandleFinished(sslSocket *ss, SSL3Opaque *b, PRUint32 length,
|
| - if (doStepUp || ss->writerThread == PR_GetCurrentThread()) {
|
| - flags = ssl_SEND_FLAG_FORCE_INTO_BUFFER;
|
| - }
|
| -+
|
| -+ if (!isServer && !ss->firstHsDone) {
|
| -+ rv = ssl3_SendNextProto(ss);
|
| -+ if (rv != SECSuccess) {
|
| -+ goto xmit_loser; /* err code was set. */
|
| -+ }
|
| -+ }
|
| -+
|
| - rv = ssl3_SendFinished(ss, flags);
|
| - if (rv != SECSuccess) {
|
| - goto xmit_loser; /* err is set. */
|
| -@@ -9488,6 +9541,11 @@ ssl3_DestroySSL3Info(sslSocket *ss)
|
| - ssl3_DestroyCipherSpec(&ss->ssl3.specs[1], PR_TRUE/*freeSrvName*/);
|
| -
|
| - ss->ssl3.initialized = PR_FALSE;
|
| -+
|
| -+ if (ss->ssl3.nextProto.data) {
|
| -+ PORT_Free(ss->ssl3.nextProto.data);
|
| -+ ss->ssl3.nextProto.data = NULL;
|
| -+ }
|
| - }
|
| -
|
| - /* End of ssl3con.c */
|
| -diff --git a/mozilla/security/nss/lib/ssl/ssl3ext.c b/mozilla/security/nss/lib/ssl/ssl3ext.c
|
| -index becbfe9..711cad0 100644
|
| ---- a/mozilla/security/nss/lib/ssl/ssl3ext.c
|
| -+++ b/mozilla/security/nss/lib/ssl/ssl3ext.c
|
| -@@ -235,6 +235,7 @@ static const ssl3HelloExtensionHandler clientHelloHandlers[] = {
|
| - #endif
|
| - { ssl_session_ticket_xtn, &ssl3_ServerHandleSessionTicketXtn },
|
| - { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
|
| -+ { ssl_next_proto_neg_xtn, &ssl3_ServerHandleNextProtoNegoXtn },
|
| - { -1, NULL }
|
| - };
|
| -
|
| -@@ -245,6 +246,7 @@ static const ssl3HelloExtensionHandler serverHelloHandlersTLS[] = {
|
| - /* TODO: add a handler for ssl_ec_point_formats_xtn */
|
| - { ssl_session_ticket_xtn, &ssl3_ClientHandleSessionTicketXtn },
|
| - { ssl_renegotiation_info_xtn, &ssl3_HandleRenegotiationInfoXtn },
|
| -+ { ssl_next_proto_neg_xtn, &ssl3_ClientHandleNextProtoNegoXtn },
|
| - { -1, NULL }
|
| - };
|
| -
|
| -@@ -267,7 +269,8 @@ ssl3HelloExtensionSender clientHelloSendersTLS[SSL_MAX_EXTENSIONS] = {
|
| - { ssl_elliptic_curves_xtn, &ssl3_SendSupportedCurvesXtn },
|
| - { ssl_ec_point_formats_xtn, &ssl3_SendSupportedPointFormatsXtn },
|
| - #endif
|
| -- { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn }
|
| -+ { ssl_session_ticket_xtn, &ssl3_SendSessionTicketXtn },
|
| -+ { ssl_next_proto_neg_xtn, &ssl3_ClientSendNextProtoNegoXtn }
|
| - /* any extra entries will appear as { 0, NULL } */
|
| - };
|
| -
|
| -@@ -534,6 +537,105 @@ ssl3_SendSessionTicketXtn(
|
| - return -1;
|
| - }
|
| -
|
| -+/* handle an incoming Next Protocol Negotiation extension. */
|
| -+SECStatus
|
| -+ssl3_ServerHandleNextProtoNegoXtn(sslSocket * ss, PRUint16 ex_type, SECItem *data)
|
| -+{
|
| -+ if (data->len != 0) {
|
| -+ /* Clients MUST send an empty NPN extension, if any. */
|
| -+ return SECFailure;
|
| -+ }
|
| -+
|
| -+ return SECSuccess;
|
| -+}
|
| -+
|
| -+/* ssl3_ValidateNextProtoNego checks that the given block of data is valid: none
|
| -+ * of the lengths may be 0 and the sum of the lengths must equal the length of
|
| -+ * the block. */
|
| -+SECStatus
|
| -+ssl3_ValidateNextProtoNego(const unsigned char* data, unsigned short length)
|
| -+{
|
| -+ unsigned int offset = 0;
|
| -+
|
| -+ while (offset < length) {
|
| -+ if (data[offset] == 0) {
|
| -+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
|
| -+ return SECFailure;
|
| -+ }
|
| -+ offset += (unsigned int)data[offset] + 1;
|
| -+ }
|
| -+
|
| -+ if (offset > length) {
|
| -+ PORT_SetError(SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID);
|
| -+ return SECFailure;
|
| -+ }
|
| -+
|
| -+ return SECSuccess;
|
| -+}
|
| -+
|
| -+SECStatus
|
| -+ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss, PRUint16 ex_type,
|
| -+ SECItem *data)
|
| -+{
|
| -+ SECStatus rv;
|
| -+ unsigned char result[255];
|
| -+ unsigned int result_len;
|
| -+
|
| -+ rv = ssl3_ValidateNextProtoNego(data->data, data->len);
|
| -+ if (rv != SECSuccess)
|
| -+ return rv;
|
| -+
|
| -+ rv = ss->nextProtoCallback(ss->nextProtoArg, ss->fd,
|
| -+ data->data, data->len,
|
| -+ result, &result_len);
|
| -+ if (rv != SECSuccess)
|
| -+ return rv;
|
| -+ /* If the callback wrote more than allowed to |result| it has corrupted our
|
| -+ * stack. */
|
| -+ PORT_Assert(result_len <= sizeof(result));
|
| -+
|
| -+ if (ss->ssl3.nextProto.data)
|
| -+ PORT_Free(ss->ssl3.nextProto.data);
|
| -+ ss->ssl3.nextProto.data = PORT_Alloc(result_len);
|
| -+ PORT_Memcpy(ss->ssl3.nextProto.data, result, result_len);
|
| -+ ss->ssl3.nextProto.len = result_len;
|
| -+ return SECSuccess;
|
| -+}
|
| -+
|
| -+PRInt32
|
| -+ssl3_ClientSendNextProtoNegoXtn(sslSocket * ss,
|
| -+ PRBool append,
|
| -+ PRUint32 maxBytes)
|
| -+{
|
| -+ PRInt32 extension_length;
|
| -+
|
| -+ /* Renegotiations do not send this extension. */
|
| -+ if (!ss->nextProtoCallback || ss->firstHsDone) {
|
| -+ return 0;
|
| -+ }
|
| -+
|
| -+ extension_length = 4;
|
| -+
|
| -+ if (append && maxBytes >= extension_length) {
|
| -+ SECStatus rv;
|
| -+ rv = ssl3_AppendHandshakeNumber(ss, ssl_next_proto_neg_xtn, 2);
|
| -+ if (rv != SECSuccess)
|
| -+ goto loser;
|
| -+ rv = ssl3_AppendHandshakeNumber(ss, 0, 2);
|
| -+ if (rv != SECSuccess)
|
| -+ goto loser;
|
| -+ ss->xtnData.advertised[ss->xtnData.numAdvertised++] =
|
| -+ ssl_next_proto_neg_xtn;
|
| -+ } else if (maxBytes < extension_length) {
|
| -+ return 0;
|
| -+ }
|
| -+
|
| -+ return extension_length;
|
| -+
|
| -+ loser:
|
| -+ return -1;
|
| -+}
|
| -+
|
| - /*
|
| - * NewSessionTicket
|
| - * Called from ssl3_HandleFinished
|
| -diff --git a/mozilla/security/nss/lib/ssl/ssl3prot.h b/mozilla/security/nss/lib/ssl/ssl3prot.h
|
| -index 4702fcc..f3c950e 100644
|
| ---- a/mozilla/security/nss/lib/ssl/ssl3prot.h
|
| -+++ b/mozilla/security/nss/lib/ssl/ssl3prot.h
|
| -@@ -157,7 +157,8 @@ typedef enum {
|
| - server_hello_done = 14,
|
| - certificate_verify = 15,
|
| - client_key_exchange = 16,
|
| -- finished = 20
|
| -+ finished = 20,
|
| -+ next_proto = 67
|
| - } SSL3HandshakeType;
|
| -
|
| - typedef struct {
|
| -diff --git a/mozilla/security/nss/lib/ssl/sslerr.h b/mozilla/security/nss/lib/ssl/sslerr.h
|
| -index a2f6524..c76ffa9 100644
|
| ---- a/mozilla/security/nss/lib/ssl/sslerr.h
|
| -+++ b/mozilla/security/nss/lib/ssl/sslerr.h
|
| -@@ -203,6 +203,8 @@ SSL_ERROR_RX_UNEXPECTED_UNCOMPRESSED_RECORD = (SSL_ERROR_BASE + 114),
|
| -
|
| - SSL_ERROR_WEAK_SERVER_EPHEMERAL_DH_KEY = (SSL_ERROR_BASE + 115),
|
| -
|
| -+SSL_ERROR_NEXT_PROTOCOL_DATA_INVALID = (SSL_ERROR_BASE + 117),
|
| -+
|
| - SSL_ERROR_END_OF_LIST /* let the c compiler determine the value of this. */
|
| - } SSLErrorCodes;
|
| - #endif /* NO_SECURITY_ERROR_ENUM */
|
| -diff --git a/mozilla/security/nss/lib/ssl/sslimpl.h b/mozilla/security/nss/lib/ssl/sslimpl.h
|
| -index 9af471d..199c573 100644
|
| ---- a/mozilla/security/nss/lib/ssl/sslimpl.h
|
| -+++ b/mozilla/security/nss/lib/ssl/sslimpl.h
|
| -@@ -313,6 +313,10 @@ typedef struct {
|
| - #endif /* NSS_ENABLE_ECC */
|
| -
|
| - typedef struct sslOptionsStr {
|
| -+ /* If SSL_SetNextProtoNego has been called, then this contains the
|
| -+ * list of supported protocols. */
|
| -+ SECItem nextProtoNego;
|
| -+
|
| - unsigned int useSecurity : 1; /* 1 */
|
| - unsigned int useSocks : 1; /* 2 */
|
| - unsigned int requestCertificate : 1; /* 3 */
|
| -@@ -827,6 +831,13 @@ struct ssl3StateStr {
|
| - PRBool initialized;
|
| - SSL3HandshakeState hs;
|
| - ssl3CipherSpec specs[2]; /* one is current, one is pending. */
|
| -+
|
| -+ /* In a client: if the server supports Next Protocol Negotiation, then
|
| -+ * this is the protocol that was negotiated.
|
| -+ *
|
| -+ * If the data pointer is non-NULL, then it is malloced data. */
|
| -+ SECItem nextProto;
|
| -+ int nextProtoState; /* See NEXT_PROTO_* defines */
|
| - };
|
| -
|
| - typedef struct {
|
| -@@ -1058,6 +1069,8 @@ const unsigned char * preferredCipher;
|
| - SSLHandshakeCallback handshakeCallback;
|
| - void *handshakeCallbackData;
|
| - void *pkcs11PinArg;
|
| -+ SSLNextProtoCallback nextProtoCallback;
|
| -+ void *nextProtoArg;
|
| -
|
| - PRIntervalTime rTimeout; /* timeout for NSPR I/O */
|
| - PRIntervalTime wTimeout; /* timeout for NSPR I/O */
|
| -@@ -1494,8 +1507,12 @@ extern SECStatus ssl3_HandleSupportedPointFormatsXtn(sslSocket * ss,
|
| - PRUint16 ex_type, SECItem *data);
|
| - extern SECStatus ssl3_ClientHandleSessionTicketXtn(sslSocket *ss,
|
| - PRUint16 ex_type, SECItem *data);
|
| -+extern SECStatus ssl3_ClientHandleNextProtoNegoXtn(sslSocket *ss,
|
| -+ PRUint16 ex_type, SECItem *data);
|
| - extern SECStatus ssl3_ServerHandleSessionTicketXtn(sslSocket *ss,
|
| - PRUint16 ex_type, SECItem *data);
|
| -+extern SECStatus ssl3_ServerHandleNextProtoNegoXtn(sslSocket *ss,
|
| -+ PRUint16 ex_type, SECItem *data);
|
| -
|
| - /* ClientHello and ServerHello extension senders.
|
| - * Note that not all extension senders are exposed here; only those that
|
| -@@ -1526,6 +1543,10 @@ extern PRInt32 ssl3_SendSupportedCurvesXtn(sslSocket *ss,
|
| - extern PRInt32 ssl3_SendSupportedPointFormatsXtn(sslSocket *ss,
|
| - PRBool append, PRUint32 maxBytes);
|
| - #endif
|
| -+extern PRInt32 ssl3_ClientSendNextProtoNegoXtn(sslSocket *ss, PRBool append,
|
| -+ PRUint32 maxBytes);
|
| -+extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data,
|
| -+ unsigned short length);
|
| -
|
| - /* call the registered extension handlers. */
|
| - extern SECStatus ssl3_HandleHelloExtensions(sslSocket *ss,
|
| -diff --git a/mozilla/security/nss/lib/ssl/sslsock.c b/mozilla/security/nss/lib/ssl/sslsock.c
|
| -index bc770a1..829103b 100644
|
| ---- a/mozilla/security/nss/lib/ssl/sslsock.c
|
| -+++ b/mozilla/security/nss/lib/ssl/sslsock.c
|
| -@@ -163,6 +163,7 @@ static const sslSocketOps ssl_secure_ops = { /* SSL. */
|
| - ** default settings for socket enables
|
| - */
|
| - static sslOptions ssl_defaults = {
|
| -+ { siBuffer, NULL, 0 }, /* nextProtoNego */
|
| - PR_TRUE, /* useSecurity */
|
| - PR_FALSE, /* useSocks */
|
| - PR_FALSE, /* requestCertificate */
|
| -@@ -438,6 +439,10 @@ ssl_DestroySocketContents(sslSocket *ss)
|
| - ssl3_FreeKeyPair(ss->ephemeralECDHKeyPair);
|
| - ss->ephemeralECDHKeyPair = NULL;
|
| - }
|
| -+ if (ss->opt.nextProtoNego.data) {
|
| -+ PORT_Free(ss->opt.nextProtoNego.data);
|
| -+ ss->opt.nextProtoNego.data = NULL;
|
| -+ }
|
| - PORT_Assert(!ss->xtnData.sniNameArr);
|
| - if (ss->xtnData.sniNameArr) {
|
| - PORT_Free(ss->xtnData.sniNameArr);
|
| -@@ -1266,6 +1271,135 @@ SSL_ImportFD(PRFileDesc *model, PRFileDesc *fd)
|
| - return fd;
|
| - }
|
| -
|
| -+SECStatus
|
| -+SSL_SetNextProtoCallback(PRFileDesc *fd,
|
| -+ SSLNextProtoCallback callback,
|
| -+ void *arg) {
|
| -+ sslSocket *ss = ssl_FindSocket(fd);
|
| -+
|
| -+ if (!ss) {
|
| -+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego", SSL_GETPID(),
|
| -+ fd));
|
| -+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
| -+ return SECFailure;
|
| -+ }
|
| -+
|
| -+ ssl_GetSSL3HandshakeLock(ss);
|
| -+ ss->nextProtoCallback = callback;
|
| -+ ss->nextProtoArg = arg;
|
| -+ ssl_ReleaseSSL3HandshakeLock(ss);
|
| -+ return SECSuccess;
|
| -+}
|
| -+
|
| -+/* NextProtoStandardCallback is set as an NPN callback for the case when the
|
| -+ * user of the sockets wants the standard selection algorithm. */
|
| -+static SECStatus
|
| -+NextProtoStandardCallback(void *arg,
|
| -+ PRFileDesc *fd,
|
| -+ const unsigned char *protos,
|
| -+ unsigned int protos_len,
|
| -+ unsigned char *protoOut,
|
| -+ unsigned int *protoOutLen)
|
| -+{
|
| -+ unsigned int i, j;
|
| -+ const unsigned char *result;
|
| -+
|
| -+ sslSocket *ss = ssl_FindSocket(fd);
|
| -+ PORT_Assert(ss);
|
| -+
|
| -+ if (protos_len == 0) {
|
| -+ /* The server supports the extension, but doesn't have any protocols
|
| -+ * configured. In this case we request our favoured protocol. */
|
| -+ goto pick_first;
|
| -+ }
|
| -+
|
| -+ /* For each protocol in server preference, see if we support it. */
|
| -+ for (i = 0; i < protos_len; ) {
|
| -+ for (j = 0; j < ss->opt.nextProtoNego.len; ) {
|
| -+ if (protos[i] == ss->opt.nextProtoNego.data[j] &&
|
| -+ memcmp(&protos[i+1], &ss->opt.nextProtoNego.data[j+1],
|
| -+ protos[i]) == 0) {
|
| -+ /* We found a match. */
|
| -+ ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NEGOTIATED;
|
| -+ result = &protos[i];
|
| -+ goto found;
|
| -+ }
|
| -+ j += (unsigned int)ss->opt.nextProtoNego.data[j] + 1;
|
| -+ }
|
| -+ i += (unsigned int)protos[i] + 1;
|
| -+ }
|
| -+
|
| -+pick_first:
|
| -+ ss->ssl3.nextProtoState = SSL_NEXT_PROTO_NO_OVERLAP;
|
| -+ result = ss->opt.nextProtoNego.data;
|
| -+
|
| -+found:
|
| -+ memcpy(protoOut, result + 1, result[0]);
|
| -+ *protoOutLen = result[0];
|
| -+ return SECSuccess;
|
| -+}
|
| -+
|
| -+SECStatus
|
| -+SSL_SetNextProtoNego(PRFileDesc *fd, const unsigned char *data,
|
| -+ unsigned int length)
|
| -+{
|
| -+ SECStatus rv;
|
| -+
|
| -+ sslSocket *ss = ssl_FindSocket(fd);
|
| -+
|
| -+ if (!ss) {
|
| -+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetNextProtoNego",
|
| -+ SSL_GETPID(), fd));
|
| -+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
| -+ return SECFailure;
|
| -+ }
|
| -+
|
| -+ if (ssl3_ValidateNextProtoNego(data, length) != SECSuccess)
|
| -+ return SECFailure;
|
| -+
|
| -+ ssl_GetSSL3HandshakeLock(ss);
|
| -+ if (ss->opt.nextProtoNego.data)
|
| -+ PORT_Free(ss->opt.nextProtoNego.data);
|
| -+ ss->opt.nextProtoNego.data = PORT_Alloc(length);
|
| -+ if (!ss->opt.nextProtoNego.data) {
|
| -+ ssl_ReleaseSSL3HandshakeLock(ss);
|
| -+ return SECFailure;
|
| -+ }
|
| -+ memcpy(ss->opt.nextProtoNego.data, data, length);
|
| -+ ss->opt.nextProtoNego.len = length;
|
| -+ ss->opt.nextProtoNego.type = siBuffer;
|
| -+ ssl_ReleaseSSL3HandshakeLock(ss);
|
| -+
|
| -+ return SSL_SetNextProtoCallback(fd, NextProtoStandardCallback, NULL);
|
| -+}
|
| -+
|
| -+SECStatus
|
| -+SSL_GetNextProto(PRFileDesc *fd, int *state, unsigned char *buf,
|
| -+ unsigned int *length, unsigned int buf_len)
|
| -+{
|
| -+ sslSocket *ss = ssl_FindSocket(fd);
|
| -+
|
| -+ if (!ss) {
|
| -+ SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNextProto", SSL_GETPID(),
|
| -+ fd));
|
| -+ return SECFailure;
|
| -+ }
|
| -+
|
| -+ *state = ss->ssl3.nextProtoState;
|
| -+
|
| -+ if (ss->ssl3.nextProtoState != SSL_NEXT_PROTO_NO_SUPPORT &&
|
| -+ ss->ssl3.nextProto.data) {
|
| -+ *length = ss->ssl3.nextProto.len;
|
| -+ if (*length > buf_len)
|
| -+ *length = buf_len;
|
| -+ PORT_Memcpy(buf, ss->ssl3.nextProto.data, *length);
|
| -+ } else {
|
| -+ *length = 0;
|
| -+ }
|
| -+
|
| -+ return SECSuccess;
|
| -+}
|
| -+
|
| - PRFileDesc *
|
| - SSL_ReconfigFD(PRFileDesc *model, PRFileDesc *fd)
|
| - {
|
| -diff --git a/mozilla/security/nss/lib/ssl/sslt.h b/mozilla/security/nss/lib/ssl/sslt.h
|
| -index c7d4553..f6e0b62 100644
|
| ---- a/mozilla/security/nss/lib/ssl/sslt.h
|
| -+++ b/mozilla/security/nss/lib/ssl/sslt.h
|
| -@@ -203,9 +203,10 @@ typedef enum {
|
| - ssl_ec_point_formats_xtn = 11,
|
| - #endif
|
| - ssl_session_ticket_xtn = 35,
|
| -+ ssl_next_proto_neg_xtn = 13172,
|
| - ssl_renegotiation_info_xtn = 0xff01 /* experimental number */
|
| - } SSLExtensionType;
|
| -
|
| --#define SSL_MAX_EXTENSIONS 5
|
| -+#define SSL_MAX_EXTENSIONS 6
|
| -
|
| - #endif /* __sslt_h_ */
|
|
|