Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / net / third_party / nss / patches / tlsunique.patch
blobf2b2c50c05a7af274bea5d741a64862f5ea17ac4
1 diff --git a/ssl/ssl.h b/ssl/ssl.h
2 index 716537d..80717db 100644
3 --- a/ssl/ssl.h
4 +++ b/ssl/ssl.h
5 @@ -292,6 +292,27 @@ SSL_IMPORT SECStatus SSL_CipherPrefGetDefault(PRInt32 cipher, PRBool *enabled);
6 SSL_IMPORT SECStatus SSL_CipherPolicySet(PRInt32 cipher, PRInt32 policy);
7 SSL_IMPORT SECStatus SSL_CipherPolicyGet(PRInt32 cipher, PRInt32 *policy);
9 +/* SSLChannelBindingType enumerates the types of supported channel binding
10 + * values. See RFC 5929. */
11 +typedef enum SSLChannelBindingType {
12 + SSL_CHANNEL_BINDING_TLS_UNIQUE = 1,
13 +} SSLChannelBindingType;
15 +/* SSL_GetChannelBinding copies the requested channel binding value, as defined
16 + * in RFC 5929, into |out|. The full length of the binding value is written
17 + * into |*outLen|.
18 + *
19 + * At most |outLenMax| bytes of data are copied. If |outLenMax| is
20 + * insufficient then the function returns SECFailure and sets the error to
21 + * SEC_ERROR_OUTPUT_LEN, but |*outLen| is still set.
22 + *
23 + * This call will fail if made during a renegotiation. */
24 +SSL_IMPORT SECStatus SSL_GetChannelBinding(PRFileDesc *fd,
25 + SSLChannelBindingType binding_type,
26 + unsigned char *out,
27 + unsigned int *outLen,
28 + unsigned int outLenMax);
30 /* SSL Version Range API
32 ** This API should be used to control SSL 3.0 & TLS support instead of the
33 diff --git a/ssl/ssl3con.c b/ssl/ssl3con.c
34 index c0e8e79..7c06815 100644
35 --- a/ssl/ssl3con.c
36 +++ b/ssl/ssl3con.c
37 @@ -12479,6 +12479,68 @@ ssl3_InitSocketPolicy(sslSocket *ss)
38 PORT_Memcpy(ss->cipherSuites, cipherSuites, sizeof cipherSuites);
41 +SECStatus
42 +ssl3_GetTLSUniqueChannelBinding(sslSocket *ss,
43 + unsigned char *out,
44 + unsigned int *outLen,
45 + unsigned int outLenMax) {
46 + PRBool isTLS;
47 + int index = 0;
48 + unsigned int len;
49 + SECStatus rv = SECFailure;
51 + *outLen = 0;
53 + ssl_GetSSL3HandshakeLock(ss);
55 + ssl_GetSpecReadLock(ss);
56 + isTLS = (PRBool)(ss->ssl3.cwSpec->version > SSL_LIBRARY_VERSION_3_0);
57 + ssl_ReleaseSpecReadLock(ss);
59 + /* The tls-unique channel binding is the first Finished structure in the
60 + * handshake. In the case of a resumption, that's the server's Finished.
61 + * Otherwise, it's the client's Finished. */
62 + len = ss->ssl3.hs.finishedBytes;
64 + /* Sending or receiving a Finished message will set finishedBytes to a
65 + * non-zero value. */
66 + if (len == 0) {
67 + PORT_SetError(SSL_ERROR_HANDSHAKE_NOT_COMPLETED);
68 + goto loser;
69 + }
71 + /* If we are in the middle of a renegotiation then the channel binding
72 + * value is poorly defined and depends on the direction that it will be
73 + * used on. Therefore we simply return an error in this case. */
74 + if (ss->firstHsDone && ss->ssl3.hs.ws != idle_handshake) {
75 + PORT_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED);
76 + goto loser;
77 + }
79 + /* If resuming, then we want the second Finished value in the array, which
80 + * is the server's */
81 + if (ss->ssl3.hs.isResuming)
82 + index = 1;
84 + *outLen = len;
85 + if (outLenMax < len) {
86 + PORT_SetError(SEC_ERROR_OUTPUT_LEN);
87 + goto loser;
88 + }
90 + if (isTLS) {
91 + memcpy(out, &ss->ssl3.hs.finishedMsgs.tFinished[index], len);
92 + } else {
93 + memcpy(out, &ss->ssl3.hs.finishedMsgs.sFinished[index], len);
94 + }
96 + rv = SECSuccess;
98 +loser:
99 + ssl_ReleaseSSL3HandshakeLock(ss);
100 + return rv;
103 /* ssl3_config_match_init must have already been called by
104 * the caller of this function.
106 diff --git a/ssl/sslimpl.h b/ssl/sslimpl.h
107 index e11860e..0ece0ed 100644
108 --- a/ssl/sslimpl.h
109 +++ b/ssl/sslimpl.h
110 @@ -1864,6 +1864,11 @@ extern PRBool ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
111 extern SECStatus ssl3_ValidateNextProtoNego(const unsigned char* data,
112 unsigned int length);
114 +extern SECStatus ssl3_GetTLSUniqueChannelBinding(sslSocket *ss,
115 + unsigned char *out,
116 + unsigned int *outLen,
117 + unsigned int outLenMax);
119 /* Construct a new NSPR socket for the app to use */
120 extern PRFileDesc *ssl_NewPRSocket(sslSocket *ss, PRFileDesc *fd);
121 extern void ssl_FreePRSocket(PRFileDesc *fd);
122 diff --git a/ssl/sslsock.c b/ssl/sslsock.c
123 index 042f24f..14ff328 100644
124 --- a/ssl/sslsock.c
125 +++ b/ssl/sslsock.c
126 @@ -1345,6 +1345,27 @@ NSS_SetFrancePolicy(void)
127 return NSS_SetDomesticPolicy();
130 +SECStatus
131 +SSL_GetChannelBinding(PRFileDesc *fd,
132 + SSLChannelBindingType binding_type,
133 + unsigned char *out,
134 + unsigned int *outLen,
135 + unsigned int outLenMax) {
136 + sslSocket *ss = ssl_FindSocket(fd);
138 + if (!ss) {
139 + SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetChannelBinding",
140 + SSL_GETPID(), fd));
141 + return SECFailure;
144 + if (binding_type != SSL_CHANNEL_BINDING_TLS_UNIQUE) {
145 + PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
146 + return SECFailure;
149 + return ssl3_GetTLSUniqueChannelBinding(ss, out, outLen, outLenMax);
153 /* LOCKS ??? XXX */