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