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