| Index: net/third_party/nss/ssl/ssl3con.c
|
| diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
|
| index 9343b2b4796ea60c683ec1c465cac34488034f48..d3d2727725a283f82e307e0d3a50c6ae934952eb 100644
|
| --- a/net/third_party/nss/ssl/ssl3con.c
|
| +++ b/net/third_party/nss/ssl/ssl3con.c
|
| @@ -2011,6 +2011,12 @@ ssl3_ComputeRecordMAC(
|
|
|
| static PRBool
|
| ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
|
| +#ifdef NSS_PLATFORM_CLIENT_AUTH
|
| + if (!sid || !sid->u.ssl3.clPlatformAuthValid) {
|
| + return PR_TRUE;
|
| + }
|
| + return ssl_PlatformAuthTokenPresent(&sid->u.ssl3.clPlatformAuthInfo);
|
| +#else
|
| PK11SlotInfo *slot = NULL;
|
| PRBool isPresent = PR_TRUE;
|
|
|
| @@ -2034,6 +2040,7 @@ ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
|
| PK11_FreeSlot(slot);
|
| }
|
| return isPresent;
|
| +#endif /* NSS_PLATFORM_CLIENT_AUTH */
|
| }
|
|
|
| SECStatus
|
| @@ -4827,6 +4834,20 @@ ssl3_SendCertificateVerify(sslSocket *ss)
|
| }
|
|
|
| isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
|
| +#ifdef NSS_PLATFORM_CLIENT_AUTH
|
| + rv = ssl3_PlatformSignHashes(&hashes, ss->ssl3.platformClientKey,
|
| + &buf, isTLS);
|
| + if (rv == SECSuccess) {
|
| + sslSessionID * sid = ss->sec.ci.sid;
|
| + ssl_GetPlatformAuthInfoForKey(ss->ssl3.platformClientKey,
|
| + &sid->u.ssl3.clPlatformAuthInfo);
|
| + sid->u.ssl3.clPlatformAuthValid = PR_TRUE;
|
| + }
|
| + if (ss->ssl3.hs.kea_def->exchKeyType == kt_rsa) {
|
| + ssl_FreePlatformKey(ss->ssl3.platformClientKey);
|
| + ss->ssl3.platformClientKey = (PlatformKey)NULL;
|
| + }
|
| +#else /* NSS_PLATFORM_CLIENT_AUTH */
|
| rv = ssl3_SignHashes(&hashes, ss->ssl3.clientPrivateKey, &buf, isTLS);
|
| if (rv == SECSuccess) {
|
| PK11SlotInfo * slot;
|
| @@ -4851,6 +4872,7 @@ ssl3_SendCertificateVerify(sslSocket *ss)
|
| SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
|
| ss->ssl3.clientPrivateKey = NULL;
|
| }
|
| +#endif /* NSS_PLATFORM_CLIENT_AUTH */
|
| if (rv != SECSuccess) {
|
| goto done; /* err code was set by ssl3_SignHashes */
|
| }
|
| @@ -5481,6 +5503,10 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
| SSL3AlertDescription desc = illegal_parameter;
|
| SECItem cert_types = {siBuffer, NULL, 0};
|
| CERTDistNames ca_list;
|
| +#ifdef NSS_PLATFORM_CLIENT_AUTH
|
| + CERTCertList * platform_cert_list = NULL;
|
| + CERTCertListNode * certNode = NULL;
|
| +#endif /* NSS_PLATFORM_CLIENT_AUTH */
|
|
|
| SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
|
| SSL_GETPID(), ss->fd));
|
| @@ -5507,6 +5533,12 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
| SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
|
| ss->ssl3.clientPrivateKey = NULL;
|
| }
|
| +#ifdef NSS_PLATFORM_CLIENT_AUTH
|
| + if (ss->ssl3.platformClientKey) {
|
| + ssl_FreePlatformKey(ss->ssl3.platformClientKey);
|
| + ss->ssl3.platformClientKey = (PlatformKey)NULL;
|
| + }
|
| +#endif /* NSS_PLATFORM_CLIENT_AUTH */
|
|
|
| isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
|
| rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length);
|
| @@ -5573,6 +5605,18 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
| desc = no_certificate;
|
| ss->ssl3.hs.ws = wait_hello_done;
|
|
|
| +#ifdef NSS_PLATFORM_CLIENT_AUTH
|
| + if (ss->getPlatformClientAuthData == NULL) {
|
| + rv = SECFailure; /* force it to send a no_certificate alert */
|
| + } else {
|
| + /* XXX Should pass cert_types in this call!! */
|
| + rv = (SECStatus)(*ss->getPlatformClientAuthData)(
|
| + ss->getPlatformClientAuthDataArg,
|
| + ss->fd, &ca_list,
|
| + &platform_cert_list,
|
| + (void**)&ss->ssl3.platformClientKey);
|
| + }
|
| +#else
|
| if (ss->getClientAuthData == NULL) {
|
| rv = SECFailure; /* force it to send a no_certificate alert */
|
| } else {
|
| @@ -5582,12 +5626,51 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
| &ss->ssl3.clientCertificate,
|
| &ss->ssl3.clientPrivateKey);
|
| }
|
| +#endif /* NSS_PLATFORM_CLIENT_AUTH */
|
| switch (rv) {
|
| case SECWouldBlock: /* getClientAuthData has put up a dialog box. */
|
| ssl_SetAlwaysBlock(ss);
|
| break; /* not an error */
|
|
|
| case SECSuccess:
|
| +#ifdef NSS_PLATFORM_CLIENT_AUTH
|
| + if (!platform_cert_list || CERT_LIST_EMPTY(platform_cert_list) ||
|
| + !ss->ssl3.platformClientKey) {
|
| + if (platform_cert_list) {
|
| + CERT_DestroyCertList(platform_cert_list);
|
| + platform_cert_list = NULL;
|
| + }
|
| + if (ss->ssl3.platformClientKey) {
|
| + ssl_FreePlatformKey(ss->ssl3.platformClientKey);
|
| + ss->ssl3.platformClientKey = (PlatformKey)NULL;
|
| + }
|
| + goto send_no_certificate;
|
| + }
|
| +
|
| + certNode = CERT_LIST_HEAD(platform_cert_list);
|
| + ss->ssl3.clientCertificate = CERT_DupCertificate(certNode->cert);
|
| +
|
| + /* Setting ssl3.clientCertChain non-NULL will cause
|
| + * ssl3_HandleServerHelloDone to call SendCertificate.
|
| + * Note: clientCertChain should include the EE cert as
|
| + * clientCertificate is ignored during the actual sending
|
| + */
|
| + ss->ssl3.clientCertChain =
|
| + hack_NewCertificateListFromCertList(platform_cert_list);
|
| + CERT_DestroyCertList(platform_cert_list);
|
| + platform_cert_list = NULL;
|
| + if (ss->ssl3.clientCertChain == NULL) {
|
| + if (ss->ssl3.clientCertificate != NULL) {
|
| + CERT_DestroyCertificate(ss->ssl3.clientCertificate);
|
| + ss->ssl3.clientCertificate = NULL;
|
| + }
|
| + if (ss->ssl3.platformClientKey) {
|
| + ssl_FreePlatformKey(ss->ssl3.platformClientKey);
|
| + ss->ssl3.platformClientKey = (PlatformKey)NULL;
|
| + }
|
| + goto send_no_certificate;
|
| + }
|
| +#else
|
| /* check what the callback function returned */
|
| if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
|
| /* we are missing either the key or cert */
|
| @@ -5620,6 +5703,7 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
|
| }
|
| goto send_no_certificate;
|
| }
|
| +#endif /* NSS_PLATFORM_CLIENT_AUTH */
|
| break; /* not an error */
|
|
|
| case SECFailure:
|
| @@ -5650,6 +5734,10 @@ loser:
|
| done:
|
| if (arena != NULL)
|
| PORT_FreeArena(arena, PR_FALSE);
|
| +#ifdef NSS_PLATFORM_CLIENT_AUTH
|
| + if (platform_cert_list)
|
| + CERT_DestroyCertList(platform_cert_list);
|
| +#endif
|
| return rv;
|
| }
|
|
|
| @@ -5758,6 +5846,16 @@ ssl3_HandleServerHelloDone(sslSocket *ss)
|
| goto loser; /* error code is set. */
|
| }
|
| } else
|
| +#ifdef NSS_PLATFORM_CLIENT_AUTH
|
| + if (ss->ssl3.clientCertChain != NULL &&
|
| + ss->ssl3.platformClientKey) {
|
| + send_verify = PR_TRUE;
|
| + rv = ssl3_SendCertificate(ss);
|
| + if (rv != SECSuccess) {
|
| + goto loser; /* error code is set. */
|
| + }
|
| + }
|
| +#else
|
| if (ss->ssl3.clientCertChain != NULL &&
|
| ss->ssl3.clientPrivateKey != NULL) {
|
| send_verify = PR_TRUE;
|
| @@ -5766,6 +5864,7 @@ ssl3_HandleServerHelloDone(sslSocket *ss)
|
| goto loser; /* error code is set. */
|
| }
|
| }
|
| +#endif /* NSS_PLATFORM_CLIENT_AUTH */
|
|
|
| rv = ssl3_SendClientKeyExchange(ss);
|
| if (rv != SECSuccess) {
|
| @@ -9626,6 +9725,10 @@ ssl3_DestroySSL3Info(sslSocket *ss)
|
|
|
| if (ss->ssl3.clientPrivateKey != NULL)
|
| SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
|
| +#ifdef NSS_PLATFORM_CLIENT_AUTH
|
| + if (ss->ssl3.platformClientKey)
|
| + ssl_FreePlatformKey(ss->ssl3.platformClientKey);
|
| +#endif /* NSS_PLATFORM_CLIENT_AUTH */
|
|
|
| if (ss->ssl3.peerCertArena != NULL)
|
| ssl3_CleanupPeerCerts(ss);
|
|
|