NS_IMETHODIMP nsCMSMessage::ContentIsEncrypted(PRBool *isEncrypted) { nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::ContentIsEncrypted\n")); NS_ENSURE_ARG(isEncrypted); if (!m_cmsMsg) return NS_ERROR_FAILURE; *isEncrypted = NSS_CMSMessage_IsEncrypted(m_cmsMsg); return NS_OK; }
static CamelCipherValidity * sm_decrypt(CamelCipherContext *context, CamelMimePart *ipart, CamelMimePart *opart, CamelException *ex) { NSSCMSDecoderContext *dec; NSSCMSMessage *cmsg; CamelStreamMem *istream; CamelStream *ostream; CamelCipherValidity *valid = NULL; /* FIXME: This assumes the content is only encrypted. Perhaps its ok for this api to do this ... */ ostream = camel_stream_mem_new(); camel_stream_mem_set_secure((CamelStreamMem *)ostream); /* FIXME: stream this to the decoder incrementally */ istream = (CamelStreamMem *)camel_stream_mem_new(); camel_data_wrapper_decode_to_stream(camel_medium_get_content_object((CamelMedium *)ipart), (CamelStream *)istream); camel_stream_reset((CamelStream *)istream); dec = NSS_CMSDecoder_Start(NULL, sm_write_stream, ostream, /* content callback */ NULL, NULL, NULL, NULL); /* decrypt key callback */ if (NSS_CMSDecoder_Update(dec, (char *) istream->buffer->data, istream->buffer->len) != SECSuccess) { printf("decoder update failed\n"); } camel_object_unref(istream); cmsg = NSS_CMSDecoder_Finish(dec); if (cmsg == NULL) { camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Decoder failed, error %d"), PORT_GetError()); goto fail; } #if 0 /* not sure if we really care about this? */ if (!NSS_CMSMessage_IsEncrypted(cmsg)) { camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("S/MIME Decrypt: No encrypted content found")); NSS_CMSMessage_Destroy(cmsg); goto fail; } #endif camel_stream_reset(ostream); camel_data_wrapper_construct_from_stream((CamelDataWrapper *)opart, ostream); if (NSS_CMSMessage_IsSigned(cmsg)) { valid = sm_verify_cmsg(context, cmsg, NULL, ex); } else { valid = camel_cipher_validity_new(); valid->encrypt.description = g_strdup(_("Encrypted content")); valid->encrypt.status = CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED; } NSS_CMSMessage_Destroy(cmsg); fail: camel_object_unref(ostream); return valid; }
/* TODO: This is suboptimal, but the only other solution is to pass around NSSCMSMessages */ guint32 camel_smime_context_describe_part(CamelSMIMEContext *context, CamelMimePart *part) { guint32 flags = 0; CamelContentType *ct; const char *tmp; if (!part) return flags; ct = camel_mime_part_get_content_type(part); if (camel_content_type_is(ct, "multipart", "signed")) { tmp = camel_content_type_param(ct, "protocol"); if (tmp && (g_ascii_strcasecmp(tmp, ((CamelCipherContext *)context)->sign_protocol) == 0 || g_ascii_strcasecmp(tmp, "application/pkcs7-signature") == 0)) flags = CAMEL_SMIME_SIGNED; } else if (camel_content_type_is(ct, "application", "x-pkcs7-mime")) { CamelStreamMem *istream; NSSCMSMessage *cmsg; NSSCMSDecoderContext *dec; /* FIXME: stream this to the decoder incrementally */ istream = (CamelStreamMem *)camel_stream_mem_new(); camel_data_wrapper_decode_to_stream(camel_medium_get_content_object((CamelMedium *)part), (CamelStream *)istream); camel_stream_reset((CamelStream *)istream); dec = NSS_CMSDecoder_Start(NULL, NULL, NULL, NULL, NULL, /* password callback */ NULL, NULL); /* decrypt key callback */ NSS_CMSDecoder_Update(dec, (char *) istream->buffer->data, istream->buffer->len); camel_object_unref(istream); cmsg = NSS_CMSDecoder_Finish(dec); if (cmsg) { if (NSS_CMSMessage_IsSigned(cmsg)) { printf("message is signed\n"); flags |= CAMEL_SMIME_SIGNED; } if (NSS_CMSMessage_IsEncrypted(cmsg)) { printf("message is encrypted\n"); flags |= CAMEL_SMIME_ENCRYPTED; } #if 0 if (NSS_CMSMessage_ContainsCertsOrCrls(cmsg)) { printf("message contains certs or crls\n"); flags |= CAMEL_SMIME_CERTS; } #endif NSS_CMSMessage_Destroy(cmsg); } else { printf("Message could not be parsed\n"); } } return flags; }