Home | History | Annotate | Download | only in patches
      1 diff -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   */
     73 diff -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
    104 diff -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);
    119 diff -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