Index: net/third_party/nss/patches/clientauth.patch |
=================================================================== |
--- net/third_party/nss/patches/clientauth.patch (revision 0) |
+++ net/third_party/nss/patches/clientauth.patch (revision 0) |
@@ -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); |
+ |