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	2014-01-17 17:52:00.295082288 -0800
      3 +++ b/nss/lib/ssl/ssl3con.c	2014-01-17 17:52:19.745405758 -0800
      4 @@ -2471,6 +2471,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 @@ -6103,25 +6106,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 @@ -6200,6 +6214,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 @@ -6827,6 +6847,18 @@ ssl3_ExtractClientKeyInfo(sslSocket *ss,
     82  	goto done;
     83      }
     84  
     85 +#if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(_WIN32)
     86 +    /* If the key is in CAPI, assume conservatively that the CAPI service
     87 +     * provider may be unable to sign SHA-256 hashes.
     88 +     */
     89 +    if (ss->ssl3.platformClientKey->dwKeySpec != CERT_NCRYPT_KEY_SPEC) {
     90 +	/* CAPI only supports RSA and DSA signatures, so we don't need to
     91 +	 * check the key type. */
     92 +	*preferSha1 = PR_TRUE;
     93 +	goto done;
     94 +    }
     95 +#endif  /* NSS_PLATFORM_CLIENT_AUTH && _WIN32 */
     96 +
     97      /* If the key is a 1024-bit RSA or DSA key, assume conservatively that
     98       * it may be unable to sign SHA-256 hashes. This is the case for older
     99       * Estonian ID cards that have 1024-bit RSA keys. In FIPS 186-2 and
    100 @@ -6925,6 +6957,10 @@ ssl3_HandleCertificateRequest(sslSocket
    101      SECItem              cert_types  = {siBuffer, NULL, 0};
    102      SECItem              algorithms  = {siBuffer, NULL, 0};
    103      CERTDistNames        ca_list;
    104 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    105 +    CERTCertList *       platform_cert_list = NULL;
    106 +    CERTCertListNode *   certNode = NULL;
    107 +#endif  /* NSS_PLATFORM_CLIENT_AUTH */
    108  
    109      SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
    110  		SSL_GETPID(), ss->fd));
    111 @@ -6941,6 +6977,7 @@ ssl3_HandleCertificateRequest(sslSocket
    112      PORT_Assert(ss->ssl3.clientCertChain == NULL);
    113      PORT_Assert(ss->ssl3.clientCertificate == NULL);
    114      PORT_Assert(ss->ssl3.clientPrivateKey == NULL);
    115 +    PORT_Assert(ss->ssl3.platformClientKey == (PlatformKey)NULL);
    116  
    117      isTLS = (PRBool)(ss->ssl3.prSpec->version > SSL_LIBRARY_VERSION_3_0);
    118      isTLS12 = (PRBool)(ss->ssl3.prSpec->version >= SSL_LIBRARY_VERSION_TLS_1_2);
    119 @@ -7020,6 +7057,18 @@ ssl3_HandleCertificateRequest(sslSocket
    120      desc = no_certificate;
    121      ss->ssl3.hs.ws = wait_hello_done;
    122  
    123 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    124 +    if (ss->getPlatformClientAuthData != NULL) {
    125 +	/* XXX Should pass cert_types and algorithms in this call!! */
    126 +        rv = (SECStatus)(*ss->getPlatformClientAuthData)(
    127 +                                        ss->getPlatformClientAuthDataArg,
    128 +                                        ss->fd, &ca_list,
    129 +                                        &platform_cert_list,
    130 +                                        (void**)&ss->ssl3.platformClientKey,
    131 +                                        &ss->ssl3.clientCertificate,
    132 +                                        &ss->ssl3.clientPrivateKey);
    133 +    } else
    134 +#endif
    135      if (ss->getClientAuthData != NULL) {
    136  	/* XXX Should pass cert_types and algorithms in this call!! */
    137  	rv = (SECStatus)(*ss->getClientAuthData)(ss->getClientAuthDataArg,
    138 @@ -7029,12 +7078,55 @@ ssl3_HandleCertificateRequest(sslSocket
    139      } else {
    140  	rv = SECFailure; /* force it to send a no_certificate alert */
    141      }
    142 +
    143      switch (rv) {
    144      case SECWouldBlock:	/* getClientAuthData has put up a dialog box. */
    145  	ssl3_SetAlwaysBlock(ss);
    146  	break;	/* not an error */
    147  
    148      case SECSuccess:
    149 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    150 +        if (!platform_cert_list || CERT_LIST_EMPTY(platform_cert_list) ||
    151 +            !ss->ssl3.platformClientKey) {
    152 +            if (platform_cert_list) {
    153 +                CERT_DestroyCertList(platform_cert_list);
    154 +                platform_cert_list = NULL;
    155 +            }
    156 +            if (ss->ssl3.platformClientKey) {
    157 +                ssl_FreePlatformKey(ss->ssl3.platformClientKey);
    158 +                ss->ssl3.platformClientKey = (PlatformKey)NULL;
    159 +            }
    160 +	    /* Fall through to NSS client auth check */
    161 +        } else {
    162 +	    certNode = CERT_LIST_HEAD(platform_cert_list);
    163 +	    ss->ssl3.clientCertificate = CERT_DupCertificate(certNode->cert);
    164 +
    165 +	    /* Setting ssl3.clientCertChain non-NULL will cause
    166 +	     * ssl3_HandleServerHelloDone to call SendCertificate.
    167 +	     * Note: clientCertChain should include the EE cert as
    168 +	     * clientCertificate is ignored during the actual sending
    169 +	     */
    170 +	    ss->ssl3.clientCertChain =
    171 +		    hack_NewCertificateListFromCertList(platform_cert_list);
    172 +	    CERT_DestroyCertList(platform_cert_list);
    173 +	    platform_cert_list = NULL;
    174 +	    if (ss->ssl3.clientCertChain == NULL) {
    175 +		if (ss->ssl3.clientCertificate != NULL) {
    176 +		    CERT_DestroyCertificate(ss->ssl3.clientCertificate);
    177 +		    ss->ssl3.clientCertificate = NULL;
    178 +		}
    179 +		if (ss->ssl3.platformClientKey) {
    180 +		    ssl_FreePlatformKey(ss->ssl3.platformClientKey);
    181 +		    ss->ssl3.platformClientKey = (PlatformKey)NULL;
    182 +		}
    183 +		goto send_no_certificate;
    184 +	    }
    185 +	    if (ss->ssl3.hs.hashType == handshake_hash_single) {
    186 +		ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
    187 +	    }
    188 +	    break;  /* not an error */
    189 +	}
    190 +#endif   /* NSS_PLATFORM_CLIENT_AUTH */
    191          /* check what the callback function returned */
    192          if ((!ss->ssl3.clientCertificate) || (!ss->ssl3.clientPrivateKey)) {
    193              /* we are missing either the key or cert */
    194 @@ -7096,6 +7188,10 @@ loser:
    195  done:
    196      if (arena != NULL)
    197      	PORT_FreeArena(arena, PR_FALSE);
    198 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    199 +    if (platform_cert_list)
    200 +        CERT_DestroyCertList(platform_cert_list);
    201 +#endif
    202      return rv;
    203  }
    204  
    205 @@ -7213,7 +7309,8 @@ ssl3_SendClientSecondRound(sslSocket *ss
    206  
    207      sendClientCert = !ss->ssl3.sendEmptyCert &&
    208  		     ss->ssl3.clientCertChain  != NULL &&
    209 -		     ss->ssl3.clientPrivateKey != NULL;
    210 +		     (ss->ssl3.platformClientKey ||
    211 +		     ss->ssl3.clientPrivateKey != NULL);
    212  
    213      if (!sendClientCert &&
    214  	ss->ssl3.hs.hashType == handshake_hash_single &&
    215 @@ -12052,6 +12149,10 @@ ssl3_DestroySSL3Info(sslSocket *ss)
    216  
    217      if (ss->ssl3.clientPrivateKey != NULL)
    218  	SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
    219 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    220 +    if (ss->ssl3.platformClientKey)
    221 +	ssl_FreePlatformKey(ss->ssl3.platformClientKey);
    222 +#endif /* NSS_PLATFORM_CLIENT_AUTH */
    223  
    224      if (ss->ssl3.peerCertArena != NULL)
    225  	ssl3_CleanupPeerCerts(ss);
    226 diff -pu a/nss/lib/ssl/ssl3ext.c b/nss/lib/ssl/ssl3ext.c
    227 --- a/nss/lib/ssl/ssl3ext.c	2014-01-17 17:49:26.072517368 -0800
    228 +++ b/nss/lib/ssl/ssl3ext.c	2014-01-17 17:52:19.745405758 -0800
    229 @@ -10,8 +10,8 @@
    230  #include "nssrenam.h"
    231  #include "nss.h"
    232  #include "ssl.h"
    233 -#include "sslproto.h"
    234  #include "sslimpl.h"
    235 +#include "sslproto.h"
    236  #include "pk11pub.h"
    237  #ifdef NO_PKCS11_BYPASS
    238  #include "blapit.h"
    239 diff -pu a/nss/lib/ssl/sslauth.c b/nss/lib/ssl/sslauth.c
    240 --- a/nss/lib/ssl/sslauth.c	2014-01-17 17:49:26.072517368 -0800
    241 +++ b/nss/lib/ssl/sslauth.c	2014-01-17 17:52:19.755405924 -0800
    242 @@ -216,6 +216,28 @@ SSL_GetClientAuthDataHook(PRFileDesc *s,
    243      return SECSuccess;
    244  }
    245  
    246 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    247 +/* NEED LOCKS IN HERE.  */
    248 +SECStatus 
    249 +SSL_GetPlatformClientAuthDataHook(PRFileDesc *s,
    250 +                                  SSLGetPlatformClientAuthData func,
    251 +                                  void *arg)
    252 +{
    253 +    sslSocket *ss;
    254 +
    255 +    ss = ssl_FindSocket(s);
    256 +    if (!ss) {
    257 +	SSL_DBG(("%d: SSL[%d]: bad socket in GetPlatformClientAuthDataHook",
    258 +		 SSL_GETPID(), s));
    259 +	return SECFailure;
    260 +    }
    261 +
    262 +    ss->getPlatformClientAuthData = func;
    263 +    ss->getPlatformClientAuthDataArg = arg;
    264 +    return SECSuccess;
    265 +}
    266 +#endif   /* NSS_PLATFORM_CLIENT_AUTH */
    267 +
    268  /* NEED LOCKS IN HERE.  */
    269  SECStatus 
    270  SSL_SetPKCS11PinArg(PRFileDesc *s, void *arg)
    271 diff -pu a/nss/lib/ssl/ssl.h b/nss/lib/ssl/ssl.h
    272 --- a/nss/lib/ssl/ssl.h	2014-01-17 17:49:26.062517203 -0800
    273 +++ b/nss/lib/ssl/ssl.h	2014-01-17 17:52:19.755405924 -0800
    274 @@ -533,6 +533,48 @@ typedef SECStatus (PR_CALLBACK *SSLGetCl
    275  SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd, 
    276  			                       SSLGetClientAuthData f, void *a);
    277  
    278 +/*
    279 + * Prototype for SSL callback to get client auth data from the application,
    280 + * optionally using the underlying platform's cryptographic primitives.
    281 + * To use the platform cryptographic primitives, caNames and pRetCerts
    282 + * should be set.  To use NSS, pRetNSSCert and pRetNSSKey should be set.
    283 + * Returning SECFailure will cause the socket to send no client certificate.
    284 + *	arg - application passed argument
    285 + *	caNames - pointer to distinguished names of CAs that the server likes
    286 + *	pRetCerts - pointer to pointer to list of certs, with the first being
    287 + *		    the client cert, and any following being used for chain
    288 + *		    building
    289 + *	pRetKey - pointer to native key pointer, for return of key
    290 + *          - Windows: A pointer to a PCERT_KEY_CONTEXT that was allocated
    291 + *                     via PORT_Alloc(). Ownership of the PCERT_KEY_CONTEXT
    292 + *                     is transferred to NSS, which will free via
    293 + *                     PORT_Free().
    294 + *          - Mac OS X: A pointer to a SecKeyRef. Ownership is
    295 + *                      transferred to NSS, which will free via CFRelease().
    296 + *	pRetNSSCert - pointer to pointer to NSS cert, for return of cert.
    297 + *	pRetNSSKey - pointer to NSS key pointer, for return of key.
    298 + */
    299 +typedef SECStatus (PR_CALLBACK *SSLGetPlatformClientAuthData)(void *arg,
    300 +                                PRFileDesc *fd,
    301 +                                CERTDistNames *caNames,
    302 +                                CERTCertList **pRetCerts,/*return */
    303 +                                void **pRetKey,/* return */
    304 +                                CERTCertificate **pRetNSSCert,/*return */
    305 +                                SECKEYPrivateKey **pRetNSSKey);/* return */
    306 +
    307 +/*
    308 + * Set the client side callback for SSL to retrieve user's private key
    309 + * and certificate.
    310 + * Note: If a platform client auth callback is set, the callback configured by
    311 + * SSL_GetClientAuthDataHook, if any, will not be called.
    312 + *
    313 + *	fd - the file descriptor for the connection in question
    314 + *	f - the application's callback that delivers the key and cert
    315 + *	a - application specific data
    316 + */
    317 +SSL_IMPORT SECStatus
    318 +SSL_GetPlatformClientAuthDataHook(PRFileDesc *fd,
    319 +                                  SSLGetPlatformClientAuthData f, void *a);
    320  
    321  /*
    322  ** SNI extension processing callback function.
    323 diff -pu a/nss/lib/ssl/sslimpl.h b/nss/lib/ssl/sslimpl.h
    324 --- a/nss/lib/ssl/sslimpl.h	2014-01-17 17:52:00.295082288 -0800
    325 +++ b/nss/lib/ssl/sslimpl.h	2014-01-17 17:52:19.755405924 -0800
    326 @@ -20,6 +20,7 @@
    327  #include "sslerr.h"
    328  #include "ssl3prot.h"
    329  #include "hasht.h"
    330 +#include "keythi.h"
    331  #include "nssilock.h"
    332  #include "pkcs11t.h"
    333  #if defined(XP_UNIX) || defined(XP_BEOS)
    334 @@ -31,6 +32,15 @@
    335  
    336  #include "sslt.h" /* for some formerly private types, now public */
    337  
    338 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    339 +#if defined(XP_WIN32)
    340 +#include <windows.h>
    341 +#include <wincrypt.h>
    342 +#elif defined(XP_MACOSX)
    343 +#include <Security/Security.h>
    344 +#endif
    345 +#endif
    346 +
    347  /* to make some of these old enums public without namespace pollution,
    348  ** it was necessary to prepend ssl_ to the names.
    349  ** These #defines preserve compatibility with the old code here in libssl.
    350 @@ -441,6 +451,14 @@ struct sslGatherStr {
    351  #define GS_DATA		3
    352  #define GS_PAD		4
    353  
    354 +#if defined(NSS_PLATFORM_CLIENT_AUTH) && defined(XP_WIN32)
    355 +typedef PCERT_KEY_CONTEXT PlatformKey;
    356 +#elif defined(NSS_PLATFORM_CLIENT_AUTH) && defined(XP_MACOSX)
    357 +typedef SecKeyRef PlatformKey;
    358 +#else
    359 +typedef void *PlatformKey;
    360 +#endif
    361 +
    362  
    363  
    364  /*
    365 @@ -953,6 +971,10 @@ struct ssl3StateStr {
    366  
    367      CERTCertificate *    clientCertificate;  /* used by client */
    368      SECKEYPrivateKey *   clientPrivateKey;   /* used by client */
    369 +    /* platformClientKey is present even when NSS_PLATFORM_CLIENT_AUTH is not
    370 +     * defined in order to allow cleaner conditional code.
    371 +     * At most one of clientPrivateKey and platformClientKey may be set. */
    372 +    PlatformKey          platformClientKey;  /* used by client */
    373      CERTCertificateList *clientCertChain;    /* used by client */
    374      PRBool               sendEmptyCert;      /* used by client */
    375  
    376 @@ -1214,6 +1236,10 @@ const unsigned char *  preferredCipher;
    377      void                     *authCertificateArg;
    378      SSLGetClientAuthData      getClientAuthData;
    379      void                     *getClientAuthDataArg;
    380 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    381 +    SSLGetPlatformClientAuthData getPlatformClientAuthData;
    382 +    void                        *getPlatformClientAuthDataArg;
    383 +#endif  /* NSS_PLATFORM_CLIENT_AUTH */
    384      SSLSNISocketConfig        sniSocketConfig;
    385      void                     *sniSocketConfigArg;
    386      SSLBadCertHandler         handleBadCert;
    387 @@ -1852,6 +1878,26 @@ extern SECStatus ssl_InitSessionCacheLoc
    388  
    389  extern SECStatus ssl_FreeSessionCacheLocks(void);
    390  
    391 +/***************** platform client auth ****************/
    392 +
    393 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    394 +// Releases the platform key.
    395 +extern void ssl_FreePlatformKey(PlatformKey key);
    396 +
    397 +// Implement the client CertificateVerify message for SSL3/TLS1.0
    398 +extern SECStatus ssl3_PlatformSignHashes(SSL3Hashes *hash,
    399 +                                         PlatformKey key, SECItem *buf,
    400 +                                         PRBool isTLS, KeyType keyType);
    401 +
    402 +// Converts a CERTCertList* (A collection of CERTCertificates) into a
    403 +// CERTCertificateList* (A collection of SECItems), or returns NULL if
    404 +// it cannot be converted.
    405 +// This is to allow the platform-supplied chain to be created with purely
    406 +// public API functions, using the preferred CERTCertList mutators, rather
    407 +// pushing this hack to clients.
    408 +extern CERTCertificateList* hack_NewCertificateListFromCertList(
    409 +        CERTCertList* list);
    410 +#endif  /* NSS_PLATFORM_CLIENT_AUTH */
    411  
    412  /**************** DTLS-specific functions **************/
    413  extern void dtls_FreeQueuedMessage(DTLSQueuedMessage *msg);
    414 diff -pu a/nss/lib/ssl/sslsock.c b/nss/lib/ssl/sslsock.c
    415 --- a/nss/lib/ssl/sslsock.c	2014-01-17 17:49:40.942764689 -0800
    416 +++ b/nss/lib/ssl/sslsock.c	2014-01-17 17:52:19.755405924 -0800
    417 @@ -263,6 +263,10 @@ ssl_DupSocket(sslSocket *os)
    418  	    ss->authCertificateArg    = os->authCertificateArg;
    419  	    ss->getClientAuthData     = os->getClientAuthData;
    420  	    ss->getClientAuthDataArg  = os->getClientAuthDataArg;
    421 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    422 +	    ss->getPlatformClientAuthData    = os->getPlatformClientAuthData;
    423 +	    ss->getPlatformClientAuthDataArg = os->getPlatformClientAuthDataArg;
    424 +#endif
    425              ss->sniSocketConfig       = os->sniSocketConfig;
    426              ss->sniSocketConfigArg    = os->sniSocketConfigArg;
    427  	    ss->handleBadCert         = os->handleBadCert;
    428 @@ -1667,6 +1671,12 @@ SSL_ReconfigFD(PRFileDesc *model, PRFile
    429          ss->getClientAuthData     = sm->getClientAuthData;
    430      if (sm->getClientAuthDataArg)
    431          ss->getClientAuthDataArg  = sm->getClientAuthDataArg;
    432 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    433 +    if (sm->getPlatformClientAuthData)
    434 +        ss->getPlatformClientAuthData    = sm->getPlatformClientAuthData;
    435 +    if (sm->getPlatformClientAuthDataArg)
    436 +        ss->getPlatformClientAuthDataArg = sm->getPlatformClientAuthDataArg;
    437 +#endif
    438      if (sm->sniSocketConfig)
    439          ss->sniSocketConfig       = sm->sniSocketConfig;
    440      if (sm->sniSocketConfigArg)
    441 @@ -2921,6 +2931,10 @@ ssl_NewSocket(PRBool makeLocks, SSLProto
    442          ss->sniSocketConfig    = NULL;
    443          ss->sniSocketConfigArg = NULL;
    444  	ss->getClientAuthData  = NULL;
    445 +#ifdef NSS_PLATFORM_CLIENT_AUTH
    446 +	ss->getPlatformClientAuthData = NULL;
    447 +	ss->getPlatformClientAuthDataArg = NULL;
    448 +#endif   /* NSS_PLATFORM_CLIENT_AUTH */
    449  	ss->handleBadCert      = NULL;
    450  	ss->badCertArg         = NULL;
    451  	ss->pkcs11PinArg       = NULL;
    452