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