| OLD | NEW |
| (Empty) |
| 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:55:01.518095989 -0800 | |
| 3 +++ b/nss/lib/ssl/ssl3con.c 2014-01-17 17:55:19.158389328 -0800 | |
| 4 @@ -7199,6 +7199,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 static SECStatus | |
| 88 ssl3_CheckFalseStart(sslSocket *ss) | |
| 89 { | |
| 90 diff -pu a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h | |
| 91 --- a/nss/lib/ssl/ssl.h 2014-01-17 17:55:01.538096321 -0800 | |
| 92 +++ b/nss/lib/ssl/ssl.h 2014-01-17 17:55:19.158389328 -0800 | |
| 93 @@ -399,6 +399,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 2014-01-17 17:55:01.538096321 -0800 | |
| 107 +++ b/nss/lib/ssl/sslimpl.h 2014-01-17 17:55:19.158389328 -0800 | |
| 108 @@ -1588,16 +1588,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 2014-01-17 17:49:26.072517368 -0800 | |
| 132 +++ b/nss/lib/ssl/sslsecur.c 2014-01-17 17:55:19.158389328 -0800 | |
| 133 @@ -1518,17 +1518,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; | |
| OLD | NEW |