/* 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/. */

/*
 * CMS signerInfo methods.
 */

#include "cmslocal.h"

#include "cert.h"
#include "keyhi.h"
#include "secasn1.h"
#include "secitem.h"
#include "secoid.h"
#include "pk11func.h"
#include "prtime.h"
#include "secerr.h"
#include "secder.h"
#include "cryptohi.h"

#include "smime.h"

/* =============================================================================
 * SIGNERINFO
 */
NSSCMSSignerInfo *
nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type,
                         CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey,
                         SECKEYPrivateKey *signingKey, SECOidTag digestalgtag);

NSSCMSSignerInfo *
NSS_CMSSignerInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, SECItem *subjKeyID,
                                      SECKEYPublicKey *pubKey,
                                      SECKEYPrivateKey *signingKey, SECOidTag digestalgtag)
{
    return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_SubjectKeyID, NULL,
                                    subjKeyID, pubKey, signingKey, digestalgtag);
}

NSSCMSSignerInfo *
NSS_CMSSignerInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag digestalgtag)
{
    return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_IssuerSN, cert, NULL,
                                    NULL, NULL, digestalgtag);
}

NSSCMSSignerInfo *
nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type,
                         CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey,
                         SECKEYPrivateKey *signingKey, SECOidTag digestalgtag)
{
    void *mark;
    NSSCMSSignerInfo *signerinfo;
    int version;
    PLArenaPool *poolp;
    SECStatus rv;

    poolp = cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

    signerinfo = (NSSCMSSignerInfo *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSSignerInfo));
    if (signerinfo == NULL) {
        PORT_ArenaRelease(poolp, mark);
        return NULL;
    }

    signerinfo->cmsg = cmsg;

    switch (type) {
        case NSSCMSSignerID_IssuerSN:
            signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_IssuerSN;
            if ((signerinfo->cert = CERT_DupCertificate(cert)) == NULL)
                goto loser;
            if ((signerinfo->signerIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert)) == NULL)
                goto loser;
            break;
        case NSSCMSSignerID_SubjectKeyID:
            signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_SubjectKeyID;
            PORT_Assert(subjKeyID);
            if (!subjKeyID)
                goto loser;

            signerinfo->signerIdentifier.id.subjectKeyID = PORT_ArenaNew(poolp, SECItem);
            rv = SECITEM_CopyItem(poolp, signerinfo->signerIdentifier.id.subjectKeyID,
                                  subjKeyID);
            if (rv != SECSuccess) {
                goto loser;
            }
            signerinfo->signingKey = SECKEY_CopyPrivateKey(signingKey);
            if (!signerinfo->signingKey)
                goto loser;
            signerinfo->pubKey = SECKEY_CopyPublicKey(pubKey);
            if (!signerinfo->pubKey)
                goto loser;
            break;
        default:
            goto loser;
    }

    /* set version right now */
    version = NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN;
    /* RFC2630 5.3 "version is the syntax version number. If the .... " */
    if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID)
        version = NSS_CMS_SIGNER_INFO_VERSION_SUBJKEY;
    (void)SEC_ASN1EncodeInteger(poolp, &(signerinfo->version), (long)version);

    if (SECOID_SetAlgorithmID(poolp, &signerinfo->digestAlg, digestalgtag, NULL) != SECSuccess)
        goto loser;

    PORT_ArenaUnmark(poolp, mark);
    return signerinfo;

loser:
    PORT_ArenaRelease(poolp, mark);
    return NULL;
}

/*
 * NSS_CMSSignerInfo_Destroy - destroy a SignerInfo data structure
 */
void
NSS_CMSSignerInfo_Destroy(NSSCMSSignerInfo *si)
{
    if (si->cert != NULL)
        CERT_DestroyCertificate(si->cert);

    if (si->certList != NULL)
        CERT_DestroyCertificateList(si->certList);

    /* XXX storage ??? */
}
static SECOidTag
NSS_CMSSignerInfo_GetSignatureAlgorithmOidTag(KeyType keyType,
                                              SECOidTag pubkAlgTag,
                                              SECOidTag signAlgTag)
{
    switch (keyType) {
        case rsaKey:
            return pubkAlgTag;
        case rsaPssKey:
        case dsaKey:
        case ecKey:
            return signAlgTag;
        default:
            return SEC_OID_UNKNOWN;
    }
}

/*
 * NSS_CMSSignerInfo_Sign - sign something
 *
 */
SECStatus
NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest,
                       SECItem *contentType)
{
    CERTCertificate *cert;
    SECKEYPrivateKey *privkey = NULL;
    SECOidTag digestalgtag;
    SECOidTag pubkAlgTag;
    SECOidTag signAlgTag;
    SECOidTag cmsSignAlgTag;
    SECItem signature = { 0 };
    SECStatus rv;
    PLArenaPool *poolp, *tmppoolp = NULL;
    SECAlgorithmID *algID, freeAlgID;
    CERTSubjectPublicKeyInfo *spki;

    PORT_Assert(digest != NULL);

    poolp = signerinfo->cmsg->poolp;

    switch (signerinfo->signerIdentifier.identifierType) {
        case NSSCMSSignerID_IssuerSN:
            cert = signerinfo->cert;

            privkey = PK11_FindKeyByAnyCert(cert, signerinfo->cmsg->pwfn_arg);
            if (privkey == NULL)
                goto loser;
            algID = &cert->subjectPublicKeyInfo.algorithm;
            break;
        case NSSCMSSignerID_SubjectKeyID:
            privkey = signerinfo->signingKey;
            signerinfo->signingKey = NULL;
            spki = SECKEY_CreateSubjectPublicKeyInfo(signerinfo->pubKey);
            SECKEY_DestroyPublicKey(signerinfo->pubKey);
            signerinfo->pubKey = NULL;
            SECOID_CopyAlgorithmID(NULL, &freeAlgID, &spki->algorithm);
            SECKEY_DestroySubjectPublicKeyInfo(spki);
            algID = &freeAlgID;
            break;
        default:
            goto loser;
    }
    digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
    /*
     * XXX I think there should be a cert-level interface for this,
     * so that I do not have to know about subjectPublicKeyInfo...
     */
    pubkAlgTag = SECOID_GetAlgorithmTag(algID);
    if (algID == &freeAlgID) {
        SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE);
    }

    signAlgTag = SEC_GetSignatureAlgorithmOidTag(SECKEY_GetPrivateKeyType(privkey),
                                                 digestalgtag);
    if (signAlgTag == SEC_OID_UNKNOWN) {
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
        goto loser;
    }

    cmsSignAlgTag = NSS_CMSSignerInfo_GetSignatureAlgorithmOidTag(
        SECKEY_GetPrivateKeyType(privkey), pubkAlgTag, signAlgTag);
    if (cmsSignAlgTag == SEC_OID_UNKNOWN) {
        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
        goto loser;
    }

    if (SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg),
                              cmsSignAlgTag, NULL) != SECSuccess)
        goto loser;

    if (signerinfo->authAttr != NULL) {
        SECItem encoded_attrs;

        /* find and fill in the message digest attribute. */
        rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr),
                                           SEC_OID_PKCS9_MESSAGE_DIGEST, digest, PR_FALSE);
        if (rv != SECSuccess)
            goto loser;

        if (contentType != NULL) {
            /* if the caller wants us to, find and fill in the content type attribute. */
            rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr),
                                               SEC_OID_PKCS9_CONTENT_TYPE, contentType, PR_FALSE);
            if (rv != SECSuccess)
                goto loser;
        }

        if ((tmppoolp = PORT_NewArena(1024)) == NULL) {
            PORT_SetError(SEC_ERROR_NO_MEMORY);
            goto loser;
        }

        /*
     * Before encoding, reorder the attributes so that when they
     * are encoded, they will be conforming DER, which is required
     * to have a specific order and that is what must be used for
     * the hash/signature.  We do this here, rather than building
     * it into EncodeAttributes, because we do not want to do
     * such reordering on incoming messages (which also uses
     * EncodeAttributes) or our old signatures (and other "broken"
     * implementations) will not verify.  So, we want to guarantee
     * that we send out good DER encodings of attributes, but not
     * to expect to receive them.
     */
        if (NSS_CMSAttributeArray_Reorder(signerinfo->authAttr) != SECSuccess)
            goto loser;

        encoded_attrs.data = NULL;
        encoded_attrs.len = 0;
        if (NSS_CMSAttributeArray_Encode(tmppoolp, &(signerinfo->authAttr),
                                         &encoded_attrs) == NULL)
            goto loser;

        rv = SEC_SignData(&signature, encoded_attrs.data, encoded_attrs.len,
                          privkey, signAlgTag);
        PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */
        tmppoolp = 0;
    } else {
        rv = SGN_Digest(privkey, digestalgtag, &signature, digest);
    }
    SECKEY_DestroyPrivateKey(privkey);
    privkey = NULL;

    if (rv != SECSuccess)
        goto loser;

    if (SECITEM_CopyItem(poolp, &(signerinfo->encDigest), &signature) != SECSuccess)
        goto loser;

    SECITEM_FreeItem(&signature, PR_FALSE);

    return SECSuccess;

loser:
    if (signature.len != 0)
        SECITEM_FreeItem(&signature, PR_FALSE);
    if (privkey)
        SECKEY_DestroyPrivateKey(privkey);
    if (tmppoolp)
        PORT_FreeArena(tmppoolp, PR_FALSE);
    return SECFailure;
}

SECStatus
NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb,
                                    SECCertUsage certusage)
{
    CERTCertificate *cert;
    PRTime stime;

    if ((cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb)) == NULL) {
        signerinfo->verificationStatus = NSSCMSVS_SigningCertNotFound;
        return SECFailure;
    }

    /*
     * Get and convert the signing time; if available, it will be used
     * both on the cert verification and for importing the sender
     * email profile.
     */
    if (NSS_CMSSignerInfo_GetSigningTime(signerinfo, &stime) != SECSuccess)
        stime = PR_Now(); /* not found or conversion failed, so check against now */

    /*
     * XXX  This uses the signing time, if available.  Additionally, we
     * might want to, if there is no signing time, get the message time
     * from the mail header itself, and use that.  That would require
     * a change to our interface though, and for S/MIME callers to pass
     * in a time (and for non-S/MIME callers to pass in nothing, or
     * maybe make them pass in the current time, always?).
     */
    if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, stime,
                        signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
        signerinfo->verificationStatus = NSSCMSVS_SigningCertNotTrusted;
        return SECFailure;
    }
    return SECSuccess;
}

/*
 * NSS_CMSSignerInfo_Verify - verify the signature of a single SignerInfo
 *
 * Just verifies the signature. The assumption is that verification of
 * the certificate is done already.
 */
SECStatus
NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
                         SECItem *digest,      /* may be NULL */
                         SECItem *contentType) /* may be NULL */
{
    SECKEYPublicKey *publickey = NULL;
    NSSCMSAttribute *attr;
    SECItem encoded_attrs;
    CERTCertificate *cert;
    NSSCMSVerificationStatus vs = NSSCMSVS_Unverified;
    PLArenaPool *poolp;
    SECOidTag digestalgtag;
    SECOidTag pubkAlgTag;
    SECOidTag digestalgtagCmp;
    SECOidTag sigAlgTag;

    if (signerinfo == NULL)
        return SECFailure;

    /* NSS_CMSSignerInfo_GetSigningCertificate will fail if 2nd parm is NULL
    ** and cert has not been verified
    */
    cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, NULL);
    if (cert == NULL) {
        vs = NSSCMSVS_SigningCertNotFound;
        goto loser;
    }

    if ((publickey = CERT_ExtractPublicKey(cert)) == NULL) {
        vs = NSSCMSVS_ProcessingError;
        goto loser;
    }

    digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
    pubkAlgTag = SECOID_GetAlgorithmTag(&(cert->subjectPublicKeyInfo.algorithm));
    sigAlgTag = SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg));
    if ((pubkAlgTag == SEC_OID_UNKNOWN) || (digestalgtag == SEC_OID_UNKNOWN) ||
        (sigAlgTag == SEC_OID_UNKNOWN)) {
        vs = NSSCMSVS_SignatureAlgorithmUnknown;
        goto loser;
    }

    if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {
        if (contentType) {
            /*
         * Check content type
         *
         * RFC2630 sez that if there are any authenticated attributes,
         * then there must be one for content type which matches the
         * content type of the content being signed, and there must
         * be one for message digest which matches our message digest.
         * So check these things first.
         */
            attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
                                                          SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE);
            if (attr == NULL) {
                vs = NSSCMSVS_MalformedSignature;
                goto loser;
            }

            if (NSS_CMSAttribute_CompareValue(attr, contentType) == PR_FALSE) {
                vs = NSSCMSVS_MalformedSignature;
                goto loser;
            }
        }

        /*
     * Check digest
     */
        attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
                                                      SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE);
        if (attr == NULL) {
            vs = NSSCMSVS_MalformedSignature;
            goto loser;
        }
        if (!digest ||
            NSS_CMSAttribute_CompareValue(attr, digest) == PR_FALSE) {
            vs = NSSCMSVS_DigestMismatch;
            goto loser;
        }

        if ((poolp = PORT_NewArena(1024)) == NULL) {
            vs = NSSCMSVS_ProcessingError;
            goto loser;
        }

        /*
     * Check signature
     *
     * The signature is based on a digest of the DER-encoded authenticated
     * attributes.  So, first we encode and then we digest/verify.
     * we trust the decoder to have the attributes in the right (sorted)
     * order
     */
        encoded_attrs.data = NULL;
        encoded_attrs.len = 0;

        if (NSS_CMSAttributeArray_Encode(poolp, &(signerinfo->authAttr),
                                         &encoded_attrs) == NULL ||
            encoded_attrs.data == NULL || encoded_attrs.len == 0) {
            PORT_FreeArena(poolp, PR_FALSE);
            vs = NSSCMSVS_ProcessingError;
            goto loser;
        }

        if (sigAlgTag == pubkAlgTag) {
            /* This is to handle cases in which signatureAlgorithm field
	     * specifies the public key algorithm rather than a signature
	     * algorithm. */
            vs = (VFY_VerifyDataDirect(encoded_attrs.data, encoded_attrs.len,
                                       publickey, &(signerinfo->encDigest), pubkAlgTag,
                                       digestalgtag, NULL, signerinfo->cmsg->pwfn_arg) != SECSuccess)
                     ? NSSCMSVS_BadSignature
                     : NSSCMSVS_GoodSignature;
        } else {
            if (VFY_VerifyDataWithAlgorithmID(encoded_attrs.data,
                                              encoded_attrs.len, publickey, &(signerinfo->encDigest),
                                              &(signerinfo->digestEncAlg), &digestalgtagCmp,
                                              signerinfo->cmsg->pwfn_arg) != SECSuccess) {
                vs = NSSCMSVS_BadSignature;
            } else if (digestalgtagCmp != digestalgtag) {
                PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
                vs = NSSCMSVS_BadSignature;
            } else {
                vs = NSSCMSVS_GoodSignature;
            }
        }

        PORT_FreeArena(poolp, PR_FALSE); /* awkward memory management :-( */

    } else {
        SECItem *sig;

        /* No authenticated attributes.
    ** The signature is based on the plain message digest.
    */
        sig = &(signerinfo->encDigest);
        if (sig->len == 0)
            goto loser;

        if (sigAlgTag == pubkAlgTag) {
            /* This is to handle cases in which signatureAlgorithm field
	     * specifies the public key algorithm rather than a signature
	     * algorithm. */
            vs = (!digest ||
                  VFY_VerifyDigestDirect(digest, publickey, sig, pubkAlgTag,
                                         digestalgtag, signerinfo->cmsg->pwfn_arg) != SECSuccess)
                     ? NSSCMSVS_BadSignature
                     : NSSCMSVS_GoodSignature;
        } else {
            vs = (!digest ||
                  VFY_VerifyDigestWithAlgorithmID(digest, publickey, sig,
                                                  &(signerinfo->digestEncAlg), digestalgtag,
                                                  signerinfo->cmsg->pwfn_arg) != SECSuccess)
                     ? NSSCMSVS_BadSignature
                     : NSSCMSVS_GoodSignature;
        }
    }

    if (vs == NSSCMSVS_BadSignature) {
        int error = PORT_GetError();
        /*
     * XXX Change the generic error into our specific one, because
     * in that case we get a better explanation out of the Security
     * Advisor.  This is really a bug in the PSM error strings (the
     * "generic" error has a lousy/wrong message associated with it
     * which assumes the signature verification was done for the
     * purposes of checking the issuer signature on a certificate)
     * but this is at least an easy workaround and/or in the
     * Security Advisor, which specifically checks for the error
     * SEC_ERROR_PKCS7_BAD_SIGNATURE and gives more explanation
     * in that case but does not similarly check for
     * SEC_ERROR_BAD_SIGNATURE.  It probably should, but then would
     * probably say the wrong thing in the case that it *was* the
     * certificate signature check that failed during the cert
     * verification done above.  Our error handling is really a mess.
     */
        if (error == SEC_ERROR_BAD_SIGNATURE)
            PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
        /*
     * map algorithm failures to NSSCMSVS values
     */
        if ((error == SEC_ERROR_PKCS7_KEYALG_MISMATCH) ||
            (error == SEC_ERROR_INVALID_ALGORITHM)) {
            /* keep the same error code as 3.11 and before */
            PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
            vs = NSSCMSVS_SignatureAlgorithmUnsupported;
        }
    }

    if (publickey != NULL)
        SECKEY_DestroyPublicKey(publickey);

    signerinfo->verificationStatus = vs;

    return (vs == NSSCMSVS_GoodSignature) ? SECSuccess : SECFailure;

loser:
    if (publickey != NULL)
        SECKEY_DestroyPublicKey(publickey);

    signerinfo->verificationStatus = vs;

    PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
    return SECFailure;
}

NSSCMSVerificationStatus
NSS_CMSSignerInfo_GetVerificationStatus(NSSCMSSignerInfo *signerinfo)
{
    return signerinfo->verificationStatus;
}

SECOidData *
NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo)
{
    SECOidData *algdata;
    SECOidTag algtag;

    algdata = SECOID_FindOID(&(signerinfo->digestAlg.algorithm));
    if (algdata == NULL) {
        return algdata;
    }
    /* Windows may have given us a signer algorithm oid instead of a digest
     * algorithm oid. This call will map to a signer oid to a digest one,
     * otherwise it leaves the oid alone and let the chips fall as they may
     * if it's not a digest oid.
     */
    algtag = NSS_CMSUtil_MapSignAlgs(algdata->offset);
    if (algtag != algdata->offset) {
        /* if the tags don't match, then we must have received a signer
     * algorithID. Now we need to get the oid data for the digest
     * oid, which the rest of the code is expecting */
        algdata = SECOID_FindOIDByTag(algtag);
    }

    return algdata;
}

SECOidTag
NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo)
{
    SECOidData *algdata;

    if (!signerinfo) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SEC_OID_UNKNOWN;
    }

    algdata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
    if (algdata != NULL)
        return algdata->offset;
    else
        return SEC_OID_UNKNOWN;
}

CERTCertificateList *
NSS_CMSSignerInfo_GetCertList(NSSCMSSignerInfo *signerinfo)
{
    return signerinfo->certList;
}

int
NSS_CMSSignerInfo_GetVersion(NSSCMSSignerInfo *signerinfo)
{
    unsigned long version;

    /* always take apart the SECItem */
    if (SEC_ASN1DecodeInteger(&(signerinfo->version), &version) != SECSuccess)
        return 0;
    else
        return (int)version;
}

/*
 * NSS_CMSSignerInfo_GetSigningTime - return the signing time,
 *                    in UTCTime or GeneralizedTime format,
 *                                    of a CMS signerInfo.
 *
 * sinfo - signerInfo data for this signer
 *
 * Returns a pointer to XXXX (what?)
 * A return value of NULL is an error.
 */
SECStatus
NSS_CMSSignerInfo_GetSigningTime(NSSCMSSignerInfo *sinfo, PRTime *stime)
{
    NSSCMSAttribute *attr;
    SECItem *value;

    if (sinfo == NULL)
        return SECFailure;

    if (sinfo->signingTime != 0) {
        *stime = sinfo->signingTime; /* cached copy */
        return SECSuccess;
    }

    attr = NSS_CMSAttributeArray_FindAttrByOidTag(sinfo->authAttr,
                                                  SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE);
    /* XXXX multi-valued attributes NIH */
    if (attr == NULL || (value = NSS_CMSAttribute_GetValue(attr)) == NULL)
        return SECFailure;
    if (DER_DecodeTimeChoice(stime, value) != SECSuccess)
        return SECFailure;
    sinfo->signingTime = *stime; /* make cached copy */
    return SECSuccess;
}

/*
 * Return the signing cert of a CMS signerInfo.
 *
 * the certs in the enclosing SignedData must have been imported already
 */
CERTCertificate *
NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb)
{
    CERTCertificate *cert;
    NSSCMSSignerIdentifier *sid;

    if (signerinfo->cert != NULL)
        return signerinfo->cert;

    /* no certdb, and cert hasn't been set yet? */
    if (certdb == NULL)
        return NULL;

    /*
     * This cert will also need to be freed, but since we save it
     * in signerinfo for later, we do not want to destroy it when
     * we leave this function -- we let the clean-up of the entire
     * cinfo structure later do the destroy of this cert.
     */
    sid = &signerinfo->signerIdentifier;
    switch (sid->identifierType) {
        case NSSCMSSignerID_IssuerSN:
            cert = CERT_FindCertByIssuerAndSN(certdb, sid->id.issuerAndSN);
            break;
        case NSSCMSSignerID_SubjectKeyID:
            cert = CERT_FindCertBySubjectKeyID(certdb, sid->id.subjectKeyID);
            break;
        default:
            cert = NULL;
            break;
    }

    /* cert can be NULL at that point */
    signerinfo->cert = cert; /* earmark it */

    return cert;
}

/*
 * NSS_CMSSignerInfo_GetSignerCommonName - return the common name of the signer
 *
 * sinfo - signerInfo data for this signer
 *
 * Returns a pointer to allocated memory, which must be freed with PORT_Free.
 * A return value of NULL is an error.
 */
char *
NSS_CMSSignerInfo_GetSignerCommonName(NSSCMSSignerInfo *sinfo)
{
    CERTCertificate *signercert;

    /* will fail if cert is not verified */
    if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
        return NULL;

    return (CERT_GetCommonName(&signercert->subject));
}

/*
 * NSS_CMSSignerInfo_GetSignerEmailAddress - return the common name of the signer
 *
 * sinfo - signerInfo data for this signer
 *
 * Returns a pointer to allocated memory, which must be freed.
 * A return value of NULL is an error.
 */
char *
NSS_CMSSignerInfo_GetSignerEmailAddress(NSSCMSSignerInfo *sinfo)
{
    CERTCertificate *signercert;

    if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
        return NULL;

    if (!signercert->emailAddr || !signercert->emailAddr[0])
        return NULL;

    return (PORT_Strdup(signercert->emailAddr));
}

/*
 * NSS_CMSSignerInfo_AddAuthAttr - add an attribute to the
 * authenticated (i.e. signed) attributes of "signerinfo".
 */
SECStatus
NSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
{
    return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->authAttr), attr);
}

/*
 * NSS_CMSSignerInfo_AddUnauthAttr - add an attribute to the
 * unauthenticated attributes of "signerinfo".
 */
SECStatus
NSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
{
    return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->unAuthAttr), attr);
}

/*
 * NSS_CMSSignerInfo_AddSigningTime - add the signing time to the
 * authenticated (i.e. signed) attributes of "signerinfo".
 *
 * This is expected to be included in outgoing signed
 * messages for email (S/MIME) but is likely useful in other situations.
 *
 * This should only be added once; a second call will do nothing.
 *
 * XXX This will probably just shove the current time into "signerinfo"
 * but it will not actually get signed until the entire item is
 * processed for encoding.  Is this (expected to be small) delay okay?
 */
SECStatus
NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t)
{
    NSSCMSAttribute *attr;
    SECItem stime;
    void *mark;
    PLArenaPool *poolp;

    poolp = signerinfo->cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

    /* create new signing time attribute */
    if (DER_EncodeTimeChoice(NULL, &stime, t) != SECSuccess)
        goto loser;

    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SIGNING_TIME, &stime, PR_FALSE)) == NULL) {
        SECITEM_FreeItem(&stime, PR_FALSE);
        goto loser;
    }

    SECITEM_FreeItem(&stime, PR_FALSE);

    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
        goto loser;

    PORT_ArenaUnmark(poolp, mark);

    return SECSuccess;

loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

/*
 * NSS_CMSSignerInfo_AddSMIMECaps - add a SMIMECapabilities attribute to the
 * authenticated (i.e. signed) attributes of "signerinfo".
 *
 * This is expected to be included in outgoing signed
 * messages for email (S/MIME).
 */
SECStatus
NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo)
{
    NSSCMSAttribute *attr;
    SECItem *smimecaps = NULL;
    void *mark;
    PLArenaPool *poolp;

    poolp = signerinfo->cmsg->poolp;

    mark = PORT_ArenaMark(poolp);

    smimecaps = SECITEM_AllocItem(poolp, NULL, 0);
    if (smimecaps == NULL)
        goto loser;

    /* create new signing time attribute */
    if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps) != SECSuccess)
        goto loser;

    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL)
        goto loser;

    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
        goto loser;

    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

/*
 * NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
 * authenticated (i.e. signed) attributes of "signerinfo".
 *
 * This is expected to be included in outgoing signed messages for email (S/MIME).
 */
SECStatus
NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb)
{
    NSSCMSAttribute *attr;
    SECItem *smimeekp = NULL;
    void *mark;
    PLArenaPool *poolp;

    /* verify this cert for encryption */
    if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
        return SECFailure;
    }

    poolp = signerinfo->cmsg->poolp;
    mark = PORT_ArenaMark(poolp);

    smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
    if (smimeekp == NULL)
        goto loser;

    /* create new signing time attribute */
    if (NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
        goto loser;

    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
        goto loser;

    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
        goto loser;

    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

/*
 * NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
 * authenticated (i.e. signed) attributes of "signerinfo", using the OID preferred by Microsoft.
 *
 * This is expected to be included in outgoing signed messages for email (S/MIME),
 * if compatibility with Microsoft mail clients is wanted.
 */
SECStatus
NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb)
{
    NSSCMSAttribute *attr;
    SECItem *smimeekp = NULL;
    void *mark;
    PLArenaPool *poolp;

    /* verify this cert for encryption */
    if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
        return SECFailure;
    }

    poolp = signerinfo->cmsg->poolp;
    mark = PORT_ArenaMark(poolp);

    smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
    if (smimeekp == NULL)
        goto loser;

    /* create new signing time attribute */
    if (NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
        goto loser;

    if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
        goto loser;

    if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
        goto loser;

    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;

loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

/*
 * NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo
 *
 * 1. digest the DER-encoded signature value of the original signerinfo
 * 2. create new signerinfo with correct version, sid, digestAlg
 * 3. add message-digest authAttr, but NO content-type
 * 4. sign the authAttrs
 * 5. DER-encode the new signerInfo
 * 6. add the whole thing to original signerInfo's unAuthAttrs
 *    as a SEC_OID_PKCS9_COUNTER_SIGNATURE attribute
 *
 * XXXX give back the new signerinfo?
 */
SECStatus
NSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo,
                                      SECOidTag digestalg, CERTCertificate signingcert)
{
    /* XXXX TBD XXXX */
    return SECFailure;
}

/*
 * XXXX the following needs to be done in the S/MIME layer code
 * after signature of a signerinfo is verified
 */
SECStatus
NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo)
{
    CERTCertificate *cert = NULL;
    SECItem *profile = NULL;
    NSSCMSAttribute *attr;
    SECItem *stime = NULL;
    SECItem *ekp;
    CERTCertDBHandle *certdb;
    int save_error;
    SECStatus rv;
    PRBool must_free_cert = PR_FALSE;

    certdb = CERT_GetDefaultCertDB();

    /* sanity check - see if verification status is ok (unverified does not count...) */
    if (signerinfo->verificationStatus != NSSCMSVS_GoodSignature)
        return SECFailure;

    /* find preferred encryption cert */
    if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr) &&
        (attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
                                                       SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, PR_TRUE)) != NULL) { /* we have a SMIME_ENCRYPTION_KEY_PREFERENCE attribute! */
        ekp = NSS_CMSAttribute_GetValue(attr);
        if (ekp == NULL)
            return SECFailure;

        /* we assume that all certs coming with the message have been imported to the */
        /* temporary database */
        cert = NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(certdb, ekp);
        if (cert == NULL)
            return SECFailure;
        must_free_cert = PR_TRUE;
    }

    if (cert == NULL) {
        /* no preferred cert found?
     * find the cert the signerinfo is signed with instead */
        cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb);
        if (cert == NULL || cert->emailAddr == NULL || !cert->emailAddr[0])
            return SECFailure;
    }

/* verify this cert for encryption (has been verified for signing so far) */
/* don't verify this cert for encryption. It may just be a signing cert.
     * that's OK, we can still save the S/MIME profile. The encryption cert
     * should have already been saved */
#ifdef notdef
    if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
        if (must_free_cert)
            CERT_DestroyCertificate(cert);
        return SECFailure;
    }
#endif

    /* XXX store encryption cert permanently? */

    /*
     * Remember the current error set because we do not care about
     * anything set by the functions we are about to call.
     */
    save_error = PORT_GetError();

    if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {
        attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
                                                      SEC_OID_PKCS9_SMIME_CAPABILITIES,
                                                      PR_TRUE);
        profile = NSS_CMSAttribute_GetValue(attr);
        attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
                                                      SEC_OID_PKCS9_SIGNING_TIME,
                                                      PR_TRUE);
        stime = NSS_CMSAttribute_GetValue(attr);
    }

    rv = CERT_SaveSMimeProfile(cert, profile, stime);
    if (must_free_cert)
        CERT_DestroyCertificate(cert);

    /*
     * Restore the saved error in case the calls above set a new
     * one that we do not actually care about.
     */
    PORT_SetError(save_error);

    return rv;
}

/*
 * NSS_CMSSignerInfo_IncludeCerts - set cert chain inclusion mode for this signer
 */
SECStatus
NSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo,
                               NSSCMSCertChainMode cm, SECCertUsage usage)
{
    if (signerinfo->cert == NULL)
        return SECFailure;

    /* don't leak if we get called twice */
    if (signerinfo->certList != NULL) {
        CERT_DestroyCertificateList(signerinfo->certList);
        signerinfo->certList = NULL;
    }

    switch (cm) {
        case NSSCMSCM_None:
            signerinfo->certList = NULL;
            break;
        case NSSCMSCM_CertOnly:
            signerinfo->certList = CERT_CertListFromCert(signerinfo->cert);
            break;
        case NSSCMSCM_CertChain:
            signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert,
                                                          usage, PR_FALSE);
            break;
        case NSSCMSCM_CertChainWithRoot:
            signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert,
                                                          usage, PR_TRUE);
            break;
    }

    if (cm != NSSCMSCM_None && signerinfo->certList == NULL)
        return SECFailure;

    return SECSuccess;
}
