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:31:45.326118409 -0700
      3 +++ b/nss/lib/ssl/ssl3con.c	2013-07-31 12:35:27.189373289 -0700
      4 @@ -2284,6 +2284,9 @@ ssl3_ClientAuthTokenPresent(sslSessionID
      5      PRBool isPresent = PR_TRUE;
      6  
      7      /* we only care if we are doing client auth */
      8 +    /* If NSS_PLATFORM_CLIENT_AUTH is defined and a platformClientKey is being
      9 +     * used, u.ssl3.clAuthValid will be false and this function will always
     10 +     * return PR_TRUE. */
     11      if (!sid || !sid->u.ssl3.clAuthValid) {
     12  	return PR_TRUE;
     13      }
     14 @@ -5768,25 +5771,36 @@ ssl3_SendCertificateVerify(sslSocket *ss
     15  
     16      isTLS = (PRBool)(ss->ssl3.pwSpec->version > SSL_LIBRARY_VERSION_3_0);
     17      isTLS12 = (PRBool)(ss->ssl3.pwSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
     18 -    keyType = ss->ssl3.clientPrivateKey->keyType;
     19 -    rv = ssl3_SignHashes(&hashes, ss->ssl3.clientPrivateKey, &buf, isTLS);
     20 -    if (rv == SECSuccess) {
     21 -	PK11SlotInfo * slot;
     22 -	sslSessionID * sid   = ss->sec.ci.sid;
     23 +    if (ss->ssl3.platformClientKey) {
     24 +#ifdef NSS_PLATFORM_CLIENT_AUTH
     25 +	keyType = CERT_GetCertKeyType(
     26 +	    &ss->ssl3.clientCertificate->subjectPublicKeyInfo);
     27 +	rv = ssl3_PlatformSignHashes(
     28 +	    &hashes, ss->ssl3.platformClientKey, &buf, isTLS, keyType);
     29 +	ssl_FreePlatformKey(ss->ssl3.platformClientKey);
     30 +	ss->ssl3.platformClientKey = (PlatformKey)NULL;
     31 +#endif /* NSS_PLATFORM_CLIENT_AUTH */
     32 +    } else {
     33 +	keyType = ss->ssl3.clientPrivateKey->keyType;
     34 +	rv = ssl3_SignHashes(&hashes, ss->ssl3.clientPrivateKey, &buf, isTLS);
     35 +	if (rv == SECSuccess) {
     36 +	    PK11SlotInfo * slot;
     37 +	    sslSessionID * sid   = ss->sec.ci.sid;
     38  
     39 -    	/* Remember the info about the slot that did the signing.
     40 -	** Later, when doing an SSL restart handshake, verify this.
     41 -	** These calls are mere accessors, and can't fail.
     42 -	*/
     43 -	slot = PK11_GetSlotFromPrivateKey(ss->ssl3.clientPrivateKey);
     44 -	sid->u.ssl3.clAuthSeries     = PK11_GetSlotSeries(slot);
     45 -	sid->u.ssl3.clAuthSlotID     = PK11_GetSlotID(slot);
     46 -	sid->u.ssl3.clAuthModuleID   = PK11_GetModuleID(slot);
     47 -	sid->u.ssl3.clAuthValid      = PR_TRUE;
     48 -	PK11_FreeSlot(slot);
     49 +	    /* Remember the info about the slot that did the signing.
     50 +	    ** Later, when doing an SSL restart handshake, verify this.
     51 +	    ** These calls are mere accessors, and can't fail.
     52 +	    */
     53 +	    slot = PK11_GetSlotFromPrivateKey(ss->ssl3.clientPrivateKey);
     54 +	    sid->u.ssl3.clAuthSeries     = PK11_GetSlotSeries(slot);
     55 +	    sid->u.ssl3.clAuthSlotID     = PK11_GetSlotID(slot);
     56 +	    sid->u.ssl3.clAuthModuleID   = PK11_GetModuleID(slot);
     57 +	    sid->u.ssl3.clAuthValid      = PR_TRUE;
     58 +	    PK11_FreeSlot(slot);
     59 +	}
     60 +	SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
     61 +	ss->ssl3.clientPrivateKey = NULL;
     62      }
     63 -    SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
     64 -    ss->ssl3.clientPrivateKey = NULL;
     65      if (rv != SECSuccess) {
     66  	goto done;	/* err code was set by ssl3_SignHashes */
     67      }
     68 @@ -5870,6 +5884,12 @@ ssl3_HandleServerHello(sslSocket *ss, SS
     69         SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
     70         ss->ssl3.clientPrivateKey = NULL;
     71      }
     72 +#ifdef NSS_PLATFORM_CLIENT_AUTH
     73 +    if (ss->ssl3.platformClientKey) {
     74 +       ssl_FreePlatformKey(ss->ssl3.platformClientKey);
     75 +       ss->ssl3.platformClientKey = (PlatformKey)NULL;
     76 +    }
     77 +#endif  /* NSS_PLATFORM_CLIENT_AUTH */
     78  
     79      temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
     80      if (temp < 0) {
     81 @@ -6496,6 +6516,10 @@ ssl3_HandleCertificateRequest(sslSocket
     82      SECItem              cert_types  = {siBuffer, NULL, 0};
     83      SECItem              algorithms  = {siBuffer, NULL, 0};
     84      CERTDistNames        ca_list;
     85 +#ifdef NSS_PLATFORM_CLIENT_AUTH
     86 +    CERTCertList *       platform_cert_list = NULL;
     87 +    CERTCertListNode *   certNode = NULL;
     88 +#endif  /* NSS_PLATFORM_CLIENT_AUTH */
     89  
     90      SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
     91  		SSL_GETPID(), ss->fd));
     92 @@ -6512,6 +6536,7 @@ ssl3_HandleCertificateRequest(sslSocket
     93      PORT_Assert(ss->ssl3.clientCertChain == NULL);
     94      PORT_Assert(ss->ssl3.clientCertificate == NULL);
     95      PORT_Assert(ss->ssl3.clientPrivateKey == NULL);
     96 +    PORT_Assert(ss->ssl3.platformClientKey == (PlatformKey)NULL);
     97  
     98      isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
     99      isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    100 @@ -6591,6 +6616,18 @@ ssl3_HandleCertificateRequest(sslSocket
    101      desc = no_certificate;
    102      ss->ssl3.hs.ws = wait_hello_done;
    103  
    104 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    105 +    if (ss->getPlatformClientAuthData != NULL) {
    106 +	/* XXX Should pass cert_types and algorithms in this call!! */
    107 +        rv = (SECStatus)(*ss->getPlatformClientAuthData)(
    108 +                                        ss->getPlatformClientAuthDataArg,
    109 +                                        ss->fd, &ca_list,
    110 +                                        &platform_cert_list,
    111 +                                        (void**)&ss->ssl3.platformClientKey,
    112 +                                        &ss->ssl3.clientCertificate,
    113 +                                        &ss->ssl3.clientPrivateKey);
    114 +    } else
    115 +#endif
    116      if (ss->getClientAuthData != NULL) {
    117  	/* XXX Should pass cert_types and algorithms in this call!! */
    118  	rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg,
    119 @@ -6600,12 +6637,52 @@ ssl3_HandleCertificateRequest(sslSocket
    120      } else {
    121  	rv = SECFailure; /* force it to send a no_certificate alert */
    122      }
    123 +
    124      switch (rv) {
    125      case SECWouldBlock:	/* getClientAuthData has put up a dialog box. */
    126  	ssl3_SetAlwaysBlock(ss);
    127  	break;	/* not an error */
    128  
    129      case SECSuccess:
    130 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    131 +        if (!platform_cert_list || CERT_LIST_EMPTY(platform_cert_list) ||
    132 +            !ss->ssl3.platformClientKey) {
    133 +            if (platform_cert_list) {
    134 +                CERT_DestroyCertList(platform_cert_list);
    135 +                platform_cert_list = NULL;
    136 +            }
    137 +            if (ss->ssl3.platformClientKey) {
    138 +                ssl_FreePlatformKey(ss->ssl3.platformClientKey);
    139 +                ss->ssl3.platformClientKey = (PlatformKey)NULL;
    140 +            }
    141 +	    /* Fall through to NSS client auth check */
    142 +        } else {
    143 +	    certNode = CERT_LIST_HEAD(platform_cert_list);
    144 +	    ss->ssl3.clientCertificate = CERT_DupCertificate(certNode->cert);
    145 +
    146 +	    /* Setting ssl3.clientCertChain non-NULL will cause
    147 +	     * ssl3_HandleServerHelloDone to call SendCertificate.
    148 +	     * Note: clientCertChain should include the EE cert as
    149 +	     * clientCertificate is ignored during the actual sending
    150 +	     */
    151 +	    ss->ssl3.clientCertChain =
    152 +		    hack_NewCertificateListFromCertList(platform_cert_list);
    153 +	    CERT_DestroyCertList(platform_cert_list);
    154 +	    platform_cert_list = NULL;
    155 +	    if (ss->ssl3.clientCertChain == NULL) {
    156 +		if (ss->ssl3.clientCertificate != NULL) {
    157 +		    CERT_DestroyCertificate(ss->ssl3.clientCertificate);
    158 +		    ss->ssl3.clientCertificate = NULL;
    159 +		}
    160 +		if (ss->ssl3.platformClientKey) {
    161 +		    ssl_FreePlatformKey(ss->ssl3.platformClientKey);
    162 +		    ss->ssl3.platformClientKey = (PlatformKey)NULL;
    163 +		}
    164 +		goto send_no_certificate;
    165 +	    }
    166 +	    break;  /* not an error */
    167 +	}
    168 +#endif   /* NSS_PLATFORM_CLIENT_AUTH */
    169          /* check what the callback function returned */
    170          if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
    171              /* we are missing either the key or cert */
    172 @@ -6668,6 +6745,10 @@ loser:
    173  done:
    174      if (arena != NULL)
    175      	PORT_FreeArena(arena, PR_FALSE);
    176 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    177 +    if (platform_cert_list)
    178 +        CERT_DestroyCertList(platform_cert_list);
    179 +#endif
    180      return rv;
    181  }
    182  
    183 @@ -6749,7 +6830,8 @@ ssl3_SendClientSecondRound(sslSocket *ss
    184  
    185      sendClientCert = !ss->ssl3.sendEmptyCert &&
    186  		     ss->ssl3.clientCertChain  != NULL &&
    187 -		     ss->ssl3.clientPrivateKey != NULL;
    188 +		     (ss->ssl3.platformClientKey ||
    189 +		     ss->ssl3.clientPrivateKey != NULL);
    190  
    191      /* We must wait for the server's certificate to be authenticated before
    192       * sending the client certificate in order to disclosing the client
    193 @@ -11465,6 +11547,10 @@ ssl3_DestroySSL3Info(sslSocket *ss)
    194  
    195      if (ss->ssl3.clientPrivateKey != NULL)
    196  	SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
    197 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    198 +    if (ss->ssl3.platformClientKey)
    199 +	ssl_FreePlatformKey(ss->ssl3.platformClientKey);
    200 +#endif /* NSS_PLATFORM_CLIENT_AUTH */
    201  
    202      if (ss->ssl3.peerCertArena != NULL)
    203  	ssl3_CleanupPeerCerts(ss);
    204 diff -pu a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c
    205 --- a/nss/lib/ssl/ssl3ext.c	2013-07-31 12:07:10.964699464 -0700
    206 +++ b/nss/lib/ssl/ssl3ext.c	2013-07-31 12:35:27.189373289 -0700
    207 @@ -10,8 +10,8 @@
    208  #include "nssrenam.h"
    209  #include "nss.h"
    210  #include "ssl.h"
    211 -#include "sslproto.h"
    212  #include "sslimpl.h"
    213 +#include "sslproto.h"
    214  #include "pk11pub.h"
    215  #ifdef NO_PKCS11_BYPASS
    216  #include "blapit.h"
    217 diff -pu a/nss/lib/ssl/sslauth.c b/nss/lib/ssl/sslauth.c
    218 --- a/nss/lib/ssl/sslauth.c	2013-07-31 12:32:29.076760372 -0700
    219 +++ b/nss/lib/ssl/sslauth.c	2013-07-31 12:35:27.189373289 -0700
    220 @@ -219,6 +219,28 @@ SSL_GetClientAuthDataHook(PRFileDesc *s,
    221      return SECSuccess;
    222  }
    223  
    224 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    225 +/* NEED LOCKS IN HERE.  */
    226 +SECStatus 
    227 +SSL_GetPlatformClientAuthDataHook(PRFileDesc *s,
    228 +                                  SSLGetPlatformClientAuthData func,
    229 +                                  void *arg)
    230 +{
    231 +    sslSocket *ss;
    232 +
    233 +    ss = ssl_FindSocket(s);
    234 +    if (!ss) {
    235 +	SSL_DBG(("%d: SSL[%d]: bad socket in GetPlatformClientAuthDataHook",
    236 +		 SSL_GETPID(), s));
    237 +	return SECFailure;
    238 +    }
    239 +
    240 +    ss->getPlatformClientAuthData = func;
    241 +    ss->getPlatformClientAuthDataArg = arg;
    242 +    return SECSuccess;
    243 +}
    244 +#endif   /* NSS_PLATFORM_CLIENT_AUTH */
    245 +
    246  /* NEED LOCKS IN HERE.  */
    247  SECStatus 
    248  SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
    249 diff -pu a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h
    250 --- a/nss/lib/ssl/ssl.h	2013-07-31 12:32:29.076760372 -0700
    251 +++ b/nss/lib/ssl/ssl.h	2013-07-31 12:35:27.199373436 -0700
    252 @@ -503,6 +503,48 @@ typedef SECStatus (PR_CALLBACK *SSLGetCl
    253  SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd, 
    254  			                       SSLGetClientAuthData f, void *a);
    255  
    256 +/*
    257 + * Prototype for SSL callback to get client auth data from the application,
    258 + * optionally using the underlying platform's cryptographic primitives.
    259 + * To use the platform cryptographic primitives, caNames and pRetCerts
    260 + * should be set.  To use NSS, pRetNSSCert and pRetNSSKey should be set.
    261 + * Returning SECFailure will cause the socket to send no client certificate.
    262 + *	arg - application passed argument
    263 + *	caNames - pointer to distinguished names of CAs that the server likes
    264 + *	pRetCerts - pointer to pointer to list of certs, with the first being
    265 + *		    the client cert, and any following being used for chain
    266 + *		    building
    267 + *	pRetKey - pointer to native key pointer, for return of key
    268 + *          - Windows: A pointer to a PCERT_KEY_CONTEXT that was allocated
    269 + *                     via PORT_Alloc(). Ownership of the PCERT_KEY_CONTEXT
    270 + *                     is transferred to NSS, which will free via
    271 + *                     PORT_Free().
    272 + *          - Mac OS X: A pointer to a SecKeyRef. Ownership is
    273 + *                      transferred to NSS, which will free via CFRelease().
    274 + *	pRetNSSCert - pointer to pointer to NSS cert, for return of cert.
    275 + *	pRetNSSKey - pointer to NSS key pointer, for return of key.
    276 + */
    277 +typedef SECStatus (PR_CALLBACK *SSLGetPlatformClientAuthData)(void *arg,
    278 +                                PRFileDesc *fd,
    279 +                                CERTDistNames *caNames,
    280 +                                CERTCertList **pRetCerts,/*return */
    281 +                                void **pRetKey,/* return */
    282 +                                CERTCertificate **pRetNSSCert,/*return */
    283 +                                SECKEYPrivateKey **pRetNSSKey);/* return */
    284 +
    285 +/*
    286 + * Set the client side callback for SSL to retrieve user's private key
    287 + * and certificate.
    288 + * Note: If a platform client auth callback is set, the callback configured by
    289 + * SSL_GetClientAuthDataHook, if any, will not be called.
    290 + *
    291 + *	fd - the file descriptor for the connection in question
    292 + *	f - the application's callback that delivers the key and cert
    293 + *	a - application specific data
    294 + */
    295 +SSL_IMPORT SECStatus
    296 +SSL_GetPlatformClientAuthDataHook(PRFileDesc *fd,
    297 +                                  SSLGetPlatformClientAuthData f, void *a);
    298  
    299  /*
    300  ** SNI extension processing callback function.
    301 diff -pu a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h
    302 --- a/nss/lib/ssl/sslimpl.h	2013-07-31 12:31:45.326118409 -0700
    303 +++ b/nss/lib/ssl/sslimpl.h	2013-07-31 12:35:27.199373436 -0700
    304 @@ -20,6 +20,7 @@
    305  #include "sslerr.h"
    306  #include "ssl3prot.h"
    307  #include "hasht.h"
    308 +#include "keythi.h"
    309  #include "nssilock.h"
    310  #include "pkcs11t.h"
    311  #if defined(XP_UNIX) || defined(XP_BEOS)
    312 @@ -31,6 +32,15 @@
    313  
    314  #include "sslt.h" /* for some formerly private types, now public */
    315  
    316 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    317 +#if defined(XP_WIN32)
    318 +#include <windows.h>
    319 +#include <wincrypt.h>
    320 +#elif defined(XP_MACOSX)
    321 +#include <Security/Security.h>
    322 +#endif
    323 +#endif
    324 +
    325  /* to make some of these old enums public without namespace pollution,
    326  ** it was necessary to prepend ssl_ to the names.
    327  ** These #defines preserve compatibility with the old code here in libssl.
    328 @@ -444,6 +454,14 @@ typedef SECStatus (*SSLCompressor)(void
    329                                     int                  inlen);
    330  typedef SECStatus (*SSLDestroy)(void *context, PRBool freeit);
    331  
    332 +#if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(XP_WIN32)
    333 +typedef PCERT_KEY_CONTEXT PlatformKey;
    334 +#elif defined(NSS_PLATFORM_CLIENT_AUTH) && defined(XP_MACOSX)
    335 +typedef SecKeyRef PlatformKey;
    336 +#else
    337 +typedef void *PlatformKey;
    338 +#endif
    339 +
    340  
    341  
    342  /*
    343 @@ -896,6 +914,10 @@ struct ssl3StateStr {
    344  
    345      CERTCertificate *    clientCertificate;  /* used by client */
    346      SECKEYPrivateKey *   clientPrivateKey;   /* used by client */
    347 +    /* platformClientKey is present even when NSS_PLATFORM_CLIENT_AUTH is not
    348 +     * defined in order to allow cleaner conditional code.
    349 +     * At most one of clientPrivateKey and platformClientKey may be set. */
    350 +    PlatformKey          platformClientKey;  /* used by client */
    351      CERTCertificateList *clientCertChain;    /* used by client */
    352      PRBool               sendEmptyCert;      /* used by client */
    353  
    354 @@ -1153,6 +1175,10 @@ const unsigned char *  preferredCipher;
    355      void                     *authCertificateArg;
    356      SSLGetClientAuthData      getClientAuthData;
    357      void                     *getClientAuthDataArg;
    358 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    359 +    SSLGetPlatformClientAuthData getPlatformClientAuthData;
    360 +    void                        *getPlatformClientAuthDataArg;
    361 +#endif  /* NSS_PLATFORM_CLIENT_AUTH */
    362      SSLSNISocketConfig        sniSocketConfig;
    363      void                     *sniSocketConfigArg;
    364      SSLBadCertHandler         handleBadCert;
    365 @@ -1737,7 +1763,6 @@ extern void ssl_FreePRSocket(PRFileDesc
    366   * various ciphers */
    367  extern int ssl3_config_match_init(sslSocket *);
    368  
    369 -
    370  /* Create a new ref counted key pair object from two keys. */
    371  extern ssl3KeyPair * ssl3_NewKeyPair( SECKEYPrivateKey * privKey, 
    372                                        SECKEYPublicKey * pubKey);
    373 @@ -1777,6 +1802,26 @@ extern SECStatus ssl_InitSessionCacheLoc
    374  
    375  extern SECStatus ssl_FreeSessionCacheLocks(void);
    376  
    377 +/***************** platform client auth ****************/
    378 +
    379 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    380 +// Releases the platform key.
    381 +extern void ssl_FreePlatformKey(PlatformKey key);
    382 +
    383 +// Implement the client CertificateVerify message for SSL3/TLS1.0
    384 +extern SECStatus ssl3_PlatformSignHashes(SSL3Hashes *hash,
    385 +                                         PlatformKey key, SECItem *buf,
    386 +                                         PRBool isTLS, KeyType keyType);
    387 +
    388 +// Converts a CERTCertList* (A collection of CERTCertificates) into a
    389 +// CERTCertificateList* (A collection of SECItems), or returns NULL if
    390 +// it cannot be converted.
    391 +// This is to allow the platform-supplied chain to be created with purely
    392 +// public API functions, using the preferred CERTCertList mutators, rather
    393 +// pushing this hack to clients.
    394 +extern CERTCertificateList* hack_NewCertificateListFromCertList(
    395 +        CERTCertList* list);
    396 +#endif  /* NSS_PLATFORM_CLIENT_AUTH */
    397  
    398  /**************** DTLS-specific functions **************/
    399  extern void dtls_FreeQueuedMessage(DTLSQueuedMessage *msg);
    400 diff -pu a/nss/lib/ssl/sslsock.c b/nss/lib/ssl/sslsock.c
    401 --- a/nss/lib/ssl/sslsock.c	2013-07-31 12:28:39.283413269 -0700
    402 +++ b/nss/lib/ssl/sslsock.c	2013-07-31 12:35:27.199373436 -0700
    403 @@ -343,6 +343,10 @@ ssl_DupSocket(sslSocket *os)
    404  	    ss->authCertificateArg    = os->authCertificateArg;
    405  	    ss->getClientAuthData     = os->getClientAuthData;
    406  	    ss->getClientAuthDataArg  = os->getClientAuthDataArg;
    407 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    408 +	    ss->getPlatformClientAuthData    = os->getPlatformClientAuthData;
    409 +	    ss->getPlatformClientAuthDataArg = os->getPlatformClientAuthDataArg;
    410 +#endif
    411              ss->sniSocketConfig       = os->sniSocketConfig;
    412              ss->sniSocketConfigArg    = os->sniSocketConfigArg;
    413  	    ss->handleBadCert         = os->handleBadCert;
    414 @@ -1730,6 +1734,12 @@ SSL_ReconfigFD(PRFileDesc *model, PRFile
    415          ss->getClientAuthData     = sm->getClientAuthData;
    416      if (sm->getClientAuthDataArg)
    417          ss->getClientAuthDataArg  = sm->getClientAuthDataArg;
    418 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    419 +    if (sm->getPlatformClientAuthData)
    420 +        ss->getPlatformClientAuthData    = sm->getPlatformClientAuthData;
    421 +    if (sm->getPlatformClientAuthDataArg)
    422 +        ss->getPlatformClientAuthDataArg = sm->getPlatformClientAuthDataArg;
    423 +#endif
    424      if (sm->sniSocketConfig)
    425          ss->sniSocketConfig       = sm->sniSocketConfig;
    426      if (sm->sniSocketConfigArg)
    427 @@ -2980,6 +2990,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProto
    428          ss->sniSocketConfig    = NULL;
    429          ss->sniSocketConfigArg = NULL;
    430  	ss->getClientAuthData  = NULL;
    431 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    432 +	ss->getPlatformClientAuthData = NULL;
    433 +	ss->getPlatformClientAuthDataArg = NULL;
    434 +#endif   /* NSS_PLATFORM_CLIENT_AUTH */
    435  	ss->handleBadCert      = NULL;
    436  	ss->badCertArg         = NULL;
    437  	ss->pkcs11PinArg       = NULL;
    438