Add explicit |forceOnlineSignin| to user pod status
[chromium-blink-merge.git] / net / third_party / nss / patches / clientauth.patch
blobf6bc0709dfa241f596ec81a5e4165bea90d9c8e7
1 diff -pu a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c
2 --- a/nss/lib/ssl/ssl3con.c 2014-01-03 19:30:40.073373382 -0800
3 +++ b/nss/lib/ssl/ssl3con.c 2014-01-03 19:30:52.653579045 -0800
4 @@ -2471,6 +2471,9 @@ ssl3_ClientAuthTokenPresent(sslSessionID
5 PRBool isPresent = PR_TRUE;
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;
14 @@ -6080,25 +6083,36 @@ ssl3_SendCertificateVerify(sslSocket *ss
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;
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;
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 */
68 @@ -6177,6 +6191,12 @@ ssl3_HandleServerHello(sslSocket *ss, SS
69 SECKEY_DestroyPrivateKey(ss->ssl3.clientPrivateKey);
70 ss->ssl3.clientPrivateKey = NULL;
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 */
79 temp = ssl3_ConsumeHandshakeNumber(ss, 2, &b, &length);
80 if (temp < 0) {
81 @@ -6804,6 +6824,18 @@ ssl3_ExtractClientKeyInfo(sslSocket *ss,
82 goto done;
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 */
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 @@ -6902,6 +6934,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 */
109 SSL_TRC(3, ("%d: SSL3[%d]: handle certificate_request handshake",
110 SSL_GETPID(), ss->fd));
111 @@ -6918,6 +6954,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);
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 @@ -6997,6 +7034,18 @@ ssl3_HandleCertificateRequest(sslSocket
120 desc = no_certificate;
121 ss->ssl3.hs.ws = wait_hello_done;
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 @@ -7006,12 +7055,55 @@ ssl3_HandleCertificateRequest(sslSocket
139 } else {
140 rv = SECFailure; /* force it to send a no_certificate alert */
143 switch (rv) {
144 case SECWouldBlock: /* getClientAuthData has put up a dialog box. */
145 ssl3_SetAlwaysBlock(ss);
146 break; /* not an error */
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;
156 + if (ss->ssl3.platformClientKey) {
157 + ssl_FreePlatformKey(ss->ssl3.platformClientKey);
158 + ss->ssl3.platformClientKey = (PlatformKey)NULL;
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);
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;
179 + if (ss->ssl3.platformClientKey) {
180 + ssl_FreePlatformKey(ss->ssl3.platformClientKey);
181 + ss->ssl3.platformClientKey = (PlatformKey)NULL;
183 + goto send_no_certificate;
185 + if (ss->ssl3.hs.hashType == handshake_hash_single) {
186 + ssl3_DestroyBackupHandshakeHashIfNotNeeded(ss, &algorithms);
188 + break; /* not an error */
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 @@ -7073,6 +7165,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;
205 @@ -7190,7 +7286,8 @@ ssl3_SendClientSecondRound(sslSocket *ss
207 sendClientCert = !ss->ssl3.sendEmptyCert &&
208 ss->ssl3.clientCertChain != NULL &&
209 - ss->ssl3.clientPrivateKey != NULL;
210 + (ss->ssl3.platformClientKey ||
211 + ss->ssl3.clientPrivateKey != NULL);
213 if (!sendClientCert &&
214 ss->ssl3.hs.hashType == handshake_hash_single &&
215 @@ -12027,6 +12124,10 @@ ssl3_DestroySSL3Info(sslSocket *ss)
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 */
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-03 19:28:03.550814608 -0800
228 +++ b/nss/lib/ssl/ssl3ext.c 2014-01-03 19:30:52.653579045 -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-03 19:28:03.550814608 -0800
241 +++ b/nss/lib/ssl/sslauth.c 2014-01-03 19:30:52.653579045 -0800
242 @@ -216,6 +216,28 @@ SSL_GetClientAuthDataHook(PRFileDesc *s,
243 return SECSuccess;
246 +#ifdef NSS_PLATFORM_CLIENT_AUTH
247 +/* NEED LOCKS IN HERE. */
248 +SECStatus
249 +SSL_GetPlatformClientAuthDataHook(PRFileDesc *s,
250 + SSLGetPlatformClientAuthData func,
251 + void *arg)
253 + sslSocket *ss;
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;
262 + ss->getPlatformClientAuthData = func;
263 + ss->getPlatformClientAuthDataArg = arg;
264 + return SECSuccess;
266 +#endif /* NSS_PLATFORM_CLIENT_AUTH */
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-03 19:28:03.540814444 -0800
273 +++ b/nss/lib/ssl/ssl.h 2014-01-03 19:30:52.653579045 -0800
274 @@ -503,6 +503,48 @@ typedef SECStatus (PR_CALLBACK *SSLGetCl
275 SSL_IMPORT SECStatus SSL_GetClientAuthDataHook(PRFileDesc *fd,
276 SSLGetClientAuthData f, void *a);
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 */
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.
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);
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-03 19:30:40.073373382 -0800
325 +++ b/nss/lib/ssl/sslimpl.h 2014-01-03 19:30:52.653579045 -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 @@
336 #include "sslt.h" /* for some formerly private types, now public */
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
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 @@ -432,6 +442,14 @@ struct sslGatherStr {
351 #define GS_DATA 3
352 #define GS_PAD 4
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
365 @@ -944,6 +962,10 @@ struct ssl3StateStr {
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 */
376 @@ -1205,6 +1227,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 @@ -1843,6 +1869,26 @@ extern SECStatus ssl_InitSessionCacheLoc
389 extern SECStatus ssl_FreeSessionCacheLocks(void);
391 +/***************** platform client auth ****************/
393 +#ifdef NSS_PLATFORM_CLIENT_AUTH
394 +// Releases the platform key.
395 +extern void ssl_FreePlatformKey(PlatformKey key);
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);
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 */
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-03 19:28:03.560814773 -0800
416 +++ b/nss/lib/ssl/sslsock.c 2014-01-03 19:30:52.653579045 -0800
417 @@ -261,6 +261,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 @@ -1645,6 +1649,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 @@ -2899,6 +2909,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;