1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * SSL server certificate configuration functions.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8
9 #include "ssl.h"
10 #include "sslimpl.h"
11 #include "secoid.h" /* for SECOID_GetAlgorithmTag */
12 #include "pk11func.h" /* for PK11_ReferenceSlot */
13 #include "nss.h" /* for NSS_RegisterShutdown */
14 #include "prinit.h" /* for PR_CallOnceWithArg */
15 #include "tls13subcerts.h" /* for tls13_ReadDelegatedCredential */
16
17 /* This global item is used only in servers. It is is initialized by
18 * SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().
19 */
20 static struct {
21 PRCallOnceType setup;
22 CERTDistNames *names;
23 } ssl_server_ca_list;
24
25 static SECStatus
ssl_ServerCAListShutdown(void * appData,void * nssData)26 ssl_ServerCAListShutdown(void *appData, void *nssData)
27 {
28 PORT_Assert(ssl_server_ca_list.names);
29 if (ssl_server_ca_list.names) {
30 CERT_FreeDistNames(ssl_server_ca_list.names);
31 }
32 PORT_Memset(&ssl_server_ca_list, 0, sizeof(ssl_server_ca_list));
33 return SECSuccess;
34 }
35
36 static PRStatus
ssl_SetupCAListOnce(void * arg)37 ssl_SetupCAListOnce(void *arg)
38 {
39 CERTCertDBHandle *dbHandle = (CERTCertDBHandle *)arg;
40 SECStatus rv = NSS_RegisterShutdown(ssl_ServerCAListShutdown, NULL);
41 PORT_Assert(SECSuccess == rv);
42 if (SECSuccess == rv) {
43 ssl_server_ca_list.names = CERT_GetSSLCACerts(dbHandle);
44 return PR_SUCCESS;
45 }
46 return PR_FAILURE;
47 }
48
49 SECStatus
ssl_SetupCAList(const sslSocket * ss)50 ssl_SetupCAList(const sslSocket *ss)
51 {
52 if (PR_SUCCESS != PR_CallOnceWithArg(&ssl_server_ca_list.setup,
53 &ssl_SetupCAListOnce,
54 (void *)(ss->dbHandle))) {
55 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
56 return SECFailure;
57 }
58 return SECSuccess;
59 }
60
61 SECStatus
ssl_GetCertificateRequestCAs(const sslSocket * ss,unsigned int * calen,const SECItem ** names,unsigned int * nnames)62 ssl_GetCertificateRequestCAs(const sslSocket *ss, unsigned int *calen,
63 const SECItem **names, unsigned int *nnames)
64 {
65 const SECItem *name;
66 const CERTDistNames *ca_list;
67 unsigned int i;
68
69 *calen = 0;
70 *names = NULL;
71 *nnames = 0;
72
73 /* ssl3.ca_list is initialized to NULL, and never changed. */
74 ca_list = ss->ssl3.ca_list;
75 if (!ca_list) {
76 if (ssl_SetupCAList(ss) != SECSuccess) {
77 return SECFailure;
78 }
79 ca_list = ssl_server_ca_list.names;
80 }
81
82 if (ca_list != NULL) {
83 *names = ca_list->names;
84 *nnames = ca_list->nnames;
85 }
86
87 for (i = 0, name = *names; i < *nnames; i++, name++) {
88 *calen += 2 + name->len;
89 }
90 return SECSuccess;
91 }
92
93 sslServerCert *
ssl_NewServerCert()94 ssl_NewServerCert()
95 {
96 sslServerCert *sc = PORT_ZNew(sslServerCert);
97 if (!sc) {
98 return NULL;
99 }
100 sc->authTypes = 0;
101 sc->namedCurve = NULL;
102 sc->serverCert = NULL;
103 sc->serverCertChain = NULL;
104 sc->certStatusArray = NULL;
105 sc->signedCertTimestamps.len = 0;
106 sc->delegCred.len = 0;
107 sc->delegCredKeyPair = NULL;
108 return sc;
109 }
110
111 sslServerCert *
ssl_CopyServerCert(const sslServerCert * oc)112 ssl_CopyServerCert(const sslServerCert *oc)
113 {
114 sslServerCert *sc;
115
116 sc = ssl_NewServerCert();
117 if (!sc) {
118 return NULL;
119 }
120
121 sc->authTypes = oc->authTypes;
122 sc->namedCurve = oc->namedCurve;
123
124 if (oc->serverCert && oc->serverCertChain) {
125 sc->serverCert = CERT_DupCertificate(oc->serverCert);
126 if (!sc->serverCert)
127 goto loser;
128 sc->serverCertChain = CERT_DupCertList(oc->serverCertChain);
129 if (!sc->serverCertChain)
130 goto loser;
131 } else {
132 sc->serverCert = NULL;
133 sc->serverCertChain = NULL;
134 }
135
136 if (oc->serverKeyPair) {
137 sc->serverKeyPair = ssl_GetKeyPairRef(oc->serverKeyPair);
138 if (!sc->serverKeyPair)
139 goto loser;
140 } else {
141 sc->serverKeyPair = NULL;
142 }
143 sc->serverKeyBits = oc->serverKeyBits;
144
145 if (oc->certStatusArray) {
146 sc->certStatusArray = SECITEM_DupArray(NULL, oc->certStatusArray);
147 if (!sc->certStatusArray)
148 goto loser;
149 } else {
150 sc->certStatusArray = NULL;
151 }
152
153 if (SECITEM_CopyItem(NULL, &sc->signedCertTimestamps,
154 &oc->signedCertTimestamps) != SECSuccess) {
155 goto loser;
156 }
157
158 if (SECITEM_CopyItem(NULL, &sc->delegCred, &oc->delegCred) != SECSuccess) {
159 goto loser;
160 }
161 if (oc->delegCredKeyPair) {
162 sc->delegCredKeyPair = ssl_GetKeyPairRef(oc->delegCredKeyPair);
163 }
164
165 return sc;
166 loser:
167 ssl_FreeServerCert(sc);
168 return NULL;
169 }
170
171 void
ssl_FreeServerCert(sslServerCert * sc)172 ssl_FreeServerCert(sslServerCert *sc)
173 {
174 if (!sc) {
175 return;
176 }
177
178 if (sc->serverCert) {
179 CERT_DestroyCertificate(sc->serverCert);
180 }
181 if (sc->serverCertChain) {
182 CERT_DestroyCertificateList(sc->serverCertChain);
183 }
184 if (sc->serverKeyPair) {
185 ssl_FreeKeyPair(sc->serverKeyPair);
186 }
187 if (sc->certStatusArray) {
188 SECITEM_FreeArray(sc->certStatusArray, PR_TRUE);
189 }
190 if (sc->signedCertTimestamps.len) {
191 SECITEM_FreeItem(&sc->signedCertTimestamps, PR_FALSE);
192 }
193 if (sc->delegCred.len) {
194 SECITEM_FreeItem(&sc->delegCred, PR_FALSE);
195 }
196 if (sc->delegCredKeyPair) {
197 ssl_FreeKeyPair(sc->delegCredKeyPair);
198 }
199 PORT_ZFree(sc, sizeof(*sc));
200 }
201
202 const sslServerCert *
ssl_FindServerCert(const sslSocket * ss,SSLAuthType authType,const sslNamedGroupDef * namedCurve)203 ssl_FindServerCert(const sslSocket *ss, SSLAuthType authType,
204 const sslNamedGroupDef *namedCurve)
205 {
206 PRCList *cursor;
207
208 /* Bug 1749475: avoid UB while fuzzing session tickets */
209 if ((unsigned)authType >= ssl_auth_size) {
210 return NULL;
211 }
212
213 for (cursor = PR_NEXT_LINK(&ss->serverCerts);
214 cursor != &ss->serverCerts;
215 cursor = PR_NEXT_LINK(cursor)) {
216 sslServerCert *cert = (sslServerCert *)cursor;
217 if (!SSL_CERT_IS(cert, authType)) {
218 continue;
219 }
220 if (SSL_CERT_IS_EC(cert)) {
221 /* Note: For deprecated APIs, we need to be able to find and
222 match a slot with any named curve. */
223 if (namedCurve && cert->namedCurve != namedCurve) {
224 continue;
225 }
226 }
227 return cert;
228 }
229 return NULL;
230 }
231
232 static SECStatus
ssl_PopulateServerCert(sslServerCert * sc,CERTCertificate * cert,const CERTCertificateList * certChain)233 ssl_PopulateServerCert(sslServerCert *sc, CERTCertificate *cert,
234 const CERTCertificateList *certChain)
235 {
236 if (sc->serverCert) {
237 CERT_DestroyCertificate(sc->serverCert);
238 }
239 if (sc->serverCertChain) {
240 CERT_DestroyCertificateList(sc->serverCertChain);
241 }
242
243 if (!cert) {
244 sc->serverCert = NULL;
245 sc->serverCertChain = NULL;
246 return SECSuccess;
247 }
248
249 sc->serverCert = CERT_DupCertificate(cert);
250 if (certChain) {
251 sc->serverCertChain = CERT_DupCertList(certChain);
252 } else {
253 sc->serverCertChain =
254 CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer,
255 PR_TRUE);
256 }
257 return sc->serverCertChain ? SECSuccess : SECFailure;
258 }
259
260 static SECStatus
ssl_PopulateKeyPair(sslServerCert * sc,sslKeyPair * keyPair)261 ssl_PopulateKeyPair(sslServerCert *sc, sslKeyPair *keyPair)
262 {
263 if (sc->serverKeyPair) {
264 ssl_FreeKeyPair(sc->serverKeyPair);
265 sc->serverKeyPair = NULL;
266 }
267 if (keyPair) {
268 KeyType keyType = SECKEY_GetPublicKeyType(keyPair->pubKey);
269 PORT_Assert(keyType == SECKEY_GetPrivateKeyType(keyPair->privKey));
270
271 if (keyType == ecKey) {
272 sc->namedCurve = ssl_ECPubKey2NamedGroup(keyPair->pubKey);
273 if (!sc->namedCurve) {
274 /* Unsupported curve. */
275 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
276 return SECFailure;
277 }
278 }
279
280 /* Get the size of the cert's public key, and remember it. */
281 sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey);
282 if (sc->serverKeyBits == 0 ||
283 (keyType == rsaKey && sc->serverKeyBits > SSL_MAX_RSA_KEY_BITS)) {
284 PORT_SetError(SEC_ERROR_INVALID_ARGS);
285 return SECFailure;
286 }
287
288 SECKEY_CacheStaticFlags(keyPair->privKey);
289 sc->serverKeyPair = ssl_GetKeyPairRef(keyPair);
290
291 if (SSL_CERT_IS(sc, ssl_auth_rsa_decrypt)) {
292 /* This will update the global session ticket key pair with this
293 * key, if a value hasn't been set already. */
294 if (ssl_MaybeSetSelfEncryptKeyPair(keyPair) != SECSuccess) {
295 return SECFailure;
296 }
297 }
298 } else {
299 sc->serverKeyPair = NULL;
300 sc->namedCurve = NULL;
301 }
302 return SECSuccess;
303 }
304
305 static SECStatus
ssl_PopulateOCSPResponses(sslServerCert * sc,const SECItemArray * stapledOCSPResponses)306 ssl_PopulateOCSPResponses(sslServerCert *sc,
307 const SECItemArray *stapledOCSPResponses)
308 {
309 if (sc->certStatusArray) {
310 SECITEM_FreeArray(sc->certStatusArray, PR_TRUE);
311 }
312 if (stapledOCSPResponses) {
313 sc->certStatusArray = SECITEM_DupArray(NULL, stapledOCSPResponses);
314 return sc->certStatusArray ? SECSuccess : SECFailure;
315 } else {
316 sc->certStatusArray = NULL;
317 }
318 return SECSuccess;
319 }
320
321 static SECStatus
ssl_PopulateSignedCertTimestamps(sslServerCert * sc,const SECItem * signedCertTimestamps)322 ssl_PopulateSignedCertTimestamps(sslServerCert *sc,
323 const SECItem *signedCertTimestamps)
324 {
325 if (sc->signedCertTimestamps.len) {
326 SECITEM_FreeItem(&sc->signedCertTimestamps, PR_FALSE);
327 }
328 if (signedCertTimestamps && signedCertTimestamps->len) {
329 return SECITEM_CopyItem(NULL, &sc->signedCertTimestamps,
330 signedCertTimestamps);
331 }
332 return SECSuccess;
333 }
334
335 /* Installs the given delegated credential (DC) and DC private key into the
336 * certificate.
337 *
338 * It's the caller's responsibility to ensure that the DC is well-formed and
339 * that the DC public key matches the DC private key.
340 */
341 static SECStatus
ssl_PopulateDelegatedCredential(sslServerCert * sc,const SECItem * delegCred,const SECKEYPrivateKey * delegCredPrivKey)342 ssl_PopulateDelegatedCredential(sslServerCert *sc,
343 const SECItem *delegCred,
344 const SECKEYPrivateKey *delegCredPrivKey)
345 {
346 sslDelegatedCredential *dc = NULL;
347
348 if (sc->delegCred.len) {
349 SECITEM_FreeItem(&sc->delegCred, PR_FALSE);
350 }
351
352 if (sc->delegCredKeyPair) {
353 ssl_FreeKeyPair(sc->delegCredKeyPair);
354 sc->delegCredKeyPair = NULL;
355 }
356
357 /* Both the DC and its private are present. */
358 if (delegCred && delegCredPrivKey) {
359 SECStatus rv;
360 SECKEYPublicKey *pub;
361 SECKEYPrivateKey *priv;
362
363 if (!delegCred->data || delegCred->len == 0) {
364 PORT_SetError(SEC_ERROR_INVALID_ARGS);
365 goto loser;
366 }
367
368 /* Parse the DC. */
369 rv = tls13_ReadDelegatedCredential(delegCred->data, delegCred->len, &dc);
370 if (rv != SECSuccess) {
371 goto loser;
372 }
373
374 /* Make a copy of the DC. */
375 rv = SECITEM_CopyItem(NULL, &sc->delegCred, delegCred);
376 if (rv != SECSuccess) {
377 goto loser;
378 }
379
380 /* Make a copy of the DC private key. */
381 priv = SECKEY_CopyPrivateKey(delegCredPrivKey);
382 if (!priv) {
383 goto loser;
384 }
385
386 /* parse public key from the DC. */
387 pub = SECKEY_ExtractPublicKey(dc->spki);
388 if (!pub) {
389 goto loser;
390 }
391
392 sc->delegCredKeyPair = ssl_NewKeyPair(priv, pub);
393
394 /* Attempting to configure either the DC or DC private key, but not both. */
395 } else if (delegCred || delegCredPrivKey) {
396 PORT_SetError(SEC_ERROR_INVALID_ARGS);
397 goto loser;
398 }
399
400 tls13_DestroyDelegatedCredential(dc);
401 return SECSuccess;
402
403 loser:
404 tls13_DestroyDelegatedCredential(dc);
405 return SECFailure;
406 }
407
408 /* Find any existing certificates that overlap with the new certificate and
409 * either remove any supported authentication types that overlap with the new
410 * certificate or - if they have no types left - remove them entirely. */
411 static void
ssl_ClearMatchingCerts(sslSocket * ss,sslAuthTypeMask authTypes,const sslNamedGroupDef * namedCurve)412 ssl_ClearMatchingCerts(sslSocket *ss, sslAuthTypeMask authTypes,
413 const sslNamedGroupDef *namedCurve)
414 {
415 PRCList *cursor = PR_NEXT_LINK(&ss->serverCerts);
416
417 while (cursor != &ss->serverCerts) {
418 sslServerCert *sc = (sslServerCert *)cursor;
419 cursor = PR_NEXT_LINK(cursor);
420 if ((sc->authTypes & authTypes) == 0) {
421 continue;
422 }
423 /* namedCurve will be NULL only for legacy functions. */
424 if (namedCurve != NULL && sc->namedCurve != namedCurve) {
425 continue;
426 }
427
428 sc->authTypes &= ~authTypes;
429 if (sc->authTypes == 0) {
430 PR_REMOVE_LINK(&sc->link);
431 ssl_FreeServerCert(sc);
432 }
433 }
434 }
435
436 static SECStatus
ssl_ConfigCert(sslSocket * ss,sslAuthTypeMask authTypes,CERTCertificate * cert,sslKeyPair * keyPair,const SSLExtraServerCertData * data)437 ssl_ConfigCert(sslSocket *ss, sslAuthTypeMask authTypes,
438 CERTCertificate *cert, sslKeyPair *keyPair,
439 const SSLExtraServerCertData *data)
440 {
441 SECStatus rv;
442 sslServerCert *sc = NULL;
443 int error_code = SEC_ERROR_NO_MEMORY;
444
445 PORT_Assert(cert);
446 PORT_Assert(keyPair);
447 PORT_Assert(data);
448 PORT_Assert(authTypes);
449
450 if (!cert || !keyPair || !data || !authTypes) {
451 error_code = SEC_ERROR_INVALID_ARGS;
452 goto loser;
453 }
454
455 sc = ssl_NewServerCert();
456 if (!sc) {
457 goto loser;
458 }
459
460 sc->authTypes = authTypes;
461 rv = ssl_PopulateServerCert(sc, cert, data->certChain);
462 if (rv != SECSuccess) {
463 goto loser;
464 }
465 rv = ssl_PopulateKeyPair(sc, keyPair);
466 if (rv != SECSuccess) {
467 error_code = PORT_GetError();
468 goto loser;
469 }
470 rv = ssl_PopulateOCSPResponses(sc, data->stapledOCSPResponses);
471 if (rv != SECSuccess) {
472 goto loser;
473 }
474 rv = ssl_PopulateSignedCertTimestamps(sc, data->signedCertTimestamps);
475 if (rv != SECSuccess) {
476 goto loser;
477 }
478 rv = ssl_PopulateDelegatedCredential(sc, data->delegCred,
479 data->delegCredPrivKey);
480 if (rv != SECSuccess) {
481 error_code = PORT_GetError();
482 goto loser;
483 }
484 ssl_ClearMatchingCerts(ss, sc->authTypes, sc->namedCurve);
485 PR_APPEND_LINK(&sc->link, &ss->serverCerts);
486 return SECSuccess;
487
488 loser:
489 ssl_FreeServerCert(sc);
490 PORT_SetError(error_code);
491 return SECFailure;
492 }
493
494 static SSLAuthType
ssl_GetEcdhAuthType(CERTCertificate * cert)495 ssl_GetEcdhAuthType(CERTCertificate *cert)
496 {
497 SECOidTag sigTag = SECOID_GetAlgorithmTag(&cert->signature);
498 switch (sigTag) {
499 case SEC_OID_PKCS1_RSA_ENCRYPTION:
500 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
501 case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
502 case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
503 case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
504 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
505 case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
506 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
507 case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
508 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
509 return ssl_auth_ecdh_rsa;
510 case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
511 case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
512 case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
513 case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
514 case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
515 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
516 case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
517 return ssl_auth_ecdh_ecdsa;
518 default:
519 return ssl_auth_null;
520 }
521 }
522
523 /* This function examines the type of certificate and its key usage and
524 * chooses which authTypes apply. For some certificates
525 * this can mean that multiple authTypes.
526 *
527 * If the targetAuthType is not ssl_auth_null, then only that type will be used.
528 * If that choice is invalid, then this function will fail. */
529 static sslAuthTypeMask
ssl_GetCertificateAuthTypes(CERTCertificate * cert,SSLAuthType targetAuthType)530 ssl_GetCertificateAuthTypes(CERTCertificate *cert, SSLAuthType targetAuthType)
531 {
532 sslAuthTypeMask authTypes = 0;
533 SECOidTag tag;
534
535 tag = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm);
536 switch (tag) {
537 case SEC_OID_X500_RSA_ENCRYPTION:
538 case SEC_OID_PKCS1_RSA_ENCRYPTION:
539 if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
540 authTypes |= 1 << ssl_auth_rsa_sign;
541 }
542
543 if (cert->keyUsage & KU_KEY_ENCIPHERMENT) {
544 /* If ku_sig=true we configure signature and encryption slots with the
545 * same cert. This is bad form, but there are enough dual-usage RSA
546 * certs that we can't really break by limiting this to one type. */
547 authTypes |= 1 << ssl_auth_rsa_decrypt;
548 }
549 break;
550
551 case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
552 if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
553 authTypes |= 1 << ssl_auth_rsa_pss;
554 }
555 break;
556
557 case SEC_OID_ANSIX9_DSA_SIGNATURE:
558 if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
559 authTypes |= 1 << ssl_auth_dsa;
560 }
561 break;
562
563 case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
564 if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
565 authTypes |= 1 << ssl_auth_ecdsa;
566 }
567 /* Again, bad form to have dual usage and we don't prevent it. */
568 if (cert->keyUsage & KU_KEY_ENCIPHERMENT) {
569 authTypes |= 1 << ssl_GetEcdhAuthType(cert);
570 }
571 break;
572
573 default:
574 break;
575 }
576
577 /* Check that we successfully picked an authType */
578 if (targetAuthType != ssl_auth_null) {
579 authTypes &= 1 << targetAuthType;
580 }
581 return authTypes;
582 }
583
584 /* This function adopts pubKey and destroys it if things go wrong. */
585 static sslKeyPair *
ssl_MakeKeyPairForCert(SECKEYPrivateKey * key,CERTCertificate * cert)586 ssl_MakeKeyPairForCert(SECKEYPrivateKey *key, CERTCertificate *cert)
587 {
588 sslKeyPair *keyPair = NULL;
589 SECKEYPublicKey *pubKey = NULL;
590 SECKEYPrivateKey *privKeyCopy = NULL;
591 PK11SlotInfo *bestSlot;
592
593 pubKey = CERT_ExtractPublicKey(cert);
594 if (!pubKey) {
595 PORT_SetError(SEC_ERROR_NO_MEMORY);
596 return NULL;
597 }
598
599 if (SECKEY_GetPublicKeyType(pubKey) != SECKEY_GetPrivateKeyType(key)) {
600 SECKEY_DestroyPublicKey(pubKey);
601 PORT_SetError(SEC_ERROR_INVALID_ARGS);
602 return NULL;
603 }
604
605 if (key->pkcs11Slot) {
606 bestSlot = PK11_ReferenceSlot(key->pkcs11Slot);
607 if (bestSlot) {
608 privKeyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
609 PK11_FreeSlot(bestSlot);
610 }
611 }
612 if (!privKeyCopy) {
613 CK_MECHANISM_TYPE keyMech = PK11_MapSignKeyType(key->keyType);
614 /* XXX Maybe should be bestSlotMultiple? */
615 bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */);
616 if (bestSlot) {
617 privKeyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
618 PK11_FreeSlot(bestSlot);
619 }
620 }
621 if (!privKeyCopy) {
622 privKeyCopy = SECKEY_CopyPrivateKey(key);
623 }
624 if (privKeyCopy) {
625 keyPair = ssl_NewKeyPair(privKeyCopy, pubKey);
626 }
627 if (!keyPair) {
628 if (privKeyCopy) {
629 SECKEY_DestroyPrivateKey(privKeyCopy);
630 }
631 SECKEY_DestroyPublicKey(pubKey);
632 PORT_SetError(SEC_ERROR_NO_MEMORY);
633 }
634 return keyPair;
635 }
636
637 /* Configure a certificate and private key.
638 *
639 * This function examines the certificate and key to determine the type (or
640 * types) of authentication the certificate supports. As long as certificates
641 * are different (different authTypes and maybe keys in different ec groups),
642 * then this function can be called multiple times.
643 */
644 SECStatus
SSL_ConfigServerCert(PRFileDesc * fd,CERTCertificate * cert,SECKEYPrivateKey * key,const SSLExtraServerCertData * data,unsigned int data_len)645 SSL_ConfigServerCert(PRFileDesc *fd, CERTCertificate *cert,
646 SECKEYPrivateKey *key,
647 const SSLExtraServerCertData *data, unsigned int data_len)
648 {
649 sslSocket *ss;
650 sslKeyPair *keyPair;
651 SECStatus rv;
652 SSLExtraServerCertData dataCopy = {
653 ssl_auth_null, NULL, NULL, NULL, NULL, NULL
654 };
655 sslAuthTypeMask authTypes;
656
657 ss = ssl_FindSocket(fd);
658 if (!ss) {
659 return SECFailure;
660 }
661
662 if (!cert || !key) {
663 PORT_SetError(SEC_ERROR_INVALID_ARGS);
664 return SECFailure;
665 }
666
667 if (data) {
668 if (data_len > sizeof(dataCopy)) {
669 PORT_SetError(SEC_ERROR_INVALID_ARGS);
670 return SECFailure;
671 }
672 PORT_Memcpy(&dataCopy, data, data_len);
673 }
674
675 authTypes = ssl_GetCertificateAuthTypes(cert, dataCopy.authType);
676 if (!authTypes) {
677 PORT_SetError(SEC_ERROR_INVALID_ARGS);
678 return SECFailure;
679 }
680
681 keyPair = ssl_MakeKeyPairForCert(key, cert);
682 if (!keyPair) {
683 return SECFailure;
684 }
685
686 rv = ssl_ConfigCert(ss, authTypes, cert, keyPair, &dataCopy);
687 ssl_FreeKeyPair(keyPair);
688 if (rv != SECSuccess) {
689 return SECFailure;
690 }
691 return SECSuccess;
692 }
693
694 /*******************************************************************/
695 /* Deprecated functions.
696 *
697 * The remainder of this file contains deprecated functions for server
698 * certificate configuration. These configure certificates incorrectly, but in
699 * a way that allows old code to continue working without change. All these
700 * functions create certificate slots based on SSLKEAType values. Some values
701 * of SSLKEAType cause multiple certificates to be configured.
702 */
703
704 SECStatus
SSL_ConfigSecureServer(PRFileDesc * fd,CERTCertificate * cert,SECKEYPrivateKey * key,SSLKEAType kea)705 SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert,
706 SECKEYPrivateKey *key, SSLKEAType kea)
707 {
708 return SSL_ConfigSecureServerWithCertChain(fd, cert, NULL, key, kea);
709 }
710
711 /* This implements a limited check that is consistent with the checks performed
712 * by older versions of NSS. This is less rigorous than the checks in
713 * ssl_ConfigCertByUsage(), only checking against the type of key and ignoring
714 * things like usage. */
715 static PRBool
ssl_CertSuitableForAuthType(CERTCertificate * cert,sslAuthTypeMask authTypes)716 ssl_CertSuitableForAuthType(CERTCertificate *cert, sslAuthTypeMask authTypes)
717 {
718 SECOidTag tag = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm);
719 sslAuthTypeMask mask = 0;
720 switch (tag) {
721 case SEC_OID_X500_RSA_ENCRYPTION:
722 case SEC_OID_PKCS1_RSA_ENCRYPTION:
723 mask |= 1 << ssl_auth_rsa_decrypt;
724 mask |= 1 << ssl_auth_rsa_sign;
725 break;
726 case SEC_OID_ANSIX9_DSA_SIGNATURE:
727 mask |= 1 << ssl_auth_dsa;
728 break;
729 case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
730 mask |= 1 << ssl_auth_ecdsa;
731 mask |= 1 << ssl_auth_ecdh_rsa;
732 mask |= 1 << ssl_auth_ecdh_ecdsa;
733 break;
734 default:
735 break;
736 }
737 PORT_Assert(authTypes);
738 /* Simply test that no inappropriate auth types are set. */
739 return (authTypes & ~mask) == 0;
740 }
741
742 /* Lookup a cert for the legacy configuration functions. An exact match on
743 * authTypes and ignoring namedCurve will ensure that values configured using
744 * legacy functions are overwritten by other legacy functions. */
745 static sslServerCert *
ssl_FindCertWithMask(sslSocket * ss,sslAuthTypeMask authTypes)746 ssl_FindCertWithMask(sslSocket *ss, sslAuthTypeMask authTypes)
747 {
748 PRCList *cursor;
749
750 for (cursor = PR_NEXT_LINK(&ss->serverCerts);
751 cursor != &ss->serverCerts;
752 cursor = PR_NEXT_LINK(cursor)) {
753 sslServerCert *cert = (sslServerCert *)cursor;
754 if (cert->authTypes == authTypes) {
755 return cert;
756 }
757 }
758 return NULL;
759 }
760
761 /* This finds an existing server cert in a matching slot that can be reused.
762 * Failing that, it removes any other certs that might conflict and makes a new
763 * server cert slot of the right type. */
764 static sslServerCert *
ssl_FindOrMakeCert(sslSocket * ss,sslAuthTypeMask authTypes)765 ssl_FindOrMakeCert(sslSocket *ss, sslAuthTypeMask authTypes)
766 {
767 sslServerCert *sc;
768
769 /* Reuse a perfect match. Note that there is a problem here with use of
770 * multiple EC certificates that have keys on different curves: these
771 * deprecated functions will match the first found and overwrite that
772 * certificate, potentially leaving the other values with a duplicate curve.
773 * Configuring multiple EC certificates are only possible with the new
774 * functions, so this is not something that is worth fixing. */
775 sc = ssl_FindCertWithMask(ss, authTypes);
776 if (sc) {
777 PR_REMOVE_LINK(&sc->link);
778 return sc;
779 }
780
781 /* Ignore the namedCurve parameter. Like above, this means that legacy
782 * functions will clobber values set with the new functions blindly. */
783 ssl_ClearMatchingCerts(ss, authTypes, NULL);
784
785 sc = ssl_NewServerCert();
786 if (sc) {
787 sc->authTypes = authTypes;
788 }
789 return sc;
790 }
791
792 static sslAuthTypeMask
ssl_KeaTypeToAuthTypeMask(SSLKEAType keaType)793 ssl_KeaTypeToAuthTypeMask(SSLKEAType keaType)
794 {
795 switch (keaType) {
796 case ssl_kea_rsa:
797 return (1 << ssl_auth_rsa_decrypt) |
798 (1 << ssl_auth_rsa_sign);
799
800 case ssl_kea_dh:
801 return 1 << ssl_auth_dsa;
802
803 case ssl_kea_ecdh:
804 return (1 << ssl_auth_ecdsa) |
805 (1 << ssl_auth_ecdh_rsa) |
806 (1 << ssl_auth_ecdh_ecdsa);
807
808 default:
809 PORT_SetError(SEC_ERROR_INVALID_ARGS);
810 }
811 return 0;
812 }
813
814 static SECStatus
ssl_AddCertChain(sslSocket * ss,CERTCertificate * cert,const CERTCertificateList * certChainOpt,SECKEYPrivateKey * key,sslAuthTypeMask authTypes)815 ssl_AddCertChain(sslSocket *ss, CERTCertificate *cert,
816 const CERTCertificateList *certChainOpt,
817 SECKEYPrivateKey *key, sslAuthTypeMask authTypes)
818 {
819 sslServerCert *sc;
820 sslKeyPair *keyPair;
821 SECStatus rv;
822 PRErrorCode err = SEC_ERROR_NO_MEMORY;
823
824 if (!ssl_CertSuitableForAuthType(cert, authTypes)) {
825 PORT_SetError(SEC_ERROR_INVALID_ARGS);
826 return SECFailure;
827 }
828
829 sc = ssl_FindOrMakeCert(ss, authTypes);
830 if (!sc) {
831 goto loser;
832 }
833
834 rv = ssl_PopulateServerCert(sc, cert, certChainOpt);
835 if (rv != SECSuccess) {
836 goto loser;
837 }
838
839 keyPair = ssl_MakeKeyPairForCert(key, cert);
840 if (!keyPair) {
841 /* Error code is set by ssl_MakeKeyPairForCert */
842 goto loser;
843 }
844 rv = ssl_PopulateKeyPair(sc, keyPair);
845 ssl_FreeKeyPair(keyPair);
846 if (rv != SECSuccess) {
847 err = PORT_GetError();
848 goto loser;
849 }
850
851 PR_APPEND_LINK(&sc->link, &ss->serverCerts);
852 return SECSuccess;
853
854 loser:
855 ssl_FreeServerCert(sc);
856 PORT_SetError(err);
857 return SECFailure;
858 }
859
860 /* Public deprecated function */
861 SECStatus
SSL_ConfigSecureServerWithCertChain(PRFileDesc * fd,CERTCertificate * cert,const CERTCertificateList * certChainOpt,SECKEYPrivateKey * key,SSLKEAType certType)862 SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
863 const CERTCertificateList *certChainOpt,
864 SECKEYPrivateKey *key, SSLKEAType certType)
865 {
866 sslSocket *ss;
867 sslAuthTypeMask authTypes;
868
869 ss = ssl_FindSocket(fd);
870 if (!ss) {
871 return SECFailure;
872 }
873
874 if (!cert != !key) { /* Configure both, or neither */
875 PORT_SetError(SEC_ERROR_INVALID_ARGS);
876 return SECFailure;
877 }
878
879 authTypes = ssl_KeaTypeToAuthTypeMask(certType);
880 if (!authTypes) {
881 PORT_SetError(SEC_ERROR_INVALID_ARGS);
882 return SECFailure;
883 }
884
885 if (!cert) {
886 sslServerCert *sc = ssl_FindCertWithMask(ss, authTypes);
887 if (sc) {
888 (void)ssl_PopulateServerCert(sc, NULL, NULL);
889 (void)ssl_PopulateKeyPair(sc, NULL);
890 /* Leave the entry linked here because the old API expects that.
891 * There might be OCSP stapling values or signed certificate
892 * timestamps still present that will subsequently be used. */
893 }
894 return SECSuccess;
895 }
896
897 return ssl_AddCertChain(ss, cert, certChainOpt, key, authTypes);
898 }
899
900 /* Public deprecated function */
901 SECStatus
SSL_SetStapledOCSPResponses(PRFileDesc * fd,const SECItemArray * responses,SSLKEAType certType)902 SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
903 SSLKEAType certType)
904 {
905 sslSocket *ss;
906 sslServerCert *sc;
907 sslAuthTypeMask authTypes;
908 SECStatus rv;
909
910 ss = ssl_FindSocket(fd);
911 if (!ss) {
912 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetStapledOCSPResponses",
913 SSL_GETPID(), fd));
914 return SECFailure;
915 }
916
917 authTypes = ssl_KeaTypeToAuthTypeMask(certType);
918 if (!authTypes) {
919 SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetStapledOCSPResponses",
920 SSL_GETPID(), fd));
921 PORT_SetError(SEC_ERROR_INVALID_ARGS);
922 return SECFailure;
923 }
924
925 if (!responses) {
926 sc = ssl_FindCertWithMask(ss, authTypes);
927 if (sc) {
928 (void)ssl_PopulateOCSPResponses(sc, NULL);
929 }
930 return SECSuccess;
931 }
932
933 sc = ssl_FindOrMakeCert(ss, authTypes);
934 if (!sc) {
935 return SECFailure;
936 }
937
938 rv = ssl_PopulateOCSPResponses(sc, responses);
939 if (rv == SECSuccess) {
940 PR_APPEND_LINK(&sc->link, &ss->serverCerts);
941 } else {
942 ssl_FreeServerCert(sc);
943 }
944 return rv;
945 }
946
947 /* Public deprecated function */
948 SECStatus
SSL_SetSignedCertTimestamps(PRFileDesc * fd,const SECItem * scts,SSLKEAType certType)949 SSL_SetSignedCertTimestamps(PRFileDesc *fd, const SECItem *scts,
950 SSLKEAType certType)
951 {
952 sslSocket *ss;
953 sslServerCert *sc;
954 sslAuthTypeMask authTypes;
955 SECStatus rv;
956
957 ss = ssl_FindSocket(fd);
958 if (!ss) {
959 SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSignedCertTimestamps",
960 SSL_GETPID(), fd));
961 return SECFailure;
962 }
963
964 authTypes = ssl_KeaTypeToAuthTypeMask(certType);
965 if (!authTypes) {
966 SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetSignedCertTimestamps",
967 SSL_GETPID(), fd));
968 PORT_SetError(SEC_ERROR_INVALID_ARGS);
969 return SECFailure;
970 }
971
972 if (!scts) {
973 sc = ssl_FindCertWithMask(ss, authTypes);
974 if (sc) {
975 (void)ssl_PopulateSignedCertTimestamps(sc, NULL);
976 }
977 return SECSuccess;
978 }
979
980 sc = ssl_FindOrMakeCert(ss, authTypes);
981 if (!sc) {
982 return SECFailure;
983 }
984
985 rv = ssl_PopulateSignedCertTimestamps(sc, scts);
986 if (rv == SECSuccess) {
987 PR_APPEND_LINK(&sc->link, &ss->serverCerts);
988 } else {
989 ssl_FreeServerCert(sc);
990 }
991 return rv;
992 }
993
994 /* Public deprecated function. */
995 SSLKEAType
NSS_FindCertKEAType(CERTCertificate * cert)996 NSS_FindCertKEAType(CERTCertificate *cert)
997 {
998 int tag;
999
1000 if (!cert)
1001 return ssl_kea_null;
1002
1003 tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
1004 switch (tag) {
1005 case SEC_OID_X500_RSA_ENCRYPTION:
1006 case SEC_OID_PKCS1_RSA_ENCRYPTION:
1007 return ssl_kea_rsa;
1008 case SEC_OID_ANSIX9_DSA_SIGNATURE: /* hah, signature, not a key? */
1009 case SEC_OID_X942_DIFFIE_HELMAN_KEY:
1010 return ssl_kea_dh;
1011 case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
1012 return ssl_kea_ecdh;
1013 default:
1014 return ssl_kea_null;
1015 }
1016 }
1017