/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * SSL server certificate configuration functions.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "ssl.h"
#include "sslimpl.h"
#include "secoid.h"   /* for SECOID_GetAlgorithmTag */
#include "pk11func.h" /* for PK11_ReferenceSlot */
#include "nss.h"      /* for NSS_RegisterShutdown */
#include "prinit.h"   /* for PR_CallOnceWithArg */

/* This global item is used only in servers.  It is is initialized by
 * SSL_ConfigSecureServer(), and is used in ssl3_SendCertificateRequest().
 */
static struct {
    PRCallOnceType setup;
    CERTDistNames *names;
} ssl_server_ca_list;

static SECStatus
ssl_ServerCAListShutdown(void *appData, void *nssData)
{
    PORT_Assert(ssl_server_ca_list.names);
    if (ssl_server_ca_list.names) {
        CERT_FreeDistNames(ssl_server_ca_list.names);
    }
    PORT_Memset(&ssl_server_ca_list, 0, sizeof(ssl_server_ca_list));
    return SECSuccess;
}

static PRStatus
ssl_SetupCAListOnce(void *arg)
{
    CERTCertDBHandle *dbHandle = (CERTCertDBHandle *)arg;
    SECStatus rv = NSS_RegisterShutdown(ssl_ServerCAListShutdown, NULL);
    PORT_Assert(SECSuccess == rv);
    if (SECSuccess == rv) {
        ssl_server_ca_list.names = CERT_GetSSLCACerts(dbHandle);
        return PR_SUCCESS;
    }
    return PR_FAILURE;
}

SECStatus
ssl_SetupCAList(const sslSocket *ss)
{
    if (PR_SUCCESS != PR_CallOnceWithArg(&ssl_server_ca_list.setup,
                                         &ssl_SetupCAListOnce,
                                         (void *)(ss->dbHandle))) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    return SECSuccess;
}

SECStatus
ssl_GetCertificateRequestCAs(const sslSocket *ss, unsigned int *calen,
                             const SECItem **names, unsigned int *nnames)
{
    const SECItem *name;
    const CERTDistNames *ca_list;
    unsigned int i;

    *calen = 0;
    *names = NULL;
    *nnames = 0;

    /* ssl3.ca_list is initialized to NULL, and never changed. */
    ca_list = ss->ssl3.ca_list;
    if (!ca_list) {
        if (ssl_SetupCAList(ss) != SECSuccess) {
            return SECFailure;
        }
        ca_list = ssl_server_ca_list.names;
    }

    if (ca_list != NULL) {
        *names = ca_list->names;
        *nnames = ca_list->nnames;
    }

    for (i = 0, name = *names; i < *nnames; i++, name++) {
        *calen += 2 + name->len;
    }
    return SECSuccess;
}

sslServerCert *
ssl_NewServerCert()
{
    sslServerCert *sc = PORT_ZNew(sslServerCert);
    if (!sc) {
        return NULL;
    }
    sc->authTypes = 0;
    sc->namedCurve = NULL;
    sc->serverCert = NULL;
    sc->serverCertChain = NULL;
    sc->certStatusArray = NULL;
    sc->signedCertTimestamps.len = 0;
    return sc;
}

sslServerCert *
ssl_CopyServerCert(const sslServerCert *oc)
{
    sslServerCert *sc;

    sc = ssl_NewServerCert();
    if (!sc) {
        return NULL;
    }

    sc->authTypes = oc->authTypes;
    sc->namedCurve = oc->namedCurve;

    if (oc->serverCert && oc->serverCertChain) {
        sc->serverCert = CERT_DupCertificate(oc->serverCert);
        if (!sc->serverCert)
            goto loser;
        sc->serverCertChain = CERT_DupCertList(oc->serverCertChain);
        if (!sc->serverCertChain)
            goto loser;
    } else {
        sc->serverCert = NULL;
        sc->serverCertChain = NULL;
    }

    if (oc->serverKeyPair) {
        sc->serverKeyPair = ssl_GetKeyPairRef(oc->serverKeyPair);
        if (!sc->serverKeyPair)
            goto loser;
    } else {
        sc->serverKeyPair = NULL;
    }
    sc->serverKeyBits = oc->serverKeyBits;

    if (oc->certStatusArray) {
        sc->certStatusArray = SECITEM_DupArray(NULL, oc->certStatusArray);
        if (!sc->certStatusArray)
            goto loser;
    } else {
        sc->certStatusArray = NULL;
    }

    if (SECITEM_CopyItem(NULL, &sc->signedCertTimestamps,
                         &oc->signedCertTimestamps) != SECSuccess)
        goto loser;
    return sc;
loser:
    ssl_FreeServerCert(sc);
    return NULL;
}

void
ssl_FreeServerCert(sslServerCert *sc)
{
    if (!sc) {
        return;
    }

    if (sc->serverCert) {
        CERT_DestroyCertificate(sc->serverCert);
    }
    if (sc->serverCertChain) {
        CERT_DestroyCertificateList(sc->serverCertChain);
    }
    if (sc->serverKeyPair) {
        ssl_FreeKeyPair(sc->serverKeyPair);
    }
    if (sc->certStatusArray) {
        SECITEM_FreeArray(sc->certStatusArray, PR_TRUE);
    }
    if (sc->signedCertTimestamps.len) {
        SECITEM_FreeItem(&sc->signedCertTimestamps, PR_FALSE);
    }
    PORT_ZFree(sc, sizeof(*sc));
}

const sslServerCert *
ssl_FindServerCert(const sslSocket *ss, SSLAuthType authType,
                   const sslNamedGroupDef *namedCurve)
{
    PRCList *cursor;

    for (cursor = PR_NEXT_LINK(&ss->serverCerts);
         cursor != &ss->serverCerts;
         cursor = PR_NEXT_LINK(cursor)) {
        sslServerCert *cert = (sslServerCert *)cursor;
        if (!SSL_CERT_IS(cert, authType)) {
            continue;
        }
        if (SSL_CERT_IS_EC(cert)) {
            /* Note: For deprecated APIs, we need to be able to find and
               match a slot with any named curve. */
            if (namedCurve && cert->namedCurve != namedCurve) {
                continue;
            }
        }
        return cert;
    }
    return NULL;
}

static SECStatus
ssl_PopulateServerCert(sslServerCert *sc, CERTCertificate *cert,
                       const CERTCertificateList *certChain)
{
    if (sc->serverCert) {
        CERT_DestroyCertificate(sc->serverCert);
    }
    if (sc->serverCertChain) {
        CERT_DestroyCertificateList(sc->serverCertChain);
    }

    if (!cert) {
        sc->serverCert = NULL;
        sc->serverCertChain = NULL;
        return SECSuccess;
    }

    sc->serverCert = CERT_DupCertificate(cert);
    if (certChain) {
        sc->serverCertChain = CERT_DupCertList(certChain);
    } else {
        sc->serverCertChain =
            CERT_CertChainFromCert(sc->serverCert, certUsageSSLServer,
                                   PR_TRUE);
    }
    return sc->serverCertChain ? SECSuccess : SECFailure;
}

static SECStatus
ssl_PopulateKeyPair(sslServerCert *sc, sslKeyPair *keyPair)
{
    if (sc->serverKeyPair) {
        ssl_FreeKeyPair(sc->serverKeyPair);
        sc->serverKeyPair = NULL;
    }
    if (keyPair) {
        KeyType keyType = SECKEY_GetPublicKeyType(keyPair->pubKey);
        PORT_Assert(keyType == SECKEY_GetPrivateKeyType(keyPair->privKey));

        if (keyType == ecKey) {
            sc->namedCurve = ssl_ECPubKey2NamedGroup(keyPair->pubKey);
            if (!sc->namedCurve) {
                /* Unsupported curve. */
                PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
                return SECFailure;
            }
        }

        /* Get the size of the cert's public key, and remember it. */
        sc->serverKeyBits = SECKEY_PublicKeyStrengthInBits(keyPair->pubKey);
        if (sc->serverKeyBits == 0 ||
            (keyType == rsaKey && sc->serverKeyBits > SSL_MAX_RSA_KEY_BITS)) {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return SECFailure;
        }

        SECKEY_CacheStaticFlags(keyPair->privKey);
        sc->serverKeyPair = ssl_GetKeyPairRef(keyPair);

        if (SSL_CERT_IS(sc, ssl_auth_rsa_decrypt)) {
            /* This will update the global session ticket key pair with this
             * key, if a value hasn't been set already. */
            if (ssl_MaybeSetSelfEncryptKeyPair(keyPair) != SECSuccess) {
                return SECFailure;
            }
        }
    } else {
        sc->serverKeyPair = NULL;
        sc->namedCurve = NULL;
    }
    return SECSuccess;
}

static SECStatus
ssl_PopulateOCSPResponses(sslServerCert *sc,
                          const SECItemArray *stapledOCSPResponses)
{
    if (sc->certStatusArray) {
        SECITEM_FreeArray(sc->certStatusArray, PR_TRUE);
    }
    if (stapledOCSPResponses) {
        sc->certStatusArray = SECITEM_DupArray(NULL, stapledOCSPResponses);
        return sc->certStatusArray ? SECSuccess : SECFailure;
    } else {
        sc->certStatusArray = NULL;
    }
    return SECSuccess;
}

static SECStatus
ssl_PopulateSignedCertTimestamps(sslServerCert *sc,
                                 const SECItem *signedCertTimestamps)
{
    if (sc->signedCertTimestamps.len) {
        SECITEM_FreeItem(&sc->signedCertTimestamps, PR_FALSE);
    }
    if (signedCertTimestamps && signedCertTimestamps->len) {
        return SECITEM_CopyItem(NULL, &sc->signedCertTimestamps,
                                signedCertTimestamps);
    }
    return SECSuccess;
}

/* Find any existing certificates that overlap with the new certificate and
 * either remove any supported authentication types that overlap with the new
 * certificate or - if they have no types left - remove them entirely. */
static void
ssl_ClearMatchingCerts(sslSocket *ss, sslAuthTypeMask authTypes,
                       const sslNamedGroupDef *namedCurve)
{
    PRCList *cursor = PR_NEXT_LINK(&ss->serverCerts);

    while (cursor != &ss->serverCerts) {
        sslServerCert *sc = (sslServerCert *)cursor;
        cursor = PR_NEXT_LINK(cursor);
        if ((sc->authTypes & authTypes) == 0) {
            continue;
        }
        /* namedCurve will be NULL only for legacy functions. */
        if (namedCurve != NULL && sc->namedCurve != namedCurve) {
            continue;
        }

        sc->authTypes &= ~authTypes;
        if (sc->authTypes == 0) {
            PR_REMOVE_LINK(&sc->link);
            ssl_FreeServerCert(sc);
        }
    }
}

static SECStatus
ssl_ConfigCert(sslSocket *ss, sslAuthTypeMask authTypes,
               CERTCertificate *cert, sslKeyPair *keyPair,
               const SSLExtraServerCertData *data)
{
    SECStatus rv;
    sslServerCert *sc = NULL;
    int error_code = SEC_ERROR_NO_MEMORY;

    PORT_Assert(cert);
    PORT_Assert(keyPair);
    PORT_Assert(data);
    PORT_Assert(authTypes);

    if (!cert || !keyPair || !data || !authTypes) {
        error_code = SEC_ERROR_INVALID_ARGS;
        goto loser;
    }

    sc = ssl_NewServerCert();
    if (!sc) {
        goto loser;
    }

    sc->authTypes = authTypes;
    rv = ssl_PopulateServerCert(sc, cert, data->certChain);
    if (rv != SECSuccess) {
        goto loser;
    }
    rv = ssl_PopulateKeyPair(sc, keyPair);
    if (rv != SECSuccess) {
        error_code = PORT_GetError();
        goto loser;
    }
    rv = ssl_PopulateOCSPResponses(sc, data->stapledOCSPResponses);
    if (rv != SECSuccess) {
        goto loser;
    }
    rv = ssl_PopulateSignedCertTimestamps(sc, data->signedCertTimestamps);
    if (rv != SECSuccess) {
        goto loser;
    }
    ssl_ClearMatchingCerts(ss, sc->authTypes, sc->namedCurve);
    PR_APPEND_LINK(&sc->link, &ss->serverCerts);
    return SECSuccess;

loser:
    ssl_FreeServerCert(sc);
    PORT_SetError(error_code);
    return SECFailure;
}

static SSLAuthType
ssl_GetEcdhAuthType(CERTCertificate *cert)
{
    SECOidTag sigTag = SECOID_GetAlgorithmTag(&cert->signature);
    switch (sigTag) {
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
        case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
            return ssl_auth_ecdh_rsa;
        case SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE:
        case SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE:
        case SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE:
        case SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE:
        case SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE:
        case SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST:
        case SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST:
            return ssl_auth_ecdh_ecdsa;
        default:
            return ssl_auth_null;
    }
}

/* This function examines the type of certificate and its key usage and
 * chooses which authTypes apply.  For some certificates
 * this can mean that multiple authTypes.
 *
 * If the targetAuthType is not ssl_auth_null, then only that type will be used.
 * If that choice is invalid, then this function will fail. */
static sslAuthTypeMask
ssl_GetCertificateAuthTypes(CERTCertificate *cert, SSLAuthType targetAuthType)
{
    sslAuthTypeMask authTypes = 0;
    SECOidTag tag;

    tag = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm);
    switch (tag) {
        case SEC_OID_X500_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
            if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
                authTypes |= 1 << ssl_auth_rsa_sign;
            }

            if (cert->keyUsage & KU_KEY_ENCIPHERMENT) {
                /* If ku_sig=true we configure signature and encryption slots with the
                 * same cert. This is bad form, but there are enough dual-usage RSA
                 * certs that we can't really break by limiting this to one type. */
                authTypes |= 1 << ssl_auth_rsa_decrypt;
            }
            break;

        case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
            if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
                authTypes |= 1 << ssl_auth_rsa_pss;
            }
            break;

        case SEC_OID_ANSIX9_DSA_SIGNATURE:
            if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
                authTypes |= 1 << ssl_auth_dsa;
            }
            break;

        case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
            if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
                authTypes |= 1 << ssl_auth_ecdsa;
            }
            /* Again, bad form to have dual usage and we don't prevent it. */
            if (cert->keyUsage & KU_KEY_ENCIPHERMENT) {
                authTypes |= 1 << ssl_GetEcdhAuthType(cert);
            }
            break;

        default:
            break;
    }

    /* Check that we successfully picked an authType */
    if (targetAuthType != ssl_auth_null) {
        authTypes &= 1 << targetAuthType;
    }
    return authTypes;
}

/* This function adopts pubKey and destroys it if things go wrong. */
static sslKeyPair *
ssl_MakeKeyPairForCert(SECKEYPrivateKey *key, CERTCertificate *cert)
{
    sslKeyPair *keyPair = NULL;
    SECKEYPublicKey *pubKey = NULL;
    SECKEYPrivateKey *privKeyCopy = NULL;
    PK11SlotInfo *bestSlot;

    pubKey = CERT_ExtractPublicKey(cert);
    if (!pubKey) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    if (SECKEY_GetPublicKeyType(pubKey) != SECKEY_GetPrivateKeyType(key)) {
        SECKEY_DestroyPublicKey(pubKey);
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    if (key->pkcs11Slot) {
        bestSlot = PK11_ReferenceSlot(key->pkcs11Slot);
        if (bestSlot) {
            privKeyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
            PK11_FreeSlot(bestSlot);
        }
    }
    if (!privKeyCopy) {
        CK_MECHANISM_TYPE keyMech = PK11_MapSignKeyType(key->keyType);
        /* XXX Maybe should be bestSlotMultiple? */
        bestSlot = PK11_GetBestSlot(keyMech, NULL /* wincx */);
        if (bestSlot) {
            privKeyCopy = PK11_CopyTokenPrivKeyToSessionPrivKey(bestSlot, key);
            PK11_FreeSlot(bestSlot);
        }
    }
    if (!privKeyCopy) {
        privKeyCopy = SECKEY_CopyPrivateKey(key);
    }
    if (privKeyCopy) {
        keyPair = ssl_NewKeyPair(privKeyCopy, pubKey);
    }
    if (!keyPair) {
        if (privKeyCopy) {
            SECKEY_DestroyPrivateKey(privKeyCopy);
        }
        SECKEY_DestroyPublicKey(pubKey);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
    }
    return keyPair;
}

/* Configure a certificate and private key.
 *
 * This function examines the certificate and key to determine the type (or
 * types) of authentication the certificate supports.  As long as certificates
 * are different (different authTypes and maybe keys in different ec groups),
 * then this function can be called multiple times.
 */
SECStatus
SSL_ConfigServerCert(PRFileDesc *fd, CERTCertificate *cert,
                     SECKEYPrivateKey *key,
                     const SSLExtraServerCertData *data, unsigned int data_len)
{
    sslSocket *ss;
    sslKeyPair *keyPair;
    SECStatus rv;
    SSLExtraServerCertData dataCopy = {
        ssl_auth_null, NULL, NULL, NULL
    };
    sslAuthTypeMask authTypes;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        return SECFailure;
    }

    if (!cert || !key) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (data) {
        if (data_len > sizeof(dataCopy)) {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            return SECFailure;
        }
        PORT_Memcpy(&dataCopy, data, data_len);
    }

    authTypes = ssl_GetCertificateAuthTypes(cert, dataCopy.authType);
    if (!authTypes) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    keyPair = ssl_MakeKeyPairForCert(key, cert);
    if (!keyPair) {
        return SECFailure;
    }

    rv = ssl_ConfigCert(ss, authTypes, cert, keyPair, &dataCopy);
    ssl_FreeKeyPair(keyPair);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    return SECSuccess;
}

/*******************************************************************/
/* Deprecated functions.
 *
 * The remainder of this file contains deprecated functions for server
 * certificate configuration.  These configure certificates incorrectly, but in
 * a way that allows old code to continue working without change.  All these
 * functions create certificate slots based on SSLKEAType values.  Some values
 * of SSLKEAType cause multiple certificates to be configured.
 */

SECStatus
SSL_ConfigSecureServer(PRFileDesc *fd, CERTCertificate *cert,
                       SECKEYPrivateKey *key, SSLKEAType kea)
{
    return SSL_ConfigSecureServerWithCertChain(fd, cert, NULL, key, kea);
}

/* This implements a limited check that is consistent with the checks performed
 * by older versions of NSS.  This is less rigorous than the checks in
 * ssl_ConfigCertByUsage(), only checking against the type of key and ignoring
 * things like usage. */
static PRBool
ssl_CertSuitableForAuthType(CERTCertificate *cert, sslAuthTypeMask authTypes)
{
    SECOidTag tag = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm);
    sslAuthTypeMask mask = 0;
    switch (tag) {
        case SEC_OID_X500_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
            mask |= 1 << ssl_auth_rsa_decrypt;
            mask |= 1 << ssl_auth_rsa_sign;
            break;
        case SEC_OID_ANSIX9_DSA_SIGNATURE:
            mask |= 1 << ssl_auth_dsa;
            break;
        case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
            mask |= 1 << ssl_auth_ecdsa;
            mask |= 1 << ssl_auth_ecdh_rsa;
            mask |= 1 << ssl_auth_ecdh_ecdsa;
            break;
        default:
            break;
    }
    PORT_Assert(authTypes);
    /* Simply test that no inappropriate auth types are set. */
    return (authTypes & ~mask) == 0;
}

/* Lookup a cert for the legacy configuration functions.  An exact match on
 * authTypes and ignoring namedCurve will ensure that values configured using
 * legacy functions are overwritten by other legacy functions. */
static sslServerCert *
ssl_FindCertWithMask(sslSocket *ss, sslAuthTypeMask authTypes)
{
    PRCList *cursor;

    for (cursor = PR_NEXT_LINK(&ss->serverCerts);
         cursor != &ss->serverCerts;
         cursor = PR_NEXT_LINK(cursor)) {
        sslServerCert *cert = (sslServerCert *)cursor;
        if (cert->authTypes == authTypes) {
            return cert;
        }
    }
    return NULL;
}

/* This finds an existing server cert in a matching slot that can be reused.
 * Failing that, it removes any other certs that might conflict and makes a new
 * server cert slot of the right type. */
static sslServerCert *
ssl_FindOrMakeCert(sslSocket *ss, sslAuthTypeMask authTypes)
{
    sslServerCert *sc;

    /* Reuse a perfect match.  Note that there is a problem here with use of
     * multiple EC certificates that have keys on different curves: these
     * deprecated functions will match the first found and overwrite that
     * certificate, potentially leaving the other values with a duplicate curve.
     * Configuring multiple EC certificates are only possible with the new
     * functions, so this is not something that is worth fixing.  */
    sc = ssl_FindCertWithMask(ss, authTypes);
    if (sc) {
        PR_REMOVE_LINK(&sc->link);
        return sc;
    }

    /* Ignore the namedCurve parameter. Like above, this means that legacy
     * functions will clobber values set with the new functions blindly. */
    ssl_ClearMatchingCerts(ss, authTypes, NULL);

    sc = ssl_NewServerCert();
    if (sc) {
        sc->authTypes = authTypes;
    }
    return sc;
}

static sslAuthTypeMask
ssl_KeaTypeToAuthTypeMask(SSLKEAType keaType)
{
    switch (keaType) {
        case ssl_kea_rsa:
            return (1 << ssl_auth_rsa_decrypt) |
                   (1 << ssl_auth_rsa_sign);

        case ssl_kea_dh:
            return 1 << ssl_auth_dsa;

        case ssl_kea_ecdh:
            return (1 << ssl_auth_ecdsa) |
                   (1 << ssl_auth_ecdh_rsa) |
                   (1 << ssl_auth_ecdh_ecdsa);

        default:
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
    }
    return 0;
}

static SECStatus
ssl_AddCertChain(sslSocket *ss, CERTCertificate *cert,
                 const CERTCertificateList *certChainOpt,
                 SECKEYPrivateKey *key, sslAuthTypeMask authTypes)
{
    sslServerCert *sc;
    sslKeyPair *keyPair;
    SECStatus rv;
    PRErrorCode err = SEC_ERROR_NO_MEMORY;

    if (!ssl_CertSuitableForAuthType(cert, authTypes)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    sc = ssl_FindOrMakeCert(ss, authTypes);
    if (!sc) {
        goto loser;
    }

    rv = ssl_PopulateServerCert(sc, cert, certChainOpt);
    if (rv != SECSuccess) {
        goto loser;
    }

    keyPair = ssl_MakeKeyPairForCert(key, cert);
    if (!keyPair) {
        /* Error code is set by ssl_MakeKeyPairForCert */
        goto loser;
    }
    rv = ssl_PopulateKeyPair(sc, keyPair);
    ssl_FreeKeyPair(keyPair);
    if (rv != SECSuccess) {
        err = PORT_GetError();
        goto loser;
    }

    PR_APPEND_LINK(&sc->link, &ss->serverCerts);
    return SECSuccess;

loser:
    ssl_FreeServerCert(sc);
    PORT_SetError(err);
    return SECFailure;
}

/* Public deprecated function */
SECStatus
SSL_ConfigSecureServerWithCertChain(PRFileDesc *fd, CERTCertificate *cert,
                                    const CERTCertificateList *certChainOpt,
                                    SECKEYPrivateKey *key, SSLKEAType certType)
{
    sslSocket *ss;
    sslAuthTypeMask authTypes;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        return SECFailure;
    }

    if (!cert != !key) { /* Configure both, or neither */
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    authTypes = ssl_KeaTypeToAuthTypeMask(certType);
    if (!authTypes) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!cert) {
        sslServerCert *sc = ssl_FindCertWithMask(ss, authTypes);
        if (sc) {
            (void)ssl_PopulateServerCert(sc, NULL, NULL);
            (void)ssl_PopulateKeyPair(sc, NULL);
            /* Leave the entry linked here because the old API expects that.
             * There might be OCSP stapling values or signed certificate
             * timestamps still present that will subsequently be used. */
        }
        return SECSuccess;
    }

    return ssl_AddCertChain(ss, cert, certChainOpt, key, authTypes);
}

/* Public deprecated function */
SECStatus
SSL_SetStapledOCSPResponses(PRFileDesc *fd, const SECItemArray *responses,
                            SSLKEAType certType)
{
    sslSocket *ss;
    sslServerCert *sc;
    sslAuthTypeMask authTypes;
    SECStatus rv;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetStapledOCSPResponses",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    authTypes = ssl_KeaTypeToAuthTypeMask(certType);
    if (!authTypes) {
        SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetStapledOCSPResponses",
                 SSL_GETPID(), fd));
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!responses) {
        sc = ssl_FindCertWithMask(ss, authTypes);
        if (sc) {
            (void)ssl_PopulateOCSPResponses(sc, NULL);
        }
        return SECSuccess;
    }

    sc = ssl_FindOrMakeCert(ss, authTypes);
    if (!sc) {
        return SECFailure;
    }

    rv = ssl_PopulateOCSPResponses(sc, responses);
    if (rv == SECSuccess) {
        PR_APPEND_LINK(&sc->link, &ss->serverCerts);
    } else {
        ssl_FreeServerCert(sc);
    }
    return rv;
}

/* Public deprecated function */
SECStatus
SSL_SetSignedCertTimestamps(PRFileDesc *fd, const SECItem *scts,
                            SSLKEAType certType)
{
    sslSocket *ss;
    sslServerCert *sc;
    sslAuthTypeMask authTypes;
    SECStatus rv;

    ss = ssl_FindSocket(fd);
    if (!ss) {
        SSL_DBG(("%d: SSL[%d]: bad socket in SSL_SetSignedCertTimestamps",
                 SSL_GETPID(), fd));
        return SECFailure;
    }

    authTypes = ssl_KeaTypeToAuthTypeMask(certType);
    if (!authTypes) {
        SSL_DBG(("%d: SSL[%d]: invalid cert type in SSL_SetSignedCertTimestamps",
                 SSL_GETPID(), fd));
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (!scts) {
        sc = ssl_FindCertWithMask(ss, authTypes);
        if (sc) {
            (void)ssl_PopulateSignedCertTimestamps(sc, NULL);
        }
        return SECSuccess;
    }

    sc = ssl_FindOrMakeCert(ss, authTypes);
    if (!sc) {
        return SECFailure;
    }

    rv = ssl_PopulateSignedCertTimestamps(sc, scts);
    if (rv == SECSuccess) {
        PR_APPEND_LINK(&sc->link, &ss->serverCerts);
    } else {
        ssl_FreeServerCert(sc);
    }
    return rv;
}

/* Public deprecated function. */
SSLKEAType
NSS_FindCertKEAType(CERTCertificate *cert)
{
    int tag;

    if (!cert)
        return ssl_kea_null;

    tag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
    switch (tag) {
        case SEC_OID_X500_RSA_ENCRYPTION:
        case SEC_OID_PKCS1_RSA_ENCRYPTION:
            return ssl_kea_rsa;
        case SEC_OID_ANSIX9_DSA_SIGNATURE: /* hah, signature, not a key? */
        case SEC_OID_X942_DIFFIE_HELMAN_KEY:
            return ssl_kea_dh;
        case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
            return ssl_kea_ecdh;
        default:
            return ssl_kea_null;
    }
}
