Esempio n. 1
0
/*
 * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces.
 */
void
NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo)
{
    SECOidTag kind;

    if (cinfo == NULL) {
        return;
    }

    kind = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
    switch (kind) {
        case SEC_OID_PKCS7_ENVELOPED_DATA:
            NSS_CMSEnvelopedData_Destroy(cinfo->content.envelopedData);
            break;
        case SEC_OID_PKCS7_SIGNED_DATA:
            NSS_CMSSignedData_Destroy(cinfo->content.signedData);
            break;
        case SEC_OID_PKCS7_ENCRYPTED_DATA:
            NSS_CMSEncryptedData_Destroy(cinfo->content.encryptedData);
            break;
        case SEC_OID_PKCS7_DIGESTED_DATA:
            NSS_CMSDigestedData_Destroy(cinfo->content.digestedData);
            break;
        default:
            NSS_CMSGenericWrapperData_Destroy(kind, cinfo->content.genericData);
            /* XXX Anything else that needs to be "manually" freed/destroyed? */
            break;
    }
    if (cinfo->privateInfo) {
        nss_cmsContentInfo_private_destroy(cinfo->privateInfo);
        cinfo->privateInfo = NULL;
    }
    if (cinfo->bulkkey) {
        PK11_FreeSymKey(cinfo->bulkkey);
    }
}
Esempio n. 2
0
UtlBoolean SmimeBody::nssSmimeEncrypt(int numResipientCerts,
                           const char* derPublicKeyCerts[],
                           int derPublicKeyCertLengths[],
                           const char* dataToEncrypt,
                           int dataToEncryptLength,
                           UtlBoolean encryptedDataInBase64Format,
                           UtlString& encryptedData)
{
    UtlBoolean encryptionSucceeded = FALSE;
    encryptedData.remove(0);

#ifdef ENABLE_NSS_SMIME

    // nickname can be NULL as we are not putting this in a database
    char *nickname = NULL;
    // copyDER = true so we copy the DER format cert passed in so memory
    // is internally alloc'd and freed
    PRBool copyDER = true;

    // Create an envelope or container for the encrypted data
    SECOidTag algorithm = SEC_OID_DES_EDE3_CBC; // or  SEC_OID_AES_128_CBC
    // Should be able to get the key size from the cert somehow
    int keysize = 1024;
    NSSCMSMessage* cmsMessage = NSS_CMSMessage_Create(NULL);
    NSSCMSEnvelopedData* myEnvelope =
        NSS_CMSEnvelopedData_Create(cmsMessage, algorithm, keysize);

    // Do the following for each recipient if there is more than one.
    // For each recipient:
    for(int certIndex = 0; certIndex < numResipientCerts; certIndex++)
    {
        // Convert the DER to a NSS CERT
        SECItem derFormatCertItem;
        SECItem* derFormatCertItemPtr = &derFormatCertItem;
        derFormatCertItem.data = (unsigned char*) derPublicKeyCerts[certIndex];
        derFormatCertItem.len = derPublicKeyCertLengths[certIndex];
        CERTCertificate* myCertFromDer = NULL;
        myCertFromDer = __CERT_DecodeDERCertificate(&derFormatCertItem,
                                                   copyDER,
                                                   nickname);

        // Add just the recipient Subject key Id, if it exists to the envelope
        // This is the minimal information needed to identify which recipient
        // the the symetric/session key is encrypted for
        NSSCMSRecipientInfo* recipientInfo = NULL;

        // Add the full set of recipient information including
        // the Cert. issuer location and org. info.
        recipientInfo =
            NSS_CMSRecipientInfo_Create(cmsMessage, myCertFromDer);

        if(recipientInfo)
        {
            if(NSS_CMSEnvelopedData_AddRecipient(myEnvelope , recipientInfo) !=
                SECSuccess)
            {
                NSS_CMSEnvelopedData_Destroy(myEnvelope);
                myEnvelope = NULL;
                NSS_CMSRecipientInfo_Destroy(recipientInfo);
            }
        }
        // No recipientInfo
        else
        {
            NSS_CMSEnvelopedData_Destroy(myEnvelope);
            myEnvelope = NULL;
        }

    } //end for each recipient

    // Get the content out of the envelop
    NSSCMSContentInfo* envelopContentInfo =
       NSS_CMSEnvelopedData_GetContentInfo(myEnvelope);

    //TODO: why are we copying or setting the content pointer from the envelope into the msg????????
    if (NSS_CMSContentInfo_SetContent_Data(cmsMessage,
                                           envelopContentInfo,
                                           NULL,
                                           PR_FALSE) !=
        SECSuccess)
    {
        // release cmsg and other stuff
        NSS_CMSEnvelopedData_Destroy(myEnvelope);
        myEnvelope = NULL;
    }

    //TODO: why are we copying or setting the content pointer from the message and
    // putting it back into the msg????????
    NSSCMSContentInfo* messageContentInfo =
        NSS_CMSMessage_GetContentInfo(cmsMessage);
    if(NSS_CMSContentInfo_SetContent_EnvelopedData(cmsMessage,
                                                   messageContentInfo,
                                                   myEnvelope) !=
       SECSuccess)
    {
        // release cmsg and other stuff
        NSS_CMSEnvelopedData_Destroy(myEnvelope);
        myEnvelope = NULL;
    }

    if(cmsMessage)
    {
        // Create an encoder  and context to do the encryption.
        // The encodedItem will stort the encoded result
        //SECItem encodedItem;
        //encodedItem.data = NULL;
        //encodedItem.len = 0;
        //SECITEM_AllocItem(NULL, &encodedItem, 0);
        printf("start encoder\n");
        NSSCMSEncoderContext* encoderContext =
            NSS_CMSEncoder_Start(cmsMessage, nssOutToUtlString, &encryptedData, NULL,
                                 NULL, NULL, NULL, NULL, NULL, NULL, NULL);

        // Add encrypted content
        printf("update encoder\n");
        NSS_CMSEncoder_Update(encoderContext, dataToEncrypt, dataToEncryptLength);

        // Finished encrypting
        printf("finish encoder\n");
        NSS_CMSEncoder_Finish(encoderContext);

        myEnvelope = NULL;

        if(encryptedData.length() > 0)
        {
            encryptionSucceeded = TRUE;
        }

        // Clean up the message memory, the envelop gets cleaned up
        // with the message
        NSS_CMSMessage_Destroy(cmsMessage);
        cmsMessage = NULL;
    }

#else
    Os::Logger::instance().log(FAC_SIP, PRI_ERR, "SmimeBody::nssSmimeEncrypt invoked with ENABLE_NSS_SMIME not defined");
#endif

    return(encryptionSucceeded);
}