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