diff options
-rw-r--r-- | net/third_party/nss/README.chromium | 6 | ||||
-rw-r--r-- | net/third_party/nss/patches/clientauth.patch | 703 | ||||
-rw-r--r-- | net/third_party/nss/patches/dheclientauth.patch | 98 |
3 files changed, 708 insertions, 99 deletions
diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium index 7dc9de0..d1fa694 100644 --- a/net/third_party/nss/README.chromium +++ b/net/third_party/nss/README.chromium @@ -45,10 +45,14 @@ Patches: * Add OCSP stapling support patches/ocspstapling.patch + * Add support for client auth with native crypto APIs on Mac and Windows + patches/clientauth.patch + ssl/sslplatf.c + * Don't send a client certificate when renegotiating if the peer does not request one. This only happened if the previous key exchange algorithm was non-RSA. - patches/dheclientauth.patch + patches/clientauth.patch https://bugzilla.mozilla.org/show_bug.cgi?id=616757 The ssl/bodge directory contains files taken from the NSS repo that we required diff --git a/net/third_party/nss/patches/clientauth.patch b/net/third_party/nss/patches/clientauth.patch new file mode 100644 index 0000000..5128566 --- /dev/null +++ b/net/third_party/nss/patches/clientauth.patch @@ -0,0 +1,703 @@ +Index: mozilla/security/nss/lib/ssl/ssl.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl.h,v +retrieving revision 1.38 +diff -p -u -8 -r1.38 ssl.h +--- mozilla/security/nss/lib/ssl/ssl.h 17 Feb 2010 02:29:07 -0000 1.38 ++++ mozilla/security/nss/lib/ssl/ssl.h 16 Feb 2011 02:40:21 -0000 +@@ -275,16 +275,49 @@ typedef SECStatus (PR_CALLBACK *SSLGetCl + * and certificate. + * fd - the file descriptor for the connection in question + * f - the application's callback that delivers the key and cert + * a - application specific data + */ + SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd, + SSLGetClientAuthData f, void *a); + ++/* ++ * Prototype for SSL callback to get client auth data from the application, ++ * when using the underlying platform's cryptographic primitives. Returning ++ * SECFailure will cause the socket to send no client certificate. ++ * arg - application passed argument ++ * caNames - pointer to distinguished names of CAs that the server likes ++ * pRetCerts - pointer to pointer to list of certs, with the first being ++ * the client cert, and any following being used for chain ++ * building ++ * pRetKey - pointer to native key pointer, for return of key ++ * - Windows: A pointer to a PCERT_KEY_CONTEXT that was allocated ++ * via PORT_Alloc(). Ownership of the PCERT_KEY_CONTEXT ++ * is transferred to NSS, which will free via ++ * PORT_Free(). ++ * - Mac OS X: A pointer to a SecKeyRef. Ownership is ++ * transferred to NSS, which will free via CFRelease(). ++ */ ++typedef SECStatus (PR_CALLBACK *SSLGetPlatformClientAuthData)(void *arg, ++ PRFileDesc *fd, ++ CERTDistNames *caNames, ++ CERTCertList **pRetCerts,/*return */ ++ void **pRetKey);/* return */ ++ ++/* ++ * Set the client side callback for SSL to retrieve user's private key ++ * and certificate. ++ * fd - the file descriptor for the connection in question ++ * f - the application's callback that delivers the key and cert ++ * a - application specific data ++ */ ++SSL_IMPORT SECStatus ++SSL_GetPlatformClientAuthDataHook(PRFileDesc *fd, ++ SSLGetPlatformClientAuthData f, void *a); + + /* + ** SNI extension processing callback function. + ** It is called when SSL socket receives SNI extension in ClientHello message. + ** Upon this callback invocation, application is responsible to reconfigure the + ** socket with the data for a particular server name. + ** There are three potential outcomes of this function invocation: + ** * application does not recognize the name or the type and wants the +Index: mozilla/security/nss/lib/ssl/ssl3con.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v +retrieving revision 1.142 +diff -p -u -8 -r1.142 ssl3con.c +--- mozilla/security/nss/lib/ssl/ssl3con.c 24 Jun 2010 19:53:20 -0000 1.142 ++++ mozilla/security/nss/lib/ssl/ssl3con.c 16 Feb 2011 02:40:21 -0000 +@@ -2007,16 +2007,19 @@ ssl3_ComputeRecordMAC( + rv = SECFailure; + ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE); + } + return rv; + } + + static PRBool + ssl3_ClientAuthTokenPresent(sslSessionID *sid) { ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++ return PR_TRUE; ++#else + PK11SlotInfo *slot = NULL; + PRBool isPresent = PR_TRUE; + + /* we only care if we are doing client auth */ + if (!sid || !sid->u.ssl3.clAuthValid) { + return PR_TRUE; + } + +@@ -2030,16 +2033,17 @@ ssl3_ClientAuthTokenPresent(sslSessionID + sid->u.ssl3.clAuthModuleID != PK11_GetModuleID(slot) || + (PK11_NeedLogin(slot) && !PK11_IsLoggedIn(slot, NULL))) { + isPresent = PR_FALSE; + } + if (slot) { + PK11_FreeSlot(slot); + } + return isPresent; ++#endif /* NSS_PLATFORM_CLIENT_AUTH */ + } + + static SECStatus + ssl3_CompressMACEncryptRecord(sslSocket * ss, + SSL3ContentType type, + const SSL3Opaque * pIn, + PRUint32 contentLen) + { +@@ -4812,40 +4816,41 @@ ssl3_SendCertificateVerify(sslSocket *ss + ssl_GetSpecReadLock(ss); + rv = ssl3_ComputeHandshakeHashes(ss, ss->ssl3.pwSpec, &hashes, 0); + ssl_ReleaseSpecReadLock(ss); + if (rv != SECSuccess) { + goto done; /* err code was set by ssl3_ComputeHandshakeHashes */ + } + + 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); ++ 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; + sslSessionID * sid = ss->sec.ci.sid; + + /* Remember the info about the slot that did the signing. + ** Later, when doing an SSL restart handshake, verify this. + ** These calls are mere accessors, and can't fail. + */ + slot = PK11_GetSlotFromPrivateKey(ss->ssl3.clientPrivateKey); + sid->u.ssl3.clAuthSeries = PK11_GetSlotSeries(slot); + sid->u.ssl3.clAuthSlotID = PK11_GetSlotID(slot); + sid->u.ssl3.clAuthModuleID = PK11_GetModuleID(slot); + sid->u.ssl3.clAuthValid = PR_TRUE; + PK11_FreeSlot(slot); + } +- /* If we're doing RSA key exchange, we're all done with the private key +- * here. Diffie-Hellman key exchanges need the client's +- * private key for the key exchange. +- */ +- if (ss->ssl3.hs.kea_def->exchKeyType == kt_rsa) { +- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); +- ss->ssl3.clientPrivateKey = NULL; +- } ++ 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 */ + } + + rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, buf.len + 2); + if (rv != SECSuccess) { + goto done; /* error code set by AppendHandshake */ + } +@@ -4890,16 +4895,36 @@ ssl3_HandleServerHello(sslSocket *ss, SS + goto alert_loser; + } + if (ss->ssl3.hs.ws != wait_server_hello) { + errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO; + desc = unexpected_message; + goto alert_loser; + } + ++ /* clean up anything left from previous handshake. */ ++ if (ss->ssl3.clientCertChain != NULL) { ++ CERT_DestroyCertificateList(ss->ssl3.clientCertChain); ++ ss->ssl3.clientCertChain = NULL; ++ } ++ if (ss->ssl3.clientCertificate != NULL) { ++ CERT_DestroyCertificate(ss->ssl3.clientCertificate); ++ ss->ssl3.clientCertificate = NULL; ++ } ++ if (ss->ssl3.clientPrivateKey != NULL) { ++ 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 */ ++ + temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); + if (temp < 0) { + goto loser; /* alert has been sent */ + } + version = (SSL3ProtocolVersion)temp; + + /* this is appropriate since the negotiation is complete, and we only + ** know SSL 3.x. +@@ -5430,42 +5455,39 @@ ssl3_HandleCertificateRequest(sslSocket + PRBool isTLS = PR_FALSE; + int i; + int errCode = SSL_ERROR_RX_MALFORMED_CERT_REQUEST; + int nnames = 0; + SECStatus rv; + 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)); + PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) ); + PORT_Assert( ss->opt.noLocks || ssl_HaveSSL3HandshakeLock(ss) ); + + if (ss->ssl3.hs.ws != wait_cert_request && + ss->ssl3.hs.ws != wait_server_key) { + desc = unexpected_message; + errCode = SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST; + goto alert_loser; + } + +- /* clean up anything left from previous handshake. */ +- if (ss->ssl3.clientCertChain != NULL) { +- CERT_DestroyCertificateList(ss->ssl3.clientCertChain); +- ss->ssl3.clientCertChain = NULL; +- } +- if (ss->ssl3.clientCertificate != NULL) { +- CERT_DestroyCertificate(ss->ssl3.clientCertificate); +- ss->ssl3.clientCertificate = NULL; +- } +- if (ss->ssl3.clientPrivateKey != NULL) { +- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); +- ss->ssl3.clientPrivateKey = NULL; +- } ++ PORT_Assert(ss->ssl3.clientCertChain == NULL); ++ PORT_Assert(ss->ssl3.clientCertificate == NULL); ++ PORT_Assert(ss->ssl3.clientPrivateKey == NULL); ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++ PORT_Assert(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); + if (rv != SECSuccess) + goto loser; /* malformed, alert has been sent */ + + arena = ca_list.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); + if (arena == NULL) +@@ -5522,31 +5544,82 @@ ssl3_HandleCertificateRequest(sslSocket + } + + if (length != 0) + goto alert_loser; /* malformed */ + + 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 { + /* XXX Should pass cert_types in this call!! */ + rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg, + ss->fd, &ca_list, + &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 */ + if (ss->ssl3.clientCertificate) { + /* got a cert, but no key - free it */ + CERT_DestroyCertificate(ss->ssl3.clientCertificate); + ss->ssl3.clientCertificate = NULL; + } +@@ -5569,16 +5642,17 @@ ssl3_HandleCertificateRequest(sslSocket + ss->ssl3.clientCertificate = NULL; + } + if (ss->ssl3.clientPrivateKey != NULL) { + SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); + ss->ssl3.clientPrivateKey = NULL; + } + goto send_no_certificate; + } ++#endif /* NSS_PLATFORM_CLIENT_AUTH */ + break; /* not an error */ + + case SECFailure: + default: + send_no_certificate: + if (isTLS) { + ss->ssl3.sendEmptyCert = PR_TRUE; + } else { +@@ -5599,16 +5673,20 @@ alert_loser: + desc = decode_error; + (void)SSL3_SendAlert(ss, alert_fatal, desc); + loser: + PORT_SetError(errCode); + rv = SECFailure; + 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; + } + + /* + * attempt to restart the handshake after asynchronously handling + * a request for the client's certificate. + * + * inputs: +@@ -5697,24 +5775,35 @@ ssl3_HandleServerHelloDone(sslSocket *ss + if (ss->ssl3.sendEmptyCert) { + ss->ssl3.sendEmptyCert = PR_FALSE; + rv = ssl3_SendEmptyCertificate(ss); + /* Don't send verify */ + if (rv != SECSuccess) { + 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; + rv = ssl3_SendCertificate(ss); + if (rv != SECSuccess) { + goto loser; /* error code is set. */ + } + } ++#endif /* NSS_PLATFORM_CLIENT_AUTH */ + + rv = ssl3_SendClientKeyExchange(ss); + if (rv != SECSuccess) { + goto loser; /* err is set. */ + } + + if (send_verify) { + rv = ssl3_SendCertificateVerify(ss); +@@ -9426,16 +9515,20 @@ void + ssl3_DestroySSL3Info(sslSocket *ss) + { + + if (ss->ssl3.clientCertificate != NULL) + CERT_DestroyCertificate(ss->ssl3.clientCertificate); + + 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); + + if (ss->ssl3.clientCertChain != NULL) { + CERT_DestroyCertificateList(ss->ssl3.clientCertChain); + ss->ssl3.clientCertChain = NULL; + } +Index: mozilla/security/nss/lib/ssl/ssl3ext.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3ext.c,v +retrieving revision 1.14 +diff -p -u -8 -r1.14 ssl3ext.c +--- mozilla/security/nss/lib/ssl/ssl3ext.c 3 Apr 2010 19:19:07 -0000 1.14 ++++ mozilla/security/nss/lib/ssl/ssl3ext.c 16 Feb 2011 02:40:21 -0000 +@@ -41,18 +41,18 @@ + * ***** END LICENSE BLOCK ***** */ + + /* TLS extension code moved here from ssl3ecc.c */ + /* $Id: ssl3ext.c,v 1.14 2010/04/03 19:19:07 nelson%bolyard.com Exp $ */ + + #include "nssrenam.h" + #include "nss.h" + #include "ssl.h" +-#include "sslproto.h" + #include "sslimpl.h" ++#include "sslproto.h" + #include "pk11pub.h" + #include "blapi.h" + #include "prinit.h" + + static unsigned char key_name[SESS_TICKET_KEY_NAME_LEN]; + static PK11SymKey *session_ticket_enc_key_pkcs11 = NULL; + static PK11SymKey *session_ticket_mac_key_pkcs11 = NULL; + +Index: mozilla/security/nss/lib/ssl/sslauth.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslauth.c,v +retrieving revision 1.16 +diff -p -u -8 -r1.16 sslauth.c +--- mozilla/security/nss/lib/ssl/sslauth.c 20 Apr 2006 00:20:45 -0000 1.16 ++++ mozilla/security/nss/lib/ssl/sslauth.c 16 Feb 2011 02:40:21 -0000 +@@ -204,16 +204,38 @@ SSL_GetClientAuthDataHook(PRFileDesc *s, + return SECFailure; + } + + ss->getClientAuthData = func; + ss->getClientAuthDataArg = arg; + return SECSuccess; + } + ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++/* NEED LOCKS IN HERE. */ ++SECStatus ++SSL_GetPlatformClientAuthDataHook(PRFileDesc *s, ++ SSLGetPlatformClientAuthData func, ++ void *arg) ++{ ++ sslSocket *ss; ++ ++ ss = ssl_FindSocket(s); ++ if (!ss) { ++ SSL_DBG(("%d: SSL[%d]: bad socket in GetPlatformClientAuthDataHook", ++ SSL_GETPID(), s)); ++ return SECFailure; ++ } ++ ++ ss->getPlatformClientAuthData = func; ++ ss->getPlatformClientAuthDataArg = arg; ++ return SECSuccess; ++} ++#endif /* NSS_PLATFORM_CLIENT_AUTH */ ++ + /* NEED LOCKS IN HERE. */ + SECStatus + SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg) + { + sslSocket *ss; + + ss = ssl_FindSocket(s); + if (!ss) { +Index: mozilla/security/nss/lib/ssl/sslimpl.h +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslimpl.h,v +retrieving revision 1.77 +diff -p -u -8 -r1.77 sslimpl.h +--- mozilla/security/nss/lib/ssl/sslimpl.h 10 Feb 2010 00:33:50 -0000 1.77 ++++ mozilla/security/nss/lib/ssl/sslimpl.h 16 Feb 2011 02:40:21 -0000 +@@ -60,16 +60,25 @@ + #if defined(XP_UNIX) || defined(XP_BEOS) + #include "unistd.h" + #endif + #include "nssrwlk.h" + #include "prthread.h" + + #include "sslt.h" /* for some formerly private types, now public */ + ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++#if defined(XP_WIN32) ++#include <windows.h> ++#include <wincrypt.h> ++#elif defined(XP_MACOSX) ++#include <Security/Security.h> ++#endif ++#endif ++ + /* to make some of these old enums public without namespace pollution, + ** it was necessary to prepend ssl_ to the names. + ** These #defines preserve compatibility with the old code here in libssl. + */ + typedef SSLKEAType SSL3KEAType; + typedef SSLMACAlgorithm SSL3MACAlgorithm; + typedef SSLSignType SSL3SignType; + +@@ -782,16 +791,25 @@ const ssl3CipherSuiteDef *suite_def; + SSL3Hashes sFinished[2]; + SSL3Opaque data[72]; + } finishedMsgs; + #ifdef NSS_ENABLE_ECC + PRUint32 negotiatedECCurves; /* bit mask */ + #endif /* NSS_ENABLE_ECC */ + } SSL3HandshakeState; + ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++#if defined(XP_WIN32) ++typedef PCERT_KEY_CONTEXT PlatformKey; ++#elif defined(XP_MACOSX) ++typedef SecKeyRef PlatformKey; ++#else ++typedef void *PlatformKey; ++#endif ++#endif + + + /* + ** This is the "ssl3" struct, as in "ss->ssl3". + ** note: + ** usually, crSpec == cwSpec and prSpec == pwSpec. + ** Sometimes, crSpec == pwSpec and prSpec == cwSpec. + ** But there are never more than 2 actual specs. +@@ -805,16 +823,19 @@ struct ssl3StateStr { + */ + ssl3CipherSpec * crSpec; /* current read spec. */ + ssl3CipherSpec * prSpec; /* pending read spec. */ + ssl3CipherSpec * cwSpec; /* current write spec. */ + ssl3CipherSpec * pwSpec; /* pending write spec. */ + + CERTCertificate * clientCertificate; /* used by client */ + SECKEYPrivateKey * clientPrivateKey; /* used by client */ ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++ PlatformKey platformClientKey; /* used by client */ ++#endif /* NSS_PLATFORM_CLIENT_AUTH */ + CERTCertificateList *clientCertChain; /* used by client */ + PRBool sendEmptyCert; /* used by client */ + + int policy; + /* This says what cipher suites we can do, and should + * be either SSL_ALLOWED or SSL_RESTRICTED + */ + PRArenaPool * peerCertArena; +@@ -1045,16 +1066,20 @@ const unsigned char * preferredCipher; + + ssl3KeyPair * stepDownKeyPair; /* RSA step down keys */ + + /* Callbacks */ + SSLAuthCertificate authCertificate; + void *authCertificateArg; + SSLGetClientAuthData getClientAuthData; + void *getClientAuthDataArg; ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++ SSLGetPlatformClientAuthData getPlatformClientAuthData; ++ void *getPlatformClientAuthDataArg; ++#endif /* NSS_PLATFORM_CLIENT_AUTH */ + SSLSNISocketConfig sniSocketConfig; + void *sniSocketConfigArg; + SSLBadCertHandler handleBadCert; + void *badCertArg; + SSLHandshakeCallback handshakeCallback; + void *handshakeCallbackData; + void *pkcs11PinArg; + +@@ -1587,16 +1612,36 @@ extern SECStatus SSL3_ShutdownServerCach + extern SECStatus ssl_InitSymWrapKeysLock(void); + + extern SECStatus ssl_FreeSymWrapKeysLock(void); + + extern SECStatus ssl_InitSessionCacheLocks(PRBool lazyInit); + + extern SECStatus ssl_FreeSessionCacheLocks(void); + ++/***************** platform client auth ****************/ ++ ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++// Releases the platform key. ++extern void ssl_FreePlatformKey(PlatformKey key); ++ ++// Implement the client CertificateVerify message for SSL3/TLS1.0 ++extern SECStatus ssl3_PlatformSignHashes(SSL3Hashes *hash, ++ PlatformKey key, SECItem *buf, ++ PRBool isTLS); ++ ++// Converts a CERTCertList* (A collection of CERTCertificates) into a ++// CERTCertificateList* (A collection of SECItems), or returns NULL if ++// it cannot be converted. ++// This is to allow the platform-supplied chain to be created with purely ++// public API functions, using the preferred CERTCertList mutators, rather ++// pushing this hack to clients. ++extern CERTCertificateList* hack_NewCertificateListFromCertList( ++ CERTCertList* list); ++#endif /* NSS_PLATFORM_CLIENT_AUTH */ + + /********************** misc calls *********************/ + + extern int ssl_MapLowLevelError(int hiLevelError); + + extern PRUint32 ssl_Time(void); + + extern void SSL_AtomicIncrementLong(long * x); +Index: mozilla/security/nss/lib/ssl/sslsock.c +=================================================================== +RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslsock.c,v +retrieving revision 1.67 +diff -p -u -8 -r1.67 sslsock.c +--- mozilla/security/nss/lib/ssl/sslsock.c 25 Apr 2010 23:37:38 -0000 1.67 ++++ mozilla/security/nss/lib/ssl/sslsock.c 16 Feb 2011 02:40:21 -0000 +@@ -329,16 +329,20 @@ ssl_DupSocket(sslSocket *os) + /* + * XXX the preceding CERT_ and SECKEY_ functions can fail and return NULL. + * XXX We should detect this, and not just march on with NULL pointers. + */ + ss->authCertificate = os->authCertificate; + ss->authCertificateArg = os->authCertificateArg; + ss->getClientAuthData = os->getClientAuthData; + ss->getClientAuthDataArg = os->getClientAuthDataArg; ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++ ss->getPlatformClientAuthData = os->getPlatformClientAuthData; ++ ss->getPlatformClientAuthDataArg = os->getPlatformClientAuthDataArg; ++#endif + ss->sniSocketConfig = os->sniSocketConfig; + ss->sniSocketConfigArg = os->sniSocketConfigArg; + ss->handleBadCert = os->handleBadCert; + ss->badCertArg = os->badCertArg; + ss->handshakeCallback = os->handshakeCallback; + ss->handshakeCallbackData = os->handshakeCallbackData; + ss->pkcs11PinArg = os->pkcs11PinArg; + +@@ -1338,16 +1342,22 @@ SSL_ReconfigFD(PRFileDesc *model, PRFile + if (sm->authCertificate) + ss->authCertificate = sm->authCertificate; + if (sm->authCertificateArg) + ss->authCertificateArg = sm->authCertificateArg; + if (sm->getClientAuthData) + ss->getClientAuthData = sm->getClientAuthData; + if (sm->getClientAuthDataArg) + ss->getClientAuthDataArg = sm->getClientAuthDataArg; ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++ if (sm->getPlatformClientAuthData) ++ ss->getPlatformClientAuthData = sm->getPlatformClientAuthData; ++ if (sm->getPlatformClientAuthDataArg) ++ ss->getPlatformClientAuthDataArg = sm->getPlatformClientAuthDataArg; ++#endif + if (sm->sniSocketConfig) + ss->sniSocketConfig = sm->sniSocketConfig; + if (sm->sniSocketConfigArg) + ss->sniSocketConfigArg = sm->sniSocketConfigArg; + if (sm->handleBadCert) + ss->handleBadCert = sm->handleBadCert; + if (sm->badCertArg) + ss->badCertArg = sm->badCertArg; +@@ -2350,16 +2360,20 @@ ssl_NewSocket(PRBool makeLocks) + ss->dbHandle = CERT_GetDefaultCertDB(); + + /* Provide default implementation of hooks */ + ss->authCertificate = SSL_AuthCertificate; + ss->authCertificateArg = (void *)ss->dbHandle; + ss->sniSocketConfig = NULL; + ss->sniSocketConfigArg = NULL; + ss->getClientAuthData = NULL; ++#ifdef NSS_PLATFORM_CLIENT_AUTH ++ ss->getPlatformClientAuthData = NULL; ++ ss->getPlatformClientAuthDataArg = NULL; ++#endif /* NSS_PLATFORM_CLIENT_AUTH */ + ss->handleBadCert = NULL; + ss->badCertArg = NULL; + ss->pkcs11PinArg = NULL; + + ssl_ChooseOps(ss); + ssl2_InitSocketPolicy(ss); + ssl3_InitSocketPolicy(ss); + diff --git a/net/third_party/nss/patches/dheclientauth.patch b/net/third_party/nss/patches/dheclientauth.patch deleted file mode 100644 index 92d1d97..0000000 --- a/net/third_party/nss/patches/dheclientauth.patch +++ /dev/null @@ -1,98 +0,0 @@ -Index: mozilla/security/nss/lib/ssl/ssl3con.c -=================================================================== -RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v -retrieving revision 1.142.2.4 -diff -u -p -u -8 -r1.142.2.4 ssl3con.c ---- mozilla/security/nss/lib/ssl/ssl3con.c 1 Sep 2010 19:47:11 -0000 1.142.2.4 -+++ mozilla/security/nss/lib/ssl/ssl3con.c 8 Dec 2010 06:55:49 -0000 -@@ -4832,24 +4832,18 @@ ssl3_SendCertificateVerify(sslSocket *ss - */ - slot = PK11_GetSlotFromPrivateKey(ss->ssl3.clientPrivateKey); - sid->u.ssl3.clAuthSeries = PK11_GetSlotSeries(slot); - sid->u.ssl3.clAuthSlotID = PK11_GetSlotID(slot); - sid->u.ssl3.clAuthModuleID = PK11_GetModuleID(slot); - sid->u.ssl3.clAuthValid = PR_TRUE; - PK11_FreeSlot(slot); - } -- /* If we're doing RSA key exchange, we're all done with the private key -- * here. Diffie-Hellman key exchanges need the client's -- * private key for the key exchange. -- */ -- if (ss->ssl3.hs.kea_def->exchKeyType == kt_rsa) { -- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); -- ss->ssl3.clientPrivateKey = NULL; -- } -+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); -+ ss->ssl3.clientPrivateKey = NULL; - if (rv != SECSuccess) { - goto done; /* err code was set by ssl3_SignHashes */ - } - - rv = ssl3_AppendHandshakeHeader(ss, certificate_verify, buf.len + 2); - if (rv != SECSuccess) { - goto done; /* error code set by AppendHandshake */ - } -@@ -4894,16 +4888,30 @@ ssl3_HandleServerHello(sslSocket *ss, SS - goto alert_loser; - } - if (ss->ssl3.hs.ws != wait_server_hello) { - errCode = SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO; - desc = unexpected_message; - goto alert_loser; - } - -+ /* clean up anything left from previous handshake. */ -+ if (ss->ssl3.clientCertChain != NULL) { -+ CERT_DestroyCertificateList(ss->ssl3.clientCertChain); -+ ss->ssl3.clientCertChain = NULL; -+ } -+ if (ss->ssl3.clientCertificate != NULL) { -+ CERT_DestroyCertificate(ss->ssl3.clientCertificate); -+ ss->ssl3.clientCertificate = NULL; -+ } -+ if (ss->ssl3.clientPrivateKey != NULL) { -+ SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); -+ ss->ssl3.clientPrivateKey = NULL; -+ } -+ - temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length); - if (temp < 0) { - goto loser; /* alert has been sent */ - } - version = (SSL3ProtocolVersion)temp; - - /* this is appropriate since the negotiation is complete, and we only - ** know SSL 3.x. -@@ -5449,29 +5457,19 @@ ssl3_HandleCertificateRequest(sslSocket - - if (ss->ssl3.hs.ws != wait_cert_request && - ss->ssl3.hs.ws != wait_server_key) { - desc = unexpected_message; - errCode = SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST; - goto alert_loser; - } - -- /* clean up anything left from previous handshake. */ -- if (ss->ssl3.clientCertChain != NULL) { -- CERT_DestroyCertificateList(ss->ssl3.clientCertChain); -- ss->ssl3.clientCertChain = NULL; -- } -- if (ss->ssl3.clientCertificate != NULL) { -- CERT_DestroyCertificate(ss->ssl3.clientCertificate); -- ss->ssl3.clientCertificate = NULL; -- } -- if (ss->ssl3.clientPrivateKey != NULL) { -- SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey); -- ss->ssl3.clientPrivateKey = NULL; -- } -+ PORT_Assert(ss->ssl3.clientCertChain == NULL); -+ PORT_Assert(ss->ssl3.clientCertificate == NULL); -+ PORT_Assert(ss->ssl3.clientPrivateKey == NULL); - - isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0); - rv = ssl3_ConsumeHandshakeVariable(ss, &cert_types, 1, &b, &length); - if (rv != SECSuccess) - goto loser; /* malformed, alert has been sent */ - - arena = ca_list.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - if (arena == NULL) |