Example #1
0
/*
 * 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;
}
Example #2
0
/*
 * 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;
}
Example #3
0
/*
 * SecSMIMEFindBulkAlgForRecipients - 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...
 */
OSStatus
SecSMIMEFindBulkAlgForRecipients(SecCertificateRef *rcerts, SECOidTag *bulkalgtag, int *keysize)
{
    unsigned long cipher;
    int mapi;

    cipher = smime_choose_cipher(NULL, rcerts);
    mapi = smime_mapi_by_cipher(cipher);
    if (mapi < 0) {
        return SECFailure;
    }

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

    return SECSuccess;
}