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	2013-07-31 12:44:31.987362835 -0700
      3 +++ b/nss/lib/ssl/ssl3con.c	2013-07-31 12:44:50.987642452 -0700
      4 @@ -6756,6 +6756,85 @@ done:
      5      return rv;
      6  }
      7  
      8 +/*
      9 + * attempt to restart the handshake after asynchronously handling
     10 + * a request for the client's certificate.
     11 + *
     12 + * inputs:
     13 + *	cert	Client cert chosen by application.
     14 + *		Note: ssl takes this reference, and does not bump the
     15 + *		reference count.  The caller should drop its reference
     16 + *		without calling CERT_DestroyCert after calling this function.
     17 + *
     18 + *	key	Private key associated with cert.  This function takes
     19 + *		ownership of the private key, so the caller should drop its
     20 + *		reference without destroying the private key after this
     21 + *		function returns.
     22 + *
     23 + *	certChain  DER-encoded certs, client cert and its signers.
     24 + *		Note: ssl takes this reference, and does not copy the chain.
     25 + *		The caller should drop its reference without destroying the
     26 + *		chain.  SSL will free the chain when it is done with it.
     27 + *
     28 + * Return value: XXX
     29 + *
     30 + * XXX This code only works on the initial handshake on a connection, XXX
     31 + *     It does not work on a subsequent handshake (redo).
     32 + *
     33 + * Caller holds 1stHandshakeLock.
     34 + */
     35 +SECStatus
     36 +ssl3_RestartHandshakeAfterCertReq(sslSocket *         ss,
     37 +				CERTCertificate *    cert,
     38 +				SECKEYPrivateKey *   key,
     39 +				CERTCertificateList *certChain)
     40 +{
     41 +    SECStatus        rv          = SECSuccess;
     42 +
     43 +    /* XXX This code only works on the initial handshake on a connection,
     44 +    ** XXX It does not work on a subsequent handshake (redo).
     45 +    */
     46 +    if (ss->handshake != 0) {
     47 +	ss->handshake              = ssl_GatherRecord1stHandshake;
     48 +	ss->ssl3.clientCertificate = cert;
     49 +	ss->ssl3.clientPrivateKey  = key;
     50 +	ss->ssl3.clientCertChain   = certChain;
     51 +        if (!cert || !key || !certChain) {
     52 +            /* we are missing the key, cert, or cert chain */
     53 +            if (ss->ssl3.clientCertificate) {
     54 +                CERT_DestroyCertificate(ss->ssl3.clientCertificate);
     55 +                ss->ssl3.clientCertificate = NULL;
     56 +            }
     57 +            if (ss->ssl3.clientPrivateKey) {
     58 +                SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
     59 +                ss->ssl3.clientPrivateKey = NULL;
     60 +            }
     61 +            if (ss->ssl3.clientCertChain != NULL) {
     62 +                CERT_DestroyCertificateList(ss->ssl3.clientCertChain);
     63 +                ss->ssl3.clientCertChain = NULL;
     64 +            }
     65 +            if (ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0) {
     66 +                ss->ssl3.sendEmptyCert = PR_TRUE;
     67 +            } else {
     68 +                (void)SSL3_SendAlert(ss, alert_warning, no_certificate);
     69 +            }
     70 +	}
     71 +    } else {
     72 +	if (cert) {
     73 +	    CERT_DestroyCertificate(cert);
     74 +	}
     75 +	if (key) {
     76 +	    SECKEY_DestroyPrivateKey(key);
     77 +	}
     78 +	if (certChain) {
     79 +	    CERT_DestroyCertificateList(certChain);
     80 +	}
     81 +	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
     82 +	rv = SECFailure;
     83 +    }
     84 +    return rv;
     85 +}
     86 +
     87  PRBool
     88  ssl3_CanFalseStart(sslSocket *ss) {
     89      PRBool rv;
     90 diff -pu a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h
     91 --- a/nss/lib/ssl/ssl.h	2013-07-31 12:44:31.987362835 -0700
     92 +++ b/nss/lib/ssl/ssl.h	2013-07-31 12:44:50.987642452 -0700
     93 @@ -366,6 +366,11 @@ SSL_IMPORT SECStatus SSL_ForceHandshake(
     94  SSL_IMPORT SECStatus SSL_ForceHandshakeWithTimeout(PRFileDesc *fd,
     95                                                     PRIntervalTime timeout);
     96  
     97 +SSL_IMPORT SECStatus SSL_RestartHandshakeAfterCertReq(PRFileDesc *fd,
     98 +					    CERTCertificate *cert,
     99 +					    SECKEYPrivateKey *key,
    100 +					    CERTCertificateList *certChain);
    101 +
    102  /*
    103  ** Query security status of socket. *on is set to one if security is
    104  ** enabled. *keySize will contain the stream key size used. *issuer will
    105 diff -pu a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h
    106 --- a/nss/lib/ssl/sslimpl.h	2013-07-31 12:44:31.997362988 -0700
    107 +++ b/nss/lib/ssl/sslimpl.h	2013-07-31 12:44:50.987642452 -0700
    108 @@ -1513,16 +1513,17 @@ extern  SECStatus ssl3_MasterKeyDeriveBy
    109  /* These functions are called from secnav, even though they're "private". */
    110  
    111  extern int ssl2_SendErrorMessage(struct sslSocketStr *ss, int error);
    112 -extern int SSL_RestartHandshakeAfterCertReq(struct sslSocketStr *ss,
    113 -					    CERTCertificate *cert,
    114 -					    SECKEYPrivateKey *key,
    115 -					    CERTCertificateList *certChain);
    116  extern sslSocket *ssl_FindSocket(PRFileDesc *fd);
    117  extern void ssl_FreeSocket(struct sslSocketStr *ssl);
    118  extern SECStatus SSL3_SendAlert(sslSocket *ss, SSL3AlertLevel level,
    119  				SSL3AlertDescription desc);
    120  extern SECStatus ssl3_DecodeError(sslSocket *ss);
    121  
    122 +extern SECStatus ssl3_RestartHandshakeAfterCertReq(sslSocket *    ss,
    123 +					     CERTCertificate *    cert, 
    124 +					     SECKEYPrivateKey *   key,
    125 +					     CERTCertificateList *certChain);
    126 +
    127  extern SECStatus ssl3_AuthCertificateComplete(sslSocket *ss, PRErrorCode error);
    128  
    129  /*
    130 diff -pu a/nss/lib/ssl/sslsecur.c b/nss/lib/ssl/sslsecur.c
    131 --- a/nss/lib/ssl/sslsecur.c	2013-07-31 12:28:39.283413269 -0700
    132 +++ b/nss/lib/ssl/sslsecur.c	2013-07-31 12:44:50.987642452 -0700
    133 @@ -1436,17 +1436,70 @@ SSL_CertDBHandleSet(PRFileDesc *fd, CERT
    134      return SECSuccess;
    135  }
    136  
    137 -/* DO NOT USE. This function was exported in ssl.def with the wrong signature;
    138 - * this implementation exists to maintain link-time compatibility.
    139 +/*
    140 + * attempt to restart the handshake after asynchronously handling
    141 + * a request for the client's certificate.
    142 + *
    143 + * inputs:  
    144 + *	cert	Client cert chosen by application.
    145 + *		Note: ssl takes this reference, and does not bump the 
    146 + *		reference count.  The caller should drop its reference
    147 + *		without calling CERT_DestroyCertificate after calling this
    148 + *		function.
    149 + *
    150 + *	key	Private key associated with cert.  This function takes
    151 + *		ownership of the private key, so the caller should drop its
    152 + *		reference without destroying the private key after this
    153 + *		function returns.
    154 + *
    155 + *	certChain  Chain of signers for cert.  
    156 + *		Note: ssl takes this reference, and does not copy the chain.
    157 + *		The caller should drop its reference without destroying the 
    158 + *		chain.  SSL will free the chain when it is done with it.
    159 + *
    160 + * Return value: XXX
    161 + *
    162 + * XXX This code only works on the initial handshake on a connection, XXX
    163 + *     It does not work on a subsequent handshake (redo).
    164   */
    165 -int
    166 -SSL_RestartHandshakeAfterCertReq(sslSocket *         ss,
    167 +SECStatus
    168 +SSL_RestartHandshakeAfterCertReq(PRFileDesc *        fd,
    169  				CERTCertificate *    cert, 
    170  				SECKEYPrivateKey *   key,
    171  				CERTCertificateList *certChain)
    172  {
    173 -    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    174 -    return -1;
    175 +    sslSocket *   ss = ssl_FindSocket(fd);
    176 +    SECStatus     ret;
    177 +
    178 +    if (!ss) {
    179 +	SSL_DBG(("%d: SSL[%d]: bad socket in SSL_RestartHandshakeAfterCertReq",
    180 +		 SSL_GETPID(), fd));
    181 +	if (cert) {
    182 +	    CERT_DestroyCertificate(cert);
    183 +	}
    184 +	if (key) {
    185 +	    SECKEY_DestroyPrivateKey(key);
    186 +	}
    187 +	if (certChain) {
    188 +	    CERT_DestroyCertificateList(certChain);
    189 +	}
    190 +	return SECFailure;
    191 +    }
    192 +
    193 +    ssl_Get1stHandshakeLock(ss);   /************************************/
    194 +
    195 +    if (ss->version >= SSL_LIBRARY_VERSION_3_0) {
    196 +	ret = ssl3_RestartHandshakeAfterCertReq(ss, cert, key, certChain);
    197 +    } else {
    198 +	if (certChain != NULL) {
    199 +	    CERT_DestroyCertificateList(certChain);
    200 +	}
    201 +	PORT_SetError(SSL_ERROR_FEATURE_NOT_SUPPORTED_FOR_SSL2);
    202 +	ret = SECFailure;
    203 +    }
    204 +
    205 +    ssl_Release1stHandshakeLock(ss);  /************************************/
    206 +    return ret;
    207  }
    208  
    209  /* DO NOT USE. This function was exported in ssl.def with the wrong signature;
    210