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

#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"
#include "cms.h"
#include "nss.h"

SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
SEC_ASN1_CHOOSER_DECLARE(CERT_IssuerAndSNTemplate)

/* various integer's ASN.1 encoding */
static unsigned char asn1_int40[] = { SEC_ASN1_INTEGER, 0x01, 0x28 };
static unsigned char asn1_int64[] = { SEC_ASN1_INTEGER, 0x01, 0x40 };
static unsigned char asn1_int128[] = { SEC_ASN1_INTEGER, 0x02, 0x00, 0x80 };

/* RC2 algorithm parameters (used in smime_cipher_map) */
static SECItem param_int40 = { siBuffer, asn1_int40, sizeof(asn1_int40) };
static SECItem param_int64 = { siBuffer, asn1_int64, sizeof(asn1_int64) };
static SECItem param_int128 = { siBuffer, asn1_int128, sizeof(asn1_int128) };

/*
 * 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 {
    SECItem capabilityID;
    SECItem parameters;
    long cipher; /* optimization */
} NSSSMIMECapability;

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

static const SEC_ASN1Template NSSSMIMECapabilitiesTemplate[] = {
    { SEC_ASN1_SEQUENCE_OF, 0, NSSSMIMECapabilityTemplate }
};

/*
 * NSSSMIMEEncryptionKeyPreference - if we find one of these, it needs to prompt us
 *  to store this and only this certificate permanently for the sender email address.
 */
typedef enum {
    NSSSMIMEEncryptionKeyPref_IssuerSN,
    NSSSMIMEEncryptionKeyPref_RKeyID,
    NSSSMIMEEncryptionKeyPref_SubjectKeyID
} NSSSMIMEEncryptionKeyPrefSelector;

typedef struct {
    NSSSMIMEEncryptionKeyPrefSelector selector;
    union {
        CERTIssuerAndSN *issuerAndSN;
        NSSCMSRecipientKeyIdentifier *recipientKeyID;
        SECItem *subjectKeyID;
    } id;
} NSSSMIMEEncryptionKeyPreference;

extern const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[];

static const SEC_ASN1Template smime_encryptionkeypref_template[] = {
    { SEC_ASN1_CHOICE,
      offsetof(NSSSMIMEEncryptionKeyPreference, selector), NULL,
      sizeof(NSSSMIMEEncryptionKeyPreference) },
    { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0 | SEC_ASN1_CONSTRUCTED,
      offsetof(NSSSMIMEEncryptionKeyPreference, id.issuerAndSN),
      SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
      NSSSMIMEEncryptionKeyPref_IssuerSN },
    { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 1 | SEC_ASN1_CONSTRUCTED,
      offsetof(NSSSMIMEEncryptionKeyPreference, id.recipientKeyID),
      NSSCMSRecipientKeyIdentifierTemplate,
      NSSSMIMEEncryptionKeyPref_RKeyID },
    { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2 | SEC_ASN1_CONSTRUCTED,
      offsetof(NSSSMIMEEncryptionKeyPreference, id.subjectKeyID),
      SEC_ASN1_SUB(SEC_OctetStringTemplate),
      NSSSMIMEEncryptionKeyPref_SubjectKeyID },
    { 0 }
};

/* smime_cipher_map - map of SMIME symmetric "ciphers" to algtag & parameters */
typedef struct {
    unsigned long cipher;
    SECOidTag algtag;
    SECItem *parms;
    PRBool enabled; /* in the user's preferences */
    PRBool allowed; /* per export policy */
} smime_cipher_map_entry;

/* global: list of supported SMIME symmetric ciphers, ordered roughly by increasing strength */
static smime_cipher_map_entry smime_cipher_map[] = {
    /*    cipher, algtag, parms, enabled, allowed    */
    /*    ---------------------------------------    */
    { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, &param_int40, PR_TRUE, PR_TRUE },
    { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL, PR_TRUE, PR_TRUE },
    { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, &param_int64, PR_TRUE, PR_TRUE },
    { SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, &param_int128, PR_TRUE, PR_TRUE },
    { SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL, PR_TRUE, PR_TRUE },
    { SMIME_AES_CBC_128, SEC_OID_AES_128_CBC, NULL, PR_TRUE, PR_TRUE },
    { SMIME_AES_CBC_256, SEC_OID_AES_256_CBC, NULL, PR_TRUE, PR_TRUE }
};
static const int smime_cipher_map_count = sizeof(smime_cipher_map) / sizeof(smime_cipher_map_entry);

/*
 * smime_mapi_by_cipher - find index into smime_cipher_map by cipher
 */
static int
smime_mapi_by_cipher(unsigned long cipher)
{
    int i;

    for (i = 0; i < smime_cipher_map_count; i++) {
        if (smime_cipher_map[i].cipher == cipher)
            return i; /* bingo */
    }
    return -1; /* should not happen if we're consistent, right? */
}

/*
 * NSS_SMIME_EnableCipher - this function locally records the user's preference
 */
SECStatus
NSS_SMIMEUtil_EnableCipher(unsigned long which, PRBool on)
{
    unsigned long mask;
    int mapi;

    mask = which & CIPHER_FAMILYID_MASK;

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

    mapi = smime_mapi_by_cipher(which);
    if (mapi < 0)
        /* XXX set an error */
        return SECFailure;

    /* do we try to turn on a forbidden cipher? */
    if (!smime_cipher_map[mapi].allowed && on) {
        PORT_SetError(SEC_ERROR_BAD_EXPORT_ALGORITHM);
        return SECFailure;
    }

    if (smime_cipher_map[mapi].enabled != on)
        smime_cipher_map[mapi].enabled = on;

    return SECSuccess;
}

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

    mask = which & CIPHER_FAMILYID_MASK;

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

    mapi = smime_mapi_by_cipher(which);
    if (mapi < 0)
        /* XXX set an error */
        return SECFailure;

    if (smime_cipher_map[mapi].allowed != on)
        smime_cipher_map[mapi].allowed = on;

    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 SECStatus
nss_smime_get_cipher_for_alg_and_key(SECAlgorithmID *algid, PK11SymKey *key,
                                     unsigned long *cipher)
{
    SECOidTag algtag;
    unsigned int keylen_bits;
    unsigned long c;

    algtag = SECOID_GetAlgorithmTag(algid);
    switch (algtag) {
        case SEC_OID_RC2_CBC:
            keylen_bits = PK11_GetKeyStrength(key, algid);
            switch (keylen_bits) {
                case 40:
                    c = SMIME_RC2_CBC_40;
                    break;
                case 64:
                    c = SMIME_RC2_CBC_64;
                    break;
                case 128:
                    c = SMIME_RC2_CBC_128;
                    break;
                default:
                    return SECFailure;
            }
            break;
        case SEC_OID_DES_CBC:
            c = SMIME_DES_CBC_56;
            break;
        case SEC_OID_DES_EDE3_CBC:
            c = SMIME_DES_EDE3_168;
            break;
        case SEC_OID_AES_128_CBC:
            c = SMIME_AES_CBC_128;
            break;
        case SEC_OID_AES_256_CBC:
            c = SMIME_AES_CBC_256;
            break;
        default:
            PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
            return SECFailure;
    }
    *cipher = c;
    return SECSuccess;
}

static PRBool
nss_smime_cipher_allowed(unsigned long which)
{
    int mapi;

    mapi = smime_mapi_by_cipher(which);
    if (mapi < 0)
        return PR_FALSE;
    return smime_cipher_map[mapi].allowed;
}

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

    if (nss_smime_get_cipher_for_alg_and_key(algid, key, &which) != SECSuccess)
        return PR_FALSE;

    return nss_smime_cipher_allowed(which);
}

/*
 * NSS_SMIME_EncryptionPossible - check if any encryption is allowed
 *
 * 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
NSS_SMIMEUtil_EncryptionPossible(void)
{
    int i;

    for (i = 0; i < smime_cipher_map_count; i++) {
        if (smime_cipher_map[i].allowed)
            return PR_TRUE;
    }
    return PR_FALSE;
}

static int
nss_SMIME_FindCipherForSMIMECap(NSSSMIMECapability *cap)
{
    int i;
    SECOidTag capIDTag;

    /* we need the OIDTag here */
    capIDTag = SECOID_FindOIDTag(&(cap->capabilityID));

    /* go over all the SMIME ciphers we know and see if we find a match */
    for (i = 0; i < smime_cipher_map_count; i++) {
        if (smime_cipher_map[i].algtag != capIDTag)
            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 (!smime_cipher_map[i].parms) {
            if (!cap->parameters.data || !cap->parameters.len)
                break; /* both empty: bingo */
            if (cap->parameters.len == 2 &&
                cap->parameters.data[0] == SEC_ASN1_NULL &&
                cap->parameters.data[1] == 0)
                break; /* DER NULL == NULL, bingo */
        } else if (cap->parameters.data != NULL &&
                   cap->parameters.len == smime_cipher_map[i].parms->len &&
                   PORT_Memcmp(cap->parameters.data, smime_cipher_map[i].parms->data,
                               cap->parameters.len) == 0) {
            break; /* both not empty, same length & equal content: bingo */
        }
    }

    if (i == smime_cipher_map_count)
        return 0;                      /* no match found */
    return smime_cipher_map[i].cipher; /* match found, point to cipher */
}

/*
 * smime_choose_cipher - choose a cipher that works for all the recipients
 *
 * "scert"  - sender's certificate
 * "rcerts" - recipient's certificates
 */
static long
smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts)
{
    PLArenaPool *poolp;
    long cipher;
    long chosen_cipher;
    int *cipher_abilities;
    int *cipher_votes;
    int weak_mapi;
    int strong_mapi;
    int aes128_mapi;
    int aes256_mapi;
    int rcount, mapi, max, i;

    chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */
    weak_mapi = smime_mapi_by_cipher(chosen_cipher);
    aes128_mapi = smime_mapi_by_cipher(SMIME_AES_CBC_128);
    aes256_mapi = smime_mapi_by_cipher(SMIME_AES_CBC_256);

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

    cipher_abilities = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int));
    cipher_votes = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int));
    if (cipher_votes == NULL || cipher_abilities == NULL)
        goto done;

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

    /* walk all the recipient's certs */
    for (rcount = 0; rcerts[rcount] != NULL; rcount++) {
        SECItem *profile;
        NSSSMIMECapability **caps;
        int pref;

        /* the first cipher that matches in the user's SMIME profile gets
         * "smime_cipher_map_count" votes; the next one gets "smime_cipher_map_count" - 1
         * and so on. If every cipher matches, the last one gets 1 (one) vote */
        pref = smime_cipher_map_count;

        /* find recipient's SMIME profile */
        profile = CERT_FindSMimeProfile(rcerts[rcount]);

        if (profile != NULL && profile->data != NULL && profile->len > 0) {
            /* we have a profile (still DER-encoded) */
            caps = NULL;
            /* decode it */
            if (SEC_QuickDERDecodeItem(poolp, &caps,
                                       NSSSMIMECapabilitiesTemplate, profile) == SECSuccess &&
                caps != NULL) {
                /* walk the SMIME capabilities for this recipient */
                for (i = 0; caps[i] != NULL; i++) {
                    cipher = nss_SMIME_FindCipherForSMIMECap(caps[i]);
                    mapi = smime_mapi_by_cipher(cipher);
                    if (mapi >= 0) {
                        /* found the cipher */
                        cipher_abilities[mapi]++;
                        cipher_votes[mapi] += pref;
                        --pref;
                    }
                }
            }
        } else {
            /* no profile found - so we can only assume that the user can do
             * the mandatory algorithms which are RC2-40 (weak crypto) and
             * 3DES (strong crypto), unless the user has an elliptic curve
             * key.  For elliptic curve keys, RFC 5753 mandates support
             * for AES 128 CBC. */
            SECKEYPublicKey *key;
            unsigned int pklen_bits;
            KeyType key_type;

            /*
             * if recipient's public key length is > 512, vote for a strong cipher
             * please not that the side effect of this is that if only one recipient
             * has an export-level public key, the strong cipher is disabled.
             *
             * 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]);
            pklen_bits = 0;
            key_type = nullKey;
            if (key != NULL) {
                pklen_bits = SECKEY_PublicKeyStrengthInBits(key);
                key_type = SECKEY_GetPublicKeyType(key);
                SECKEY_DestroyPublicKey(key);
                key = NULL;
            }

            if (key_type == ecKey) {
                /* While RFC 5753 mandates support for AES-128 CBC, should use
                 * AES 256 if user's key provides more than 128 bits of
                 * security strength so that symmetric key is not weak link. */

                /* RC2-40 is not compatible with elliptic curve keys. */
                chosen_cipher = SMIME_DES_EDE3_168;
                if (pklen_bits > 256) {
                    cipher_abilities[aes256_mapi]++;
                    cipher_votes[aes256_mapi] += pref;
                    pref--;
                }
                cipher_abilities[aes128_mapi]++;
                cipher_votes[aes128_mapi] += pref;
                pref--;
                cipher_abilities[strong_mapi]++;
                cipher_votes[strong_mapi] += pref;
                pref--;
            } else {
                if (pklen_bits > 3072) {
                    /* While support for AES 256 is a SHOULD+ in RFC 5751
                     * rather than a MUST, RSA and DSA keys longer than 3072
                     * bits provide more than 128 bits of security strength.
                     * So, AES 256 should be used to provide comparable
                     * security. */
                    cipher_abilities[aes256_mapi]++;
                    cipher_votes[aes256_mapi] += pref;
                    pref--;
                }
                if (pklen_bits > 1023) {
                    /* RFC 5751 mandates support for AES 128, but also says
                     * that RSA and DSA signature keys SHOULD NOT be less than
                     * 1024 bits. So, cast vote for AES 128 if key length
                     * is at least 1024 bits. */
                    cipher_abilities[aes128_mapi]++;
                    cipher_votes[aes128_mapi] += pref;
                    pref--;
                }
                if (pklen_bits > 512) {
                    /* cast votes for the strong algorithm */
                    cipher_abilities[strong_mapi]++;
                    cipher_votes[strong_mapi] += pref;
                    pref--;
                }

                /* always cast (possibly less) votes for the weak algorithm */
                cipher_abilities[weak_mapi]++;
                cipher_votes[weak_mapi] += pref;
            }
        }
        if (profile != NULL)
            SECITEM_FreeItem(profile, PR_TRUE);
    }

    /* find cipher that is agreeable by all recipients and that has the most votes */
    max = 0;
    for (mapi = 0; mapi < smime_cipher_map_count; mapi++) {
        /* if not all of the recipients can do this, forget it */
        if (cipher_abilities[mapi] != rcount)
            continue;
        /* if cipher is not enabled or not allowed by policy, forget it */
        if (!smime_cipher_map[mapi].enabled || !smime_cipher_map[mapi].allowed)
            continue;
        /* now see if this one has more votes than the last best one */
        if (cipher_votes[mapi] >= max) {
            /* if equal number of votes, prefer the ones further down in the list */
            /* with the expectation that these are higher rated ciphers */
            chosen_cipher = smime_cipher_map[mapi].cipher;
            max = cipher_votes[mapi];
        }
    }
/* if no common cipher was found, chosen_cipher stays at the default */

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:
        case SMIME_AES_CBC_128:
            keysize = 128;
            break;
        case SMIME_AES_CBC_256:
            keysize = 256;
            break;
        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;
}

/*
 * NSS_SMIMEUtil_FindBulkAlgForRecipients - find bulk algorithm suitable for all recipients
 *
 * it would be great for UI purposes if there would be a way to find out which recipients
 * prevented a strong cipher from being used...
 */
SECStatus
NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts,
                                       SECOidTag *bulkalgtag, int *keysize)
{
    unsigned long cipher;
    int mapi;

    cipher = smime_choose_cipher(NULL, rcerts);
    mapi = smime_mapi_by_cipher(cipher);

    *bulkalgtag = smime_cipher_map[mapi].algtag;
    *keysize = smime_keysize_by_cipher(smime_cipher_map[mapi].cipher);

    return SECSuccess;
}

/*
 * NSS_SMIMEUtil_CreateSMIMECapabilities - get S/MIME capabilities for this instance of NSS
 *
 * scans the list of allowed and enabled ciphers and construct a PKCS9-compliant
 * S/MIME capabilities attribute value.
 *
 * XXX Please note that, in contradiction to RFC2633 2.5.2, the capabilities only include
 * symmetric ciphers, NO signature algorithms or key encipherment algorithms.
 *
 * "poolp" - arena pool to create the S/MIME capabilities data on
 * "dest" - SECItem to put the data in
 */
SECStatus
NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest)
{
    NSSSMIMECapability *cap;
    NSSSMIMECapability **smime_capabilities;
    smime_cipher_map_entry *map;
    SECOidData *oiddata;
    SECItem *dummy;
    int i, capIndex;

    /* if we have an old NSSSMIMECapability array, we'll reuse it (has the right size) */
    /* smime_cipher_map_count + 1 is an upper bound - we might end up with less */
    smime_capabilities = (NSSSMIMECapability **)PORT_ZAlloc((smime_cipher_map_count + 1) * sizeof(NSSSMIMECapability *));
    if (smime_capabilities == NULL)
        return SECFailure;

    capIndex = 0;

    /* Add all the symmetric ciphers
     * We walk the cipher list backwards, as it is ordered by increasing strength,
     * we prefer the stronger cipher over a weaker one, and we have to list the
     * preferred algorithm first */
    for (i = smime_cipher_map_count - 1; i >= 0; i--) {
        /* Find the corresponding entry in the cipher map. */
        map = &(smime_cipher_map[i]);
        if (!map->enabled)
            continue;

        /* get next SMIME capability */
        cap = (NSSSMIMECapability *)PORT_ZAlloc(sizeof(NSSSMIMECapability));
        if (cap == NULL)
            break;
        smime_capabilities[capIndex++] = cap;

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

        cap->capabilityID.data = oiddata->oid.data;
        cap->capabilityID.len = oiddata->oid.len;
        cap->parameters.data = map->parms ? map->parms->data : NULL;
        cap->parameters.len = map->parms ? map->parms->len : 0;
        cap->cipher = smime_cipher_map[i].cipher;
    }

    /* XXX add signature algorithms */
    /* XXX add key encipherment algorithms */

    smime_capabilities[capIndex] = NULL; /* last one - now encode */
    dummy = SEC_ASN1EncodeItem(poolp, dest, &smime_capabilities, NSSSMIMECapabilitiesTemplate);

    /* now that we have the proper encoded SMIMECapabilities (or not),
     * free the work data */
    for (i = 0; smime_capabilities[i] != NULL; i++)
        PORT_Free(smime_capabilities[i]);
    PORT_Free(smime_capabilities);

    return (dummy == NULL) ? SECFailure : SECSuccess;
}

/*
 * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value
 *
 * "poolp" - arena pool to create the attr value on
 * "dest" - SECItem to put the data in
 * "cert" - certificate that should be marked as preferred encryption key
 *          cert is expected to have been verified for EmailRecipient usage.
 */
SECStatus
NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert)
{
    NSSSMIMEEncryptionKeyPreference ekp;
    SECItem *dummy = NULL;
    PLArenaPool *tmppoolp = NULL;

    if (cert == NULL)
        goto loser;

    tmppoolp = PORT_NewArena(1024);
    if (tmppoolp == NULL)
        goto loser;

    /* XXX hardcoded IssuerSN choice for now */
    ekp.selector = NSSSMIMEEncryptionKeyPref_IssuerSN;
    ekp.id.issuerAndSN = CERT_GetCertIssuerAndSN(tmppoolp, cert);
    if (ekp.id.issuerAndSN == NULL)
        goto loser;

    dummy = SEC_ASN1EncodeItem(poolp, dest, &ekp, smime_encryptionkeypref_template);

loser:
    if (tmppoolp)
        PORT_FreeArena(tmppoolp, PR_FALSE);

    return (dummy == NULL) ? SECFailure : SECSuccess;
}

/*
 * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value using MS oid
 *
 * "poolp" - arena pool to create the attr value on
 * "dest" - SECItem to put the data in
 * "cert" - certificate that should be marked as preferred encryption key
 *          cert is expected to have been verified for EmailRecipient usage.
 */
SECStatus
NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert)
{
    SECItem *dummy = NULL;
    PLArenaPool *tmppoolp = NULL;
    CERTIssuerAndSN *isn;

    if (cert == NULL)
        goto loser;

    tmppoolp = PORT_NewArena(1024);
    if (tmppoolp == NULL)
        goto loser;

    isn = CERT_GetCertIssuerAndSN(tmppoolp, cert);
    if (isn == NULL)
        goto loser;

    dummy = SEC_ASN1EncodeItem(poolp, dest, isn, SEC_ASN1_GET(CERT_IssuerAndSNTemplate));

loser:
    if (tmppoolp)
        PORT_FreeArena(tmppoolp, PR_FALSE);

    return (dummy == NULL) ? SECFailure : SECSuccess;
}

/*
 * NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference -
 *                              find cert marked by EncryptionKeyPreference attribute
 *
 * "certdb" - handle for the cert database to look in
 * "DERekp" - DER-encoded value of S/MIME Encryption Key Preference attribute
 *
 * if certificate is supposed to be found among the message's included certificates,
 * they are assumed to have been imported already.
 */
CERTCertificate *
NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(CERTCertDBHandle *certdb, SECItem *DERekp)
{
    PLArenaPool *tmppoolp = NULL;
    CERTCertificate *cert = NULL;
    NSSSMIMEEncryptionKeyPreference ekp;

    tmppoolp = PORT_NewArena(1024);
    if (tmppoolp == NULL)
        return NULL;

    /* decode DERekp */
    if (SEC_QuickDERDecodeItem(tmppoolp, &ekp, smime_encryptionkeypref_template,
                               DERekp) != SECSuccess)
        goto loser;

    /* find cert */
    switch (ekp.selector) {
        case NSSSMIMEEncryptionKeyPref_IssuerSN:
            cert = CERT_FindCertByIssuerAndSN(certdb, ekp.id.issuerAndSN);
            break;
        case NSSSMIMEEncryptionKeyPref_RKeyID:
        case NSSSMIMEEncryptionKeyPref_SubjectKeyID:
            /* XXX not supported yet - we need to be able to look up certs by SubjectKeyID */
            break;
        default:
            PORT_Assert(0);
    }
loser:
    if (tmppoolp)
        PORT_FreeArena(tmppoolp, PR_FALSE);

    return cert;
}

extern const char __nss_smime_version[];

PRBool
NSSSMIME_VersionCheck(const char *importedVersion)
{
#define NSS_VERSION_VARIABLE __nss_smime_version
#include "verref.h"
    /*
     * This is the secret handshake algorithm.
     *
     * This release has a simple version compatibility
     * check algorithm.  This release is not backward
     * compatible with previous major releases.  It is
     * not compatible with future major, minor, or
     * patch releases.
     */
    return NSS_VersionCheck(importedVersion);
}

const char *
NSSSMIME_GetVersion(void)
{
    return NSS_VERSION;
}
