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

/*
 * Stuff specific to S/MIME policy and interoperability.
 * Depends on PKCS7, but there should be no dependency the other way around.
 */

#include "secmime.h"
#include "secoid.h"
#include "pk11func.h"
#include "ciferfam.h" /* for CIPHER_FAMILY symbols */
#include "secasn1.h"
#include "secitem.h"
#include "cert.h"
#include "keyhi.h"
#include "secerr.h"

typedef struct smime_cipher_map_struct {
    unsigned long cipher;
    SECOidTag algtag;
    SECItem *parms;
} smime_cipher_map;

/*
 * These are macros because I think some subsequent parameters,
 * like those for RC5, will want to use them, too, separately.
 */
#define SMIME_DER_INTVAL_16 SEC_ASN1_INTEGER, 0x01, 0x10
#define SMIME_DER_INTVAL_40 SEC_ASN1_INTEGER, 0x01, 0x28
#define SMIME_DER_INTVAL_64 SEC_ASN1_INTEGER, 0x01, 0x40
#define SMIME_DER_INTVAL_128 SEC_ASN1_INTEGER, 0x02, 0x00, 0x80

#ifdef SMIME_DOES_RC5 /* will be needed; quiet unused warning for now */
static unsigned char smime_int16[] = { SMIME_DER_INTVAL_16 };
#endif
static unsigned char smime_int40[] = { SMIME_DER_INTVAL_40 };
static unsigned char smime_int64[] = { SMIME_DER_INTVAL_64 };
static unsigned char smime_int128[] = { SMIME_DER_INTVAL_128 };

static SECItem smime_rc2p40 = { siBuffer, smime_int40, sizeof(smime_int40) };
static SECItem smime_rc2p64 = { siBuffer, smime_int64, sizeof(smime_int64) };
static SECItem smime_rc2p128 = { siBuffer, smime_int128, sizeof(smime_int128) };

static smime_cipher_map smime_cipher_maps[] = {
    { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, &smime_rc2p40 },
    { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, &smime_rc2p64 },
    { SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, &smime_rc2p128 },
#ifdef SMIME_DOES_RC5
    { SMIME_RC5PAD_64_16_40, SEC_OID_RC5_CBC_PAD, &smime_rc5p40 },
    { SMIME_RC5PAD_64_16_64, SEC_OID_RC5_CBC_PAD, &smime_rc5p64 },
    { SMIME_RC5PAD_64_16_128, SEC_OID_RC5_CBC_PAD, &smime_rc5p128 },
#endif
    { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL },
    { SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL }
};

/*
 * Note, the following value really just needs to be an upper bound
 * on the ciphers.
 */
static const int smime_symmetric_count = sizeof(smime_cipher_maps) / sizeof(smime_cipher_map);

static unsigned long *smime_prefs, *smime_newprefs;
static int smime_current_pref_index = 0;
static PRBool smime_prefs_complete = PR_FALSE;
static PRBool smime_prefs_changed = PR_TRUE;

static unsigned long smime_policy_bits = 0;

static int
smime_mapi_by_cipher(unsigned long cipher)
{
    int i;

    for (i = 0; i < smime_symmetric_count; i++) {
        if (smime_cipher_maps[i].cipher == cipher)
            break;
    }

    if (i == smime_symmetric_count)
        return -1;

    return i;
}

/*
 * this function locally records the user's preference
 */
SECStatus
SECMIME_EnableCipher(long which, int on)
{
    unsigned long mask;

    if (smime_newprefs == NULL || smime_prefs_complete) {
        /*
         * This is either the very first time, or we are starting over.
         */
        smime_newprefs = (unsigned long *)PORT_ZAlloc(smime_symmetric_count * sizeof(*smime_newprefs));
        if (smime_newprefs == NULL)
            return SECFailure;
        smime_current_pref_index = 0;
        smime_prefs_complete = PR_FALSE;
    }

    mask = which & CIPHER_FAMILYID_MASK;
    if (mask == CIPHER_FAMILYID_MASK) {
        /*
         * This call signifies that all preferences have been set.
         * Move "newprefs" over, after checking first whether or
         * not the new ones are different from the old ones.
         */
        if (smime_prefs != NULL) {
            if (PORT_Memcmp(smime_prefs, smime_newprefs,
                            smime_symmetric_count * sizeof(*smime_prefs)) == 0)
                smime_prefs_changed = PR_FALSE;
            else
                smime_prefs_changed = PR_TRUE;
            PORT_Free(smime_prefs);
        }

        smime_prefs = smime_newprefs;
        smime_prefs_complete = PR_TRUE;
        return SECSuccess;
    }

    PORT_Assert(mask == CIPHER_FAMILYID_SMIME);
    if (mask != CIPHER_FAMILYID_SMIME) {
        /* XXX set an error! */
        return SECFailure;
    }

    if (on) {
        PORT_Assert(smime_current_pref_index < smime_symmetric_count);
        if (smime_current_pref_index >= smime_symmetric_count) {
            /* XXX set an error! */
            return SECFailure;
        }

        smime_newprefs[smime_current_pref_index++] = which;
    }

    return SECSuccess;
}

/*
 * this function locally records the export policy
 */
SECStatus
SECMIME_SetPolicy(long which, int on)
{
    unsigned long mask;

    PORT_Assert((which & CIPHER_FAMILYID_MASK) == CIPHER_FAMILYID_SMIME);
    if ((which & CIPHER_FAMILYID_MASK) != CIPHER_FAMILYID_SMIME) {
        /* XXX set an error! */
        return SECFailure;
    }

    which &= ~CIPHER_FAMILYID_MASK;

    PORT_Assert(which < 32); /* bits in the long */
    if (which >= 32) {
        /* XXX set an error! */
        return SECFailure;
    }

    mask = 1UL << which;

    if (on) {
        smime_policy_bits |= mask;
    } else {
        smime_policy_bits &= ~mask;
    }

    return SECSuccess;
}

/*
 * Based on the given algorithm (including its parameters, in some cases!)
 * and the given key (may or may not be inspected, depending on the
 * algorithm), find the appropriate policy algorithm specification
 * and return it.  If no match can be made, -1 is returned.
 */
static long
smime_policy_algorithm(SECAlgorithmID *algid, PK11SymKey *key)
{
    SECOidTag algtag;

    algtag = SECOID_GetAlgorithmTag(algid);
    switch (algtag) {
        case SEC_OID_RC2_CBC: {
            unsigned int keylen_bits;

            keylen_bits = PK11_GetKeyStrength(key, algid);
            switch (keylen_bits) {
                case 40:
                    return SMIME_RC2_CBC_40;
                case 64:
                    return SMIME_RC2_CBC_64;
                case 128:
                    return SMIME_RC2_CBC_128;
                default:
                    break;
            }
        } break;
        case SEC_OID_DES_CBC:
            return SMIME_DES_CBC_56;
        case SEC_OID_DES_EDE3_CBC:
            return SMIME_DES_EDE3_168;
#ifdef SMIME_DOES_RC5
        case SEC_OID_RC5_CBC_PAD:
            PORT_Assert(0); /* XXX need to pull out parameters and match */
            break;
#endif
        default:
            break;
    }

    return -1;
}

static PRBool
smime_cipher_allowed(unsigned long which)
{
    unsigned long mask;

    which &= ~CIPHER_FAMILYID_MASK;
    PORT_Assert(which < 32); /* bits per long (min) */
    if (which >= 32)
        return PR_FALSE;

    mask = 1UL << which;
    if ((mask & smime_policy_bits) == 0)
        return PR_FALSE;

    return PR_TRUE;
}

PRBool
SECMIME_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key)
{
    long which;

    which = smime_policy_algorithm(algid, key);
    if (which < 0)
        return PR_FALSE;

    return smime_cipher_allowed((unsigned long)which);
}

/*
 * Does the current policy allow *any* S/MIME encryption (or decryption)?
 *
 * This tells whether or not *any* S/MIME encryption can be done,
 * according to policy.  Callers may use this to do nicer user interface
 * (say, greying out a checkbox so a user does not even try to encrypt
 * a message when they are not allowed to) or for any reason they want
 * to check whether S/MIME encryption (or decryption, for that matter)
 * may be done.
 *
 * It takes no arguments.  The return value is a simple boolean:
 *   PR_TRUE means encryption (or decryption) is *possible*
 *      (but may still fail due to other reasons, like because we cannot
 *      find all the necessary certs, etc.; PR_TRUE is *not* a guarantee)
 *   PR_FALSE means encryption (or decryption) is not permitted
 *
 * There are no errors from this routine.
 */
PRBool
SECMIME_EncryptionPossible(void)
{
    if (smime_policy_bits != 0)
        return PR_TRUE;

    return PR_FALSE;
}

/*
 * XXX Would like the "parameters" field to be a SECItem *, but the
 * encoder is having trouble with optional pointers to an ANY.  Maybe
 * once that is fixed, can change this back...
 */
typedef struct smime_capability_struct {
    unsigned long cipher; /* local; not part of encoding */
    SECOidTag capIDTag;   /* local; not part of encoding */
    SECItem capabilityID;
    SECItem parameters;
} smime_capability;

static const SEC_ASN1Template smime_capability_template[] = {
    { SEC_ASN1_SEQUENCE,
      0, NULL, sizeof(smime_capability) },
    { SEC_ASN1_OBJECT_ID,
      offsetof(smime_capability, capabilityID) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
      offsetof(smime_capability, parameters) },
    { 0 }
};

static const SEC_ASN1Template smime_capabilities_template[] = {
    { SEC_ASN1_SEQUENCE_OF, 0, smime_capability_template }
};

static void
smime_fill_capability(smime_capability *cap)
{
    unsigned long cipher;
    SECOidTag algtag;
    int i;

    algtag = SECOID_FindOIDTag(&(cap->capabilityID));

    for (i = 0; i < smime_symmetric_count; i++) {
        if (smime_cipher_maps[i].algtag != algtag)
            continue;
        /*
         * XXX If SECITEM_CompareItem allowed NULLs as arguments (comparing
         * 2 NULLs as equal and NULL and non-NULL as not equal), we could
         * use that here instead of all of the following comparison code.
         */
        if (cap->parameters.data != NULL) {
            if (smime_cipher_maps[i].parms == NULL)
                continue;
            if (cap->parameters.len != smime_cipher_maps[i].parms->len)
                continue;
            if (PORT_Memcmp(cap->parameters.data,
                            smime_cipher_maps[i].parms->data,
                            cap->parameters.len) == 0)
                break;
        } else if (smime_cipher_maps[i].parms == NULL) {
            break;
        }
    }

    if (i == smime_symmetric_count)
        cipher = 0;
    else
        cipher = smime_cipher_maps[i].cipher;

    cap->cipher = cipher;
    cap->capIDTag = algtag;
}

static long
smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts)
{
    PLArenaPool *poolp;
    long chosen_cipher;
    int *cipher_abilities;
    int *cipher_votes;
    int strong_mapi;
    int rcount, mapi, max;

    if (smime_policy_bits == 0) {
        PORT_SetError(SEC_ERROR_BAD_EXPORT_ALGORITHM);
        return -1;
    }

    chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */

    poolp = PORT_NewArena(1024); /* XXX what is right value? */
    if (poolp == NULL)
        goto done;

    cipher_abilities = (int *)PORT_ArenaZAlloc(poolp,
                                               smime_symmetric_count * sizeof(int));
    if (cipher_abilities == NULL)
        goto done;

    cipher_votes = (int *)PORT_ArenaZAlloc(poolp,
                                           smime_symmetric_count * sizeof(int));
    if (cipher_votes == NULL)
        goto done;

    /*
     * XXX Should have a #define somewhere which specifies default
     * strong cipher.  (Or better, a way to configure.)
     */

    /* Make triple-DES the strong cipher. */
    strong_mapi = smime_mapi_by_cipher(SMIME_DES_EDE3_168);

    PORT_Assert(strong_mapi >= 0);

    for (rcount = 0; rcerts[rcount] != NULL; rcount++) {
        SECItem *profile;
        smime_capability **caps;
        int capi, pref;
        SECStatus dstat;

        pref = smime_symmetric_count;
        profile = CERT_FindSMimeProfile(rcerts[rcount]);
        if (profile != NULL && profile->data != NULL && profile->len > 0) {
            caps = NULL;
            dstat = SEC_QuickDERDecodeItem(poolp, &caps,
                                           smime_capabilities_template,
                                           profile);
            if (dstat == SECSuccess && caps != NULL) {
                for (capi = 0; caps[capi] != NULL; capi++) {
                    smime_fill_capability(caps[capi]);
                    mapi = smime_mapi_by_cipher(caps[capi]->cipher);
                    if (mapi >= 0) {
                        cipher_abilities[mapi]++;
                        cipher_votes[mapi] += pref;
                        --pref;
                    }
                }
            }
        } else {
            SECKEYPublicKey *key;
            unsigned int pklen_bits;

            /*
             * XXX This is probably only good for RSA keys.  What I would
             * really like is a function to just say;  Is the public key in
             * this cert an export-length key?  Then I would not have to
             * know things like the value 512, or the kind of key, or what
             * a subjectPublicKeyInfo is, etc.
             */
            key = CERT_ExtractPublicKey(rcerts[rcount]);
            if (key != NULL) {
                pklen_bits = SECKEY_PublicKeyStrength(key) * 8;
                SECKEY_DestroyPublicKey(key);

                if (pklen_bits > 512) {
                    cipher_abilities[strong_mapi]++;
                    cipher_votes[strong_mapi] += pref;
                }
            }
        }
        if (profile != NULL)
            SECITEM_FreeItem(profile, PR_TRUE);
    }

    max = 0;
    for (mapi = 0; mapi < smime_symmetric_count; mapi++) {
        if (cipher_abilities[mapi] != rcount)
            continue;
        if (!smime_cipher_allowed(smime_cipher_maps[mapi].cipher))
            continue;
        if (cipher_votes[mapi] > max) {
            chosen_cipher = smime_cipher_maps[mapi].cipher;
            max = cipher_votes[mapi];
        } /* XXX else if a tie, let scert break it? */
    }

done:
    if (poolp != NULL)
        PORT_FreeArena(poolp, PR_FALSE);

    return chosen_cipher;
}

/*
 * XXX This is a hack for now to satisfy our current interface.
 * Eventually, with more parameters needing to be specified, just
 * looking up the keysize is not going to be sufficient.
 */
static int
smime_keysize_by_cipher(unsigned long which)
{
    int keysize;

    switch (which) {
        case SMIME_RC2_CBC_40:
            keysize = 40;
            break;
        case SMIME_RC2_CBC_64:
            keysize = 64;
            break;
        case SMIME_RC2_CBC_128:
            keysize = 128;
            break;
#ifdef SMIME_DOES_RC5
        case SMIME_RC5PAD_64_16_40:
        case SMIME_RC5PAD_64_16_64:
        case SMIME_RC5PAD_64_16_128:
            /* XXX See comment above; keysize is not enough... */
            PORT_Assert(0);
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
            keysize = -1;
            break;
#endif
        case SMIME_DES_CBC_56:
        case SMIME_DES_EDE3_168:
            /*
             * These are special; since the key size is fixed, we actually
             * want to *avoid* specifying a key size.
             */
            keysize = 0;
            break;
        default:
            keysize = -1;
            break;
    }

    return keysize;
}

/*
 * Start an S/MIME encrypting context.
 *
 * "scert" is the cert for the sender.  It will be checked for validity.
 * "rcerts" are the certs for the recipients.  They will also be checked.
 *
 * "certdb" is the cert database to use for verifying the certs.
 * It can be NULL if a default database is available (like in the client).
 *
 * This function already does all of the stuff specific to S/MIME protocol
 * and local policy; the return value just needs to be passed to
 * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
 * and finally to SEC_PKCS7DestroyContentInfo().
 *
 * An error results in a return value of NULL and an error set.
 * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
 */
SEC_PKCS7ContentInfo *
SECMIME_CreateEncrypted(CERTCertificate *scert,
                        CERTCertificate **rcerts,
                        CERTCertDBHandle *certdb,
                        SECKEYGetPasswordKey pwfn,
                        void *pwfn_arg)
{
    SEC_PKCS7ContentInfo *cinfo;
    long cipher;
    SECOidTag encalg;
    int keysize;
    int mapi, rci;

    cipher = smime_choose_cipher(scert, rcerts);
    if (cipher < 0)
        return NULL;

    mapi = smime_mapi_by_cipher(cipher);
    if (mapi < 0)
        return NULL;

    /*
     * XXX This is stretching it -- CreateEnvelopedData should probably
     * take a cipher itself of some sort, because we cannot know what the
     * future will bring in terms of parameters for each type of algorithm.
     * For example, just an algorithm and keysize is *not* sufficient to
     * fully specify the usage of RC5 (which also needs to know rounds and
     * block size).  Work this out into a better API!
     */
    encalg = smime_cipher_maps[mapi].algtag;
    keysize = smime_keysize_by_cipher(cipher);
    if (keysize < 0)
        return NULL;

    cinfo = SEC_PKCS7CreateEnvelopedData(scert, certUsageEmailRecipient,
                                         certdb, encalg, keysize,
                                         pwfn, pwfn_arg);
    if (cinfo == NULL)
        return NULL;

    for (rci = 0; rcerts[rci] != NULL; rci++) {
        if (rcerts[rci] == scert)
            continue;
        if (SEC_PKCS7AddRecipient(cinfo, rcerts[rci], certUsageEmailRecipient,
                                  NULL) != SECSuccess) {
            SEC_PKCS7DestroyContentInfo(cinfo);
            return NULL;
        }
    }

    return cinfo;
}

static smime_capability **smime_capabilities;
static SECItem *smime_encoded_caps;

static SECStatus
smime_init_caps(void)
{
    smime_capability *cap;
    smime_cipher_map *map;
    SECOidData *oiddata;
    SECStatus rv;
    int i;

    if (smime_encoded_caps != NULL && (!smime_prefs_changed))
        return SECSuccess;

    if (smime_encoded_caps != NULL) {
        SECITEM_FreeItem(smime_encoded_caps, PR_TRUE);
        smime_encoded_caps = NULL;
    }

    if (smime_capabilities == NULL) {
        smime_capabilities = (smime_capability **)PORT_ZAlloc(
            (smime_symmetric_count + 1) * sizeof(smime_capability *));
        if (smime_capabilities == NULL)
            return SECFailure;
    }

    rv = SECFailure;

    /*
       The process of creating the encoded PKCS7 cipher capability list
       involves two basic steps:

       (a) Convert our internal representation of cipher preferences
           (smime_prefs) into an array containing cipher OIDs and
           parameter data (smime_capabilities). This step is
           performed here.

       (b) Encode, using ASN.1, the cipher information in
           smime_capabilities, leaving the encoded result in
           smime_encoded_caps.

       (In the process of performing (a), Lisa put in some optimizations
       which allow us to avoid needlessly re-populating elements in
       smime_capabilities as we walk through smime_prefs.)
    */
    for (i = 0; i < smime_current_pref_index; i++) {
        int mapi;

        /* Get the next cipher preference in smime_prefs. */
        mapi = smime_mapi_by_cipher(smime_prefs[i]);
        if (mapi < 0)
            break;

        /* Find the corresponding entry in the cipher map. */
        PORT_Assert(mapi < smime_symmetric_count);
        map = &(smime_cipher_maps[mapi]);

        /*
         * Convert the next preference found in smime_prefs into an
         * smime_capability.
         */

        cap = smime_capabilities[i];
        if (cap == NULL) {
            cap = (smime_capability *)PORT_ZAlloc(sizeof(smime_capability));
            if (cap == NULL)
                break;
            smime_capabilities[i] = cap;
        } else if (cap->cipher == smime_prefs[i]) {
            continue; /* no change to this one */
        }

        cap->capIDTag = map->algtag;
        oiddata = SECOID_FindOIDByTag(map->algtag);
        if (oiddata == NULL)
            break;

        if (cap->capabilityID.data != NULL) {
            SECITEM_FreeItem(&(cap->capabilityID), PR_FALSE);
            cap->capabilityID.data = NULL;
            cap->capabilityID.len = 0;
        }

        rv = SECITEM_CopyItem(NULL, &(cap->capabilityID), &(oiddata->oid));
        if (rv != SECSuccess)
            break;

        if (map->parms == NULL) {
            cap->parameters.data = NULL;
            cap->parameters.len = 0;
        } else {
            cap->parameters.data = map->parms->data;
            cap->parameters.len = map->parms->len;
        }

        cap->cipher = smime_prefs[i];
    }

    if (i != smime_current_pref_index)
        return rv;

    while (i < smime_symmetric_count) {
        cap = smime_capabilities[i];
        if (cap != NULL) {
            SECITEM_FreeItem(&(cap->capabilityID), PR_FALSE);
            PORT_Free(cap);
        }
        smime_capabilities[i] = NULL;
        i++;
    }
    smime_capabilities[i] = NULL;

    smime_encoded_caps = SEC_ASN1EncodeItem(NULL, NULL, &smime_capabilities,
                                            smime_capabilities_template);
    if (smime_encoded_caps == NULL)
        return SECFailure;

    return SECSuccess;
}

static SECStatus
smime_add_profile(CERTCertificate *cert, SEC_PKCS7ContentInfo *cinfo)
{
    PORT_Assert(smime_prefs_complete);
    if (!smime_prefs_complete)
        return SECFailure;

    /* For that matter, if capabilities haven't been initialized yet,
       do so now. */
    if (smime_encoded_caps == NULL || smime_prefs_changed) {
        SECStatus rv;

        rv = smime_init_caps();
        if (rv != SECSuccess)
            return rv;

        PORT_Assert(smime_encoded_caps != NULL);
    }

    return SEC_PKCS7AddSignedAttribute(cinfo, SEC_OID_PKCS9_SMIME_CAPABILITIES,
                                       smime_encoded_caps);
}

/*
 * Start an S/MIME signing context.
 *
 * "scert" is the cert that will be used to sign the data.  It will be
 * checked for validity.
 *
 * "ecert" is the signer's encryption cert.  If it is different from
 * scert, then it will be included in the signed message so that the
 * recipient can save it for future encryptions.
 *
 * "certdb" is the cert database to use for verifying the cert.
 * It can be NULL if a default database is available (like in the client).
 *
 * "digestalg" names the digest algorithm (e.g. SEC_OID_SHA1).
 * XXX There should be SECMIME functions for hashing, or the hashing should
 * be built into this interface, which we would like because we would
 * support more smartcards that way, and then this argument should go away.)
 *
 * "digest" is the actual digest of the data.  It must be provided in
 * the case of detached data or NULL if the content will be included.
 *
 * This function already does all of the stuff specific to S/MIME protocol
 * and local policy; the return value just needs to be passed to
 * SEC_PKCS7Encode() or to SEC_PKCS7EncoderStart() to create the encoded data,
 * and finally to SEC_PKCS7DestroyContentInfo().
 *
 * An error results in a return value of NULL and an error set.
 * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
 */

SEC_PKCS7ContentInfo *
SECMIME_CreateSigned(CERTCertificate *scert,
                     CERTCertificate *ecert,
                     CERTCertDBHandle *certdb,
                     SECOidTag digestalg,
                     SECItem *digest,
                     SECKEYGetPasswordKey pwfn,
                     void *pwfn_arg)
{
    SEC_PKCS7ContentInfo *cinfo;
    SECStatus rv;

    /* See note in header comment above about digestalg. */
    /* Doesn't explain this. PORT_Assert (digestalg == SEC_OID_SHA1); */

    cinfo = SEC_PKCS7CreateSignedData(scert, certUsageEmailSigner,
                                      certdb, digestalg, digest,
                                      pwfn, pwfn_arg);
    if (cinfo == NULL)
        return NULL;

    if (SEC_PKCS7IncludeCertChain(cinfo, NULL) != SECSuccess) {
        SEC_PKCS7DestroyContentInfo(cinfo);
        return NULL;
    }

    /* if the encryption cert and the signing cert differ, then include
     * the encryption cert too.
     */
    /* it is ok to compare the pointers since we ref count, and the same
     * cert will always have the same pointer
     */
    if ((ecert != NULL) && (ecert != scert)) {
        rv = SEC_PKCS7AddCertificate(cinfo, ecert);
        if (rv != SECSuccess) {
            SEC_PKCS7DestroyContentInfo(cinfo);
            return NULL;
        }
    }
    /*
     * Add the signing time.  But if it fails for some reason,
     * may as well not give up altogether -- just assert.
     */
    rv = SEC_PKCS7AddSigningTime(cinfo);
    PORT_Assert(rv == SECSuccess);

    /*
     * Add the email profile.  Again, if it fails for some reason,
     * may as well not give up altogether -- just assert.
     */
    rv = smime_add_profile(ecert, cinfo);
    PORT_Assert(rv == SECSuccess);

    return cinfo;
}
