/* * 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); } }
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); }