mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-08 08:48:39 +09:00
parent
338383f722
commit
800fce0b81
14 changed files with 282 additions and 215 deletions
|
|
@ -116,7 +116,6 @@ nsMsgAttachmentHandler::nsMsgAttachmentHandler() :
|
|||
m_bogus_attachment(false),
|
||||
m_done(false),
|
||||
m_already_encoded_p(false),
|
||||
m_decrypted_p(false),
|
||||
mDeleteFile(false),
|
||||
mMHTMLPart(false),
|
||||
mPartUserOmissionOverride(false),
|
||||
|
|
|
|||
|
|
@ -140,16 +140,6 @@ public:
|
|||
bool m_already_encoded_p; // If we attach a document that is already
|
||||
// encoded, we just pass it through.
|
||||
|
||||
bool m_decrypted_p; /* S/MIME -- when attaching a message that was
|
||||
encrypted, it's necessary to decrypt it first
|
||||
(since nobody but the original recipient can
|
||||
read it -- if you forward it to someone in the
|
||||
raw, it will be useless to them.) This flag
|
||||
indicates whether decryption occurred, so that
|
||||
libmsg can issue appropriate warnings about
|
||||
doing a cleartext forward of a message that was
|
||||
originally encrypted. */
|
||||
|
||||
bool mDeleteFile; // If this is true, Delete the file...its
|
||||
// NOT the original file!
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include "nsICMSMessageErrors.h"
|
||||
#include "nsICMSDecoder.h"
|
||||
#include "mimecms.h"
|
||||
#include "mimemcms.h"
|
||||
#include "mimemsig.h"
|
||||
#include "nspr.h"
|
||||
#include "mimemsg.h"
|
||||
|
|
@ -28,6 +29,9 @@
|
|||
|
||||
using namespace mozilla::mailnews;
|
||||
|
||||
// The name "mime encrypted" is misleading, because this code is used
|
||||
// both for CMS messages that are encrypted, and also for messages that
|
||||
// aren't encrypted, but only contain a signature.
|
||||
|
||||
#define MIME_SUPERCLASS mimeEncryptedClass
|
||||
MimeDefClass(MimeEncryptedCMS, MimeEncryptedCMSClass,
|
||||
|
|
@ -68,10 +72,11 @@ typedef struct MimeCMSdata
|
|||
bool ci_is_encrypted;
|
||||
char *sender_addr;
|
||||
bool decoding_failed;
|
||||
bool skip_content;
|
||||
uint32_t decoded_bytes;
|
||||
MimeObject *self;
|
||||
bool parent_is_encrypted_p;
|
||||
bool parent_holds_stamp_p;
|
||||
bool any_parent_is_encrypted_p;
|
||||
bool any_parent_is_signed_p;
|
||||
nsCOMPtr<nsIMsgSMIMEHeaderSink> smimeHeaderSink;
|
||||
nsCString url;
|
||||
|
||||
|
|
@ -81,12 +86,11 @@ typedef struct MimeCMSdata
|
|||
ci_is_encrypted(false),
|
||||
sender_addr(nullptr),
|
||||
decoding_failed(false),
|
||||
skip_content(false),
|
||||
decoded_bytes(0),
|
||||
self(nullptr),
|
||||
parent_is_encrypted_p(false),
|
||||
parent_holds_stamp_p(false)
|
||||
{
|
||||
}
|
||||
any_parent_is_encrypted_p(false),
|
||||
any_parent_is_signed_p(false) {}
|
||||
|
||||
~MimeCMSdata()
|
||||
{
|
||||
|
|
@ -140,6 +144,46 @@ bool MimeEncryptedCMS_encrypted_p (MimeObject *obj)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool MimeEncOrMP_CMS_signed_p(MimeObject *obj) {
|
||||
bool is_signed;
|
||||
|
||||
if (!obj) return false;
|
||||
if (mime_typep(obj, (MimeObjectClass *)&mimeMultipartSignedCMSClass)) {
|
||||
return true;
|
||||
}
|
||||
if (mime_typep(obj, (MimeObjectClass *)&mimeEncryptedCMSClass)) {
|
||||
MimeEncrypted *enc = (MimeEncrypted *)obj;
|
||||
MimeCMSdata *data = (MimeCMSdata *)enc->crypto_closure;
|
||||
if (!data || !data->content_info) return false;
|
||||
data->content_info->ContentIsSigned(&is_signed);
|
||||
return is_signed;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MimeAnyParentCMSEncrypted(MimeObject *obj)
|
||||
{
|
||||
MimeObject *o2 = obj;
|
||||
while (o2 && o2->parent) {
|
||||
if (MimeEncryptedCMS_encrypted_p(o2->parent)) {
|
||||
return true;
|
||||
}
|
||||
o2 = o2->parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MimeAnyParentCMSSigned(MimeObject *obj)
|
||||
{
|
||||
MimeObject *o2 = obj;
|
||||
while (o2 && o2->parent) {
|
||||
if (MimeEncOrMP_CMS_signed_p(o2->parent)) {
|
||||
return true;
|
||||
}
|
||||
o2 = o2->parent;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MimeCMSHeadersAndCertsMatch(nsICMSMessage *content_info,
|
||||
nsIX509Cert *signerCert,
|
||||
|
|
@ -439,38 +483,37 @@ static void *MimeCMS_init(MimeObject *obj,
|
|||
data->output_fn = output_fn;
|
||||
data->output_closure = output_closure;
|
||||
PR_SetError(0, 0);
|
||||
data->decoder_context = do_CreateInstance(NS_CMSDECODER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
delete data;
|
||||
return 0;
|
||||
|
||||
data->any_parent_is_signed_p = MimeAnyParentCMSSigned(obj);
|
||||
|
||||
if (data->any_parent_is_signed_p) {
|
||||
// Parent is signed.
|
||||
// We don't know yet if this child is signed or encrypted.
|
||||
// (We'll know after decoding has completed and EOF is called.)
|
||||
// We don't support "inner encrypt" with outer sign, because the
|
||||
// inner encrypted part could have been produced by an attacker who
|
||||
// stripped away a part containing the signature (S/MIME doesn't
|
||||
// have integrity protection).
|
||||
// A sign-then-sign encoding is confusing, too, because it could be
|
||||
// an attempt to influence which signature is shown.
|
||||
data->skip_content = true;
|
||||
}
|
||||
|
||||
rv = data->decoder_context->Start(MimeCMS_content_callback, data);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
delete data;
|
||||
return 0;
|
||||
if (!data->skip_content) {
|
||||
data->decoder_context = do_CreateInstance(NS_CMSDECODER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = data->decoder_context->Start(MimeCMS_content_callback, data);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete data;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX Fix later XXX //
|
||||
data->parent_holds_stamp_p =
|
||||
(obj->parent &&
|
||||
(mime_crypto_stamped_p(obj->parent) ||
|
||||
mime_typep(obj->parent, (MimeObjectClass *) &mimeEncryptedClass)));
|
||||
|
||||
data->parent_is_encrypted_p =
|
||||
(obj->parent && MimeEncryptedCMS_encrypted_p (obj->parent));
|
||||
|
||||
/* If the parent of this object is a crypto-blob, then it's the grandparent
|
||||
who would have written out the headers and prepared for a stamp...
|
||||
(This shit sucks.)
|
||||
*/
|
||||
if (data->parent_is_encrypted_p &&
|
||||
!data->parent_holds_stamp_p &&
|
||||
obj->parent && obj->parent->parent)
|
||||
data->parent_holds_stamp_p =
|
||||
mime_crypto_stamped_p (obj->parent->parent);
|
||||
data->any_parent_is_encrypted_p = MimeAnyParentCMSEncrypted(obj);
|
||||
|
||||
mime_stream_data *msd = (mime_stream_data *) (data->self->options->stream_closure);
|
||||
if (msd)
|
||||
|
|
@ -530,9 +573,11 @@ MimeCMS_write (const char *buf, int32_t buf_size, void *closure)
|
|||
|
||||
if (!data || !data->output_fn || !data->decoder_context) return -1;
|
||||
|
||||
PR_SetError(0, 0);
|
||||
rv = data->decoder_context->Update(buf, buf_size);
|
||||
data->decoding_failed = NS_FAILED(rv);
|
||||
if (!data->decoding_failed && !data->skip_content) {
|
||||
PR_SetError(0, 0);
|
||||
rv = data->decoder_context->Update(buf, buf_size);
|
||||
data->decoding_failed = NS_FAILED(rv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -606,7 +651,12 @@ MimeCMS_eof (void *crypto_closure, bool abort_p)
|
|||
nsresult rv;
|
||||
int32_t status = nsICMSMessageErrors::SUCCESS;
|
||||
|
||||
if (!data || !data->output_fn || !data->decoder_context) {
|
||||
if (!data || !data->output_fn) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!data->skip_content && !data->decoder_context) {
|
||||
// If we don't skip, we should have a context.
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -621,11 +671,12 @@ MimeCMS_eof (void *crypto_closure, bool abort_p)
|
|||
*/
|
||||
|
||||
PR_SetError(0, 0);
|
||||
rv = data->decoder_context->Finish(getter_AddRefs(data->content_info));
|
||||
if (NS_FAILED(rv))
|
||||
status = nsICMSMessageErrors::GENERAL_ERROR;
|
||||
if (!data->skip_content) {
|
||||
rv = data->decoder_context->Finish(getter_AddRefs(data->content_info));
|
||||
if (NS_FAILED(rv)) status = nsICMSMessageErrors::GENERAL_ERROR;
|
||||
|
||||
data->decoder_context = nullptr;
|
||||
data->decoder_context = nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIX509Cert> certOfInterest;
|
||||
|
||||
|
|
@ -644,6 +695,21 @@ MimeCMS_eof (void *crypto_closure, bool abort_p)
|
|||
if (data->decoding_failed)
|
||||
status = nsICMSMessageErrors::GENERAL_ERROR;
|
||||
|
||||
if (data->skip_content) {
|
||||
// Skipping content means, we detected a forbidden combination
|
||||
// of CMS objects, so let's make sure we replace the parent status
|
||||
// with a bad status.
|
||||
if (data->any_parent_is_signed_p) {
|
||||
data->smimeHeaderSink->SignedStatus(aRelativeNestLevel,
|
||||
nsICMSMessageErrors::GENERAL_ERROR, nullptr, data->url);
|
||||
}
|
||||
if (data->any_parent_is_encrypted_p) {
|
||||
data->smimeHeaderSink->EncryptionStatus(aRelativeNestLevel,
|
||||
nsICMSMessageErrors::GENERAL_ERROR, nullptr, data->url);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!data->content_info)
|
||||
{
|
||||
if (!data->decoded_bytes)
|
||||
|
|
|
|||
|
|
@ -418,18 +418,8 @@ MimeEncrypted_emit_buffered_child(MimeObject *obj)
|
|||
obj->options->headers != MimeHeadersCitation &&
|
||||
obj->options->write_html_p &&
|
||||
obj->options->output_fn)
|
||||
// && !mime_crypto_object_p(enc->hdrs, true, obj->options)) // XXX fix later XXX //
|
||||
{
|
||||
char *html;
|
||||
#if 0 // XXX Fix this later XXX //
|
||||
char *html = (((MimeEncryptedClass *) obj->clazz)->crypto_generate_html
|
||||
(enc->crypto_closure));
|
||||
if (!html) return -1; /* MK_OUT_OF_MEMORY? */
|
||||
|
||||
status = MimeObject_write(obj, html, strlen(html), false);
|
||||
PR_FREEIF(html);
|
||||
if (status < 0) return status;
|
||||
#endif
|
||||
|
||||
/* Now that we have written out the crypto stamp, the outermost header
|
||||
block is well and truly closed. If this is in fact the outermost
|
||||
|
|
@ -445,7 +435,8 @@ MimeEncrypted_emit_buffered_child(MimeObject *obj)
|
|||
for (p = obj; p->parent; p = p->parent)
|
||||
outer_headers = p->headers;
|
||||
NS_ASSERTION(obj->options->state->first_data_written_p, "1.2 <mscott@netscape.com> 01 Nov 2001 17:59");
|
||||
html = obj->options->generate_post_header_html_fn(NULL,
|
||||
char *html = obj->options->generate_post_header_html_fn(
|
||||
NULL,
|
||||
obj->options->html_closure,
|
||||
outer_headers);
|
||||
obj->options->state->post_header_html_run_p = true;
|
||||
|
|
|
|||
|
|
@ -234,3 +234,13 @@ MimeExternalObject_displayable_inline_p (MimeObjectClass *clazz,
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#undef MIME_SUPERCLASS
|
||||
#define MIME_SUPERCLASS mimeExternalObjectClass
|
||||
MimeDefClass(MimeSuppressedCrypto, MimeSuppressedCryptoClass,
|
||||
mimeSuppressedCryptoClass, &MIME_SUPERCLASS);
|
||||
|
||||
static int MimeSuppressedCryptoClassInitialize(MimeSuppressedCryptoClass *clazz) {
|
||||
MimeExternalObjectClass *lclass = (MimeExternalObjectClass *)clazz;
|
||||
return MimeExternalObjectClassInitialize(lclass);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,4 +31,20 @@ struct MimeExternalObject {
|
|||
#define MimeExternalObjectClassInitializer(ITYPE,CSUPER) \
|
||||
{ MimeLeafClassInitializer(ITYPE,CSUPER) }
|
||||
|
||||
typedef struct MimeSuppressedCryptoClass MimeSuppressedCryptoClass;
|
||||
typedef struct MimeSuppressedCrypto MimeSuppressedCrypto;
|
||||
|
||||
struct MimeSuppressedCryptoClass {
|
||||
MimeExternalObjectClass eobj;
|
||||
};
|
||||
|
||||
extern "C" MimeSuppressedCryptoClass mimeSuppressedCryptoClass;
|
||||
|
||||
struct MimeSuppressedCrypto {
|
||||
MimeExternalObject eobj;
|
||||
};
|
||||
|
||||
#define MimeSuppressedCryptoClassInitializer(ITYPE, CSUPER) \
|
||||
{ MimeExternalObjectClassInitializer(ITYPE, CSUPER) }
|
||||
|
||||
#endif /* _MIMEEOBJ_H_ */
|
||||
|
|
|
|||
|
|
@ -731,7 +731,7 @@ mime_find_class (const char *content_type, MimeHeaders *hdrs,
|
|||
// Allowing them would leak the plain text in case the part is
|
||||
// cleverly hidden and the decrypted content gets included in
|
||||
// replies and forwards.
|
||||
clazz = (MimeObjectClass *)&mimeExternalObjectClass;
|
||||
clazz = (MimeObjectClass *)&mimeSuppressedCryptoClass;
|
||||
return clazz;
|
||||
}
|
||||
|
||||
|
|
@ -951,9 +951,14 @@ mime_create (const char *content_type, MimeHeaders *hdrs,
|
|||
(clazz != (MimeObjectClass *)&mimeInlineTextRichtextClass) &&
|
||||
(clazz != (MimeObjectClass *)&mimeInlineTextEnrichedClass) &&
|
||||
(clazz != (MimeObjectClass *)&mimeMessageClass) &&
|
||||
(clazz != (MimeObjectClass *)&mimeInlineImageClass) )
|
||||
(clazz != (MimeObjectClass *)&mimeInlineImageClass) ) {
|
||||
// not a special inline type, so show as attachment
|
||||
clazz = (MimeObjectClass *)&mimeExternalObjectClass;
|
||||
// However, mimeSuppressedCryptoClass is treated identically as
|
||||
// mimeExternalObjectClass, let's not lose that type information.
|
||||
if (clazz != (MimeObjectClass *)&mimeSuppressedCryptoClass) {
|
||||
clazz = (MimeObjectClass *)&mimeExternalObjectClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the option `Show Attachments Inline' is off, now would be the time to change our mind... */
|
||||
|
|
@ -1221,21 +1226,6 @@ mime_crypto_object_p(MimeHeaders *hdrs, bool clearsigned_counts, MimeDisplayOpti
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Whether the given object has written out the HTML version of its headers
|
||||
in such a way that it will have a "crypto stamp" next to the headers. If
|
||||
this is true, then the child must write out its HTML slightly differently
|
||||
to take this into account...
|
||||
*/
|
||||
bool
|
||||
mime_crypto_stamped_p(MimeObject *obj)
|
||||
{
|
||||
if (!obj) return false;
|
||||
if (mime_typep (obj, (MimeObjectClass *) &mimeMessageClass))
|
||||
return ((MimeMessage *) obj)->crypto_stamped_p;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif // ENABLE_SMIME
|
||||
|
||||
/* Puts a part-number into a URL. If append_p is true, then the part number
|
||||
|
|
|
|||
|
|
@ -332,14 +332,6 @@ extern void mime_get_crypto_state (MimeObject *obj,
|
|||
bool *signed_p, bool *encrypted_p,
|
||||
bool *signed_ok, bool *encrypted_ok);
|
||||
|
||||
|
||||
/* Whether the given object has written out the HTML version of its headers
|
||||
in such a way that it will have a "crypto stamp" next to the headers. If
|
||||
this is true, then the child must write out its HTML slightly differently
|
||||
to take this into account...
|
||||
*/
|
||||
extern bool mime_crypto_stamped_p(MimeObject *obj);
|
||||
|
||||
/* How the crypto code tells the MimeMessage object what the crypto stamp
|
||||
on it says. */
|
||||
extern void mime_set_crypto_stamp(MimeObject *obj,
|
||||
|
|
@ -352,7 +344,7 @@ public:
|
|||
MimeParseStateObject()
|
||||
{root = 0; separator_queued_p = false; separator_suppressed_p = false;
|
||||
first_part_written_p = false; post_header_html_run_p = false; first_data_written_p = false;
|
||||
decrypted_p = false; strippingPart = false;
|
||||
strippingPart = false;
|
||||
}
|
||||
MimeObject *root; /* The outermost parser object. */
|
||||
|
||||
|
|
@ -376,10 +368,6 @@ public:
|
|||
bool first_data_written_p; /* State used for Mozilla lazy-stream-
|
||||
creation evilness. */
|
||||
|
||||
bool decrypted_p; /* If options->dexlate_p is true, then this
|
||||
will be set to indicate whether any
|
||||
dexlateion did in fact occur.
|
||||
*/
|
||||
nsTArray<nsCString> partsToStrip; /* if we're stripping parts, what parts to strip */
|
||||
nsTArray<nsCString> detachToFiles; /* if we're detaching parts, where each part was detached to */
|
||||
bool strippingPart;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ static int MimeMultCMS_sig_eof (void *, bool);
|
|||
static int MimeMultCMS_sig_init (void *, MimeObject *, MimeHeaders *);
|
||||
static char * MimeMultCMS_generate (void *);
|
||||
static void MimeMultCMS_free (void *);
|
||||
static void MimeMultCMS_suppressed_child(void *crypto_closure);
|
||||
|
||||
extern int SEC_ERROR_CERT_ADDR_MISMATCH;
|
||||
|
||||
|
|
@ -56,6 +57,7 @@ MimeMultipartSignedCMSClassInitialize(MimeMultipartSignedCMSClass *clazz)
|
|||
sclass->crypto_signature_hash = MimeMultCMS_sig_hash;
|
||||
sclass->crypto_signature_eof = MimeMultCMS_sig_eof;
|
||||
sclass->crypto_generate_html = MimeMultCMS_generate;
|
||||
sclass->crypto_notify_suppressed_child = MimeMultCMS_suppressed_child;
|
||||
sclass->crypto_free = MimeMultCMS_free;
|
||||
|
||||
PR_ASSERT(!oclass->class_initialized);
|
||||
|
|
@ -80,8 +82,6 @@ typedef struct MimeMultCMSdata
|
|||
unsigned char* item_data;
|
||||
uint32_t item_len;
|
||||
MimeObject *self;
|
||||
bool parent_is_encrypted_p;
|
||||
bool parent_holds_stamp_p;
|
||||
nsCOMPtr<nsIMsgSMIMEHeaderSink> smimeHeaderSink;
|
||||
nsCString url;
|
||||
|
||||
|
|
@ -90,11 +90,7 @@ typedef struct MimeMultCMSdata
|
|||
sender_addr(nullptr),
|
||||
decoding_failed(false),
|
||||
item_data(nullptr),
|
||||
self(nullptr),
|
||||
parent_is_encrypted_p(false),
|
||||
parent_holds_stamp_p(false)
|
||||
{
|
||||
}
|
||||
self(nullptr) {}
|
||||
|
||||
~MimeMultCMSdata()
|
||||
{
|
||||
|
|
@ -113,7 +109,7 @@ typedef struct MimeMultCMSdata
|
|||
|
||||
/* #### MimeEncryptedCMS and MimeMultipartSignedCMS have a sleazy,
|
||||
incestuous, dysfunctional relationship. */
|
||||
extern bool MimeEncryptedCMS_encrypted_p (MimeObject *obj);
|
||||
extern bool MimeAnyParentCMSSigned(MimeObject *obj);
|
||||
extern void MimeCMSGetFromSender(MimeObject *obj,
|
||||
nsCString &from_addr,
|
||||
nsCString &from_name,
|
||||
|
|
@ -142,82 +138,11 @@ MimeMultCMS_init (MimeObject *obj)
|
|||
int16_t hash_type;
|
||||
nsresult rv;
|
||||
|
||||
ct = MimeHeaders_get (hdrs, HEADER_CONTENT_TYPE, false, false);
|
||||
if (!ct) return 0; /* #### bogus message? out of memory? */
|
||||
micalg = MimeHeaders_get_parameter (ct, PARAM_MICALG, NULL, NULL);
|
||||
PR_Free(ct);
|
||||
ct = 0;
|
||||
if (!micalg) return 0; /* #### bogus message? out of memory? */
|
||||
|
||||
if (!PL_strcasecmp(micalg, PARAM_MICALG_MD5) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_MD5_2))
|
||||
hash_type = nsICryptoHash::MD5;
|
||||
else if (!PL_strcasecmp(micalg, PARAM_MICALG_SHA1) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA1_2) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA1_3) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA1_4) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA1_5))
|
||||
hash_type = nsICryptoHash::SHA1;
|
||||
else if (!PL_strcasecmp(micalg, PARAM_MICALG_SHA256) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA256_2) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA256_3))
|
||||
hash_type = nsICryptoHash::SHA256;
|
||||
else if (!PL_strcasecmp(micalg, PARAM_MICALG_SHA384) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA384_2) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA384_3))
|
||||
hash_type = nsICryptoHash::SHA384;
|
||||
else if (!PL_strcasecmp(micalg, PARAM_MICALG_SHA512) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA512_2) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA512_3))
|
||||
hash_type = nsICryptoHash::SHA512;
|
||||
else if (!PL_strcasecmp(micalg, PARAM_MICALG_MD2))
|
||||
hash_type = nsICryptoHash::MD2;
|
||||
else
|
||||
hash_type = -1;
|
||||
|
||||
PR_Free(micalg);
|
||||
micalg = 0;
|
||||
|
||||
if (hash_type == -1) return 0; /* #### bogus message? */
|
||||
|
||||
data = new MimeMultCMSdata;
|
||||
if (!data)
|
||||
return 0;
|
||||
|
||||
data->self = obj;
|
||||
data->hash_type = hash_type;
|
||||
|
||||
data->data_hash_context = do_CreateInstance("@mozilla.org/security/hash;1", &rv);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
delete data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = data->data_hash_context->Init(data->hash_type);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
delete data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PR_SetError(0,0);
|
||||
|
||||
data->parent_holds_stamp_p =
|
||||
(obj->parent && mime_crypto_stamped_p(obj->parent));
|
||||
|
||||
data->parent_is_encrypted_p =
|
||||
(obj->parent && MimeEncryptedCMS_encrypted_p (obj->parent));
|
||||
|
||||
/* If the parent of this object is a crypto-blob, then it's the grandparent
|
||||
who would have written out the headers and prepared for a stamp...
|
||||
(This s##t s$%#s.)
|
||||
*/
|
||||
if (data->parent_is_encrypted_p &&
|
||||
!data->parent_holds_stamp_p &&
|
||||
obj->parent && obj->parent->parent)
|
||||
data->parent_holds_stamp_p =
|
||||
mime_crypto_stamped_p (obj->parent->parent);
|
||||
|
||||
mime_stream_data *msd = (mime_stream_data *) (data->self->options->stream_closure);
|
||||
if (msd)
|
||||
|
|
@ -266,6 +191,89 @@ MimeMultCMS_init (MimeObject *obj)
|
|||
} // if channel
|
||||
} // if msd
|
||||
|
||||
if (obj->parent && MimeAnyParentCMSSigned(obj)) {
|
||||
// Parent is signed. We know this part is a signature, too, because
|
||||
// multipart doesn't allow encryption.
|
||||
// We don't support "inner sign" with outer sign, because the
|
||||
// inner encrypted part could have been produced by an attacker who
|
||||
// stripped away a part containing the signature (S/MIME doesn't
|
||||
// have integrity protection).
|
||||
// Also we don't want to support sign-then-sign, that's misleading,
|
||||
// which part would be shown as having a signature?
|
||||
// TODO: should we show all contents, without any signature info?
|
||||
|
||||
if (data->smimeHeaderSink) {
|
||||
data->smimeHeaderSink->SignedStatus(
|
||||
MIMEGetRelativeCryptoNestLevel(data->self),
|
||||
nsICMSMessageErrors::GENERAL_ERROR, nullptr, data->url);
|
||||
}
|
||||
delete data;
|
||||
PR_SetError(-1, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ct = MimeHeaders_get(hdrs, HEADER_CONTENT_TYPE, false, false);
|
||||
if (!ct) {
|
||||
delete data;
|
||||
return 0; /* #### bogus message? out of memory? */
|
||||
}
|
||||
micalg = MimeHeaders_get_parameter(ct, PARAM_MICALG, NULL, NULL);
|
||||
PR_Free(ct);
|
||||
ct = 0;
|
||||
if (!micalg) {
|
||||
delete data;
|
||||
return 0; /* #### bogus message? out of memory? */
|
||||
}
|
||||
|
||||
if (!PL_strcasecmp(micalg, PARAM_MICALG_MD5) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_MD5_2))
|
||||
hash_type = nsICryptoHash::MD5;
|
||||
else if (!PL_strcasecmp(micalg, PARAM_MICALG_SHA1) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA1_2) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA1_3) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA1_4) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA1_5))
|
||||
hash_type = nsICryptoHash::SHA1;
|
||||
else if (!PL_strcasecmp(micalg, PARAM_MICALG_SHA256) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA256_2) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA256_3))
|
||||
hash_type = nsICryptoHash::SHA256;
|
||||
else if (!PL_strcasecmp(micalg, PARAM_MICALG_SHA384) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA384_2) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA384_3))
|
||||
hash_type = nsICryptoHash::SHA384;
|
||||
else if (!PL_strcasecmp(micalg, PARAM_MICALG_SHA512) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA512_2) ||
|
||||
!PL_strcasecmp(micalg, PARAM_MICALG_SHA512_3))
|
||||
hash_type = nsICryptoHash::SHA512;
|
||||
else
|
||||
hash_type = -1;
|
||||
|
||||
PR_Free(micalg);
|
||||
micalg = 0;
|
||||
|
||||
if (hash_type == -1) {
|
||||
delete data;
|
||||
return 0; /* #### bogus message? */
|
||||
}
|
||||
|
||||
data->hash_type = hash_type;
|
||||
|
||||
data->data_hash_context =
|
||||
do_CreateInstance("@mozilla.org/security/hash;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = data->data_hash_context->Init(data->hash_type);
|
||||
if (NS_FAILED(rv)) {
|
||||
delete data;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PR_SetError(0, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
@ -400,6 +408,17 @@ MimeMultCMS_free (void *crypto_closure)
|
|||
delete data;
|
||||
}
|
||||
|
||||
static void MimeMultCMS_suppressed_child(void *crypto_closure) {
|
||||
// I'm a multipart/signed. If one of my cryptographic child elements
|
||||
// was suppressed, then I want my signature to be shown as invalid.
|
||||
MimeMultCMSdata *data = (MimeMultCMSdata *)crypto_closure;
|
||||
if (data && data->smimeHeaderSink) {
|
||||
data->smimeHeaderSink->SignedStatus(
|
||||
MIMEGetRelativeCryptoNestLevel(data->self),
|
||||
nsICMSMessageErrors::GENERAL_ERROR, nullptr, data->url);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
MimeMultCMS_generate (void *crypto_closure)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -786,34 +786,22 @@ MimeMessage_write_headers_html (MimeObject *obj)
|
|||
return status;
|
||||
}
|
||||
|
||||
if (!msg->crypto_stamped_p)
|
||||
{
|
||||
/* If we're not writing a xlation stamp, and this is the outermost
|
||||
message, then now is the time to run the post_header_html_fn.
|
||||
(Otherwise, it will be run when the xlation-stamp is finally
|
||||
closed off, in MimeXlateed_emit_buffered_child() or
|
||||
MimeMultipartSigned_emit_child().)
|
||||
*/
|
||||
if (obj->options &&
|
||||
obj->options->state &&
|
||||
// If this is the outermost message, then now is the time to run the
|
||||
// post_header_html_fn.
|
||||
if (obj->options && obj->options->state &&
|
||||
obj->options->generate_post_header_html_fn &&
|
||||
!obj->options->state->post_header_html_run_p)
|
||||
{
|
||||
char *html = 0;
|
||||
PR_ASSERT(obj->options->state->first_data_written_p);
|
||||
html = obj->options->generate_post_header_html_fn(NULL,
|
||||
obj->options->html_closure,
|
||||
msg->hdrs);
|
||||
obj->options->state->post_header_html_run_p = true;
|
||||
if (html)
|
||||
{
|
||||
status = MimeObject_write(obj, html, strlen(html), false);
|
||||
PR_Free(html);
|
||||
if (status < 0)
|
||||
{
|
||||
mimeEmitterEndHeader(obj->options, obj);
|
||||
return status;
|
||||
}
|
||||
!obj->options->state->post_header_html_run_p) {
|
||||
char *html = 0;
|
||||
PR_ASSERT(obj->options->state->first_data_written_p);
|
||||
html = obj->options->generate_post_header_html_fn(
|
||||
NULL, obj->options->html_closure, msg->hdrs);
|
||||
obj->options->state->post_header_html_run_p = true;
|
||||
if (html) {
|
||||
status = MimeObject_write(obj, html, strlen(html), false);
|
||||
PR_Free(html);
|
||||
if (status < 0) {
|
||||
mimeEmitterEndHeader(obj->options, obj);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,12 +25,6 @@ struct MimeMessage {
|
|||
MimeContainer container; /* superclass variables */
|
||||
MimeHeaders *hdrs; /* headers of this message */
|
||||
bool newline_p; /* whether the last line ended in a newline */
|
||||
bool crypto_stamped_p; /* whether the header of this message has been
|
||||
emitted expecting its child to emit HTML
|
||||
which says that it is xlated. */
|
||||
|
||||
bool crypto_msg_signed_p; /* What the emitted xlation-stamp *says*. */
|
||||
bool crypto_msg_encrypted_p;
|
||||
bool grabSubject; /* Should we try to grab the subject of this message */
|
||||
int32_t bodyLength; /* Used for determining if the body has been truncated */
|
||||
int32_t sizeSoFar; /* The total size of the MIME message, once parsing is
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
#include "msgCore.h"
|
||||
#include "nsMimeStringResources.h"
|
||||
#include "mimemoz2.h"
|
||||
#include "mimeeobj.h"
|
||||
#include "nsIMimeConverter.h" // for MimeConverterOutputCallback
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
|
|
@ -32,6 +33,8 @@ static void MimeMultipartSigned_finalize (MimeObject *);
|
|||
|
||||
static int MimeMultipartSigned_emit_child (MimeObject *obj);
|
||||
|
||||
extern "C" MimeSuppressedCryptoClass mimeSuppressedCryptoClass;
|
||||
|
||||
static int
|
||||
MimeMultipartSignedClassInitialize(MimeMultipartSignedClass *clazz)
|
||||
{
|
||||
|
|
@ -582,6 +585,11 @@ MimeMultipartSigned_emit_child (MimeObject *obj)
|
|||
int status = 0;
|
||||
MimeObject *body;
|
||||
|
||||
if (!sig->crypto_closure) {
|
||||
// We might have decided to skip processing this part.
|
||||
return 0;
|
||||
}
|
||||
|
||||
NS_ASSERTION(sig->crypto_closure, "no crypto closure");
|
||||
|
||||
/* Emit some HTML saying whether the signature was cool.
|
||||
|
|
@ -594,15 +602,11 @@ MimeMultipartSigned_emit_child (MimeObject *obj)
|
|||
obj->options->headers != MimeHeadersCitation &&
|
||||
sig->crypto_closure)
|
||||
{
|
||||
// Calling crypto_generate_html may trigger wanted side effects,
|
||||
// but we're no longer using its results.
|
||||
char *html = (((MimeMultipartSignedClass *) obj->clazz)
|
||||
->crypto_generate_html (sig->crypto_closure));
|
||||
#if 0 // XXX For the moment, no HTML output. Fix this XXX //
|
||||
if (!html) return -1; /* MIME_OUT_OF_MEMORY? */
|
||||
|
||||
status = MimeObject_write(obj, html, strlen(html), false);
|
||||
PR_Free(html);
|
||||
if (status < 0) return status;
|
||||
#endif
|
||||
PR_FREEIF(html);
|
||||
|
||||
/* Now that we have written out the crypto stamp, the outermost header
|
||||
block is well and truly closed. If this is in fact the outermost
|
||||
|
|
@ -719,6 +723,11 @@ MimeMultipartSigned_emit_child (MimeObject *obj)
|
|||
if (!body)
|
||||
return -1;
|
||||
|
||||
if (mime_typep(body, (MimeObjectClass *)&mimeSuppressedCryptoClass)) {
|
||||
((MimeMultipartSignedClass *)obj->clazz)
|
||||
->crypto_notify_suppressed_child(sig->crypto_closure);
|
||||
}
|
||||
|
||||
#ifdef MIME_DRAFTS
|
||||
if (body->options->decompose_file_p) {
|
||||
body->options->signed_p = true;
|
||||
|
|
|
|||
|
|
@ -105,6 +105,8 @@ struct MimeMultipartSignedClass {
|
|||
|
||||
char * (*crypto_generate_html) (void *crypto_closure);
|
||||
|
||||
void (*crypto_notify_suppressed_child)(void *crypto_closure);
|
||||
|
||||
void (*crypto_free) (void *crypto_closure);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ extern "C" MimeObjectClass mimeMultipartRelatedClass;
|
|||
extern "C" MimeObjectClass mimeMultipartSignedClass;
|
||||
extern "C" MimeObjectClass mimeInlineTextVCardClass;
|
||||
extern "C" MimeExternalObjectClass mimeExternalObjectClass;
|
||||
extern "C" MimeSuppressedCryptoClass mimeSuppressedCryptoClass;
|
||||
|
||||
#if defined(DEBUG) && defined(XP_UNIX)
|
||||
static int MimeMultipart_debug_print (MimeObject *, PRFileDesc *, int32_t);
|
||||
|
|
@ -471,7 +472,9 @@ MimeMultipart_create_child(MimeObject *obj)
|
|||
part functions set correctly */
|
||||
!mime_typep(body, (MimeObjectClass*) &mimeMultipartClass)
|
||||
#endif
|
||||
&& ! (mime_typep(body, (MimeObjectClass*)&mimeExternalObjectClass) && !strcmp(body->content_type, "text/x-vcard"))
|
||||
&& !((mime_typep(body, (MimeObjectClass *)&mimeExternalObjectClass) ||
|
||||
mime_typep(body, (MimeObjectClass *)&mimeSuppressedCryptoClass)) &&
|
||||
!strcmp(body->content_type, "text/x-vcard"))
|
||||
)
|
||||
{
|
||||
status = obj->options->decompose_file_init_fn ( obj->options->stream_closure, mult->hdrs );
|
||||
|
|
@ -575,7 +578,9 @@ MimeMultipart_close_child(MimeObject *object)
|
|||
part functions set correctly */
|
||||
!mime_typep(kid,(MimeObjectClass*) &mimeMultipartClass)
|
||||
#endif
|
||||
&& !(mime_typep(kid, (MimeObjectClass*)&mimeExternalObjectClass) && !strcmp(kid->content_type, "text/x-vcard"))
|
||||
&& !((mime_typep(kid, (MimeObjectClass *)&mimeExternalObjectClass) ||
|
||||
mime_typep(kid, (MimeObjectClass *)&mimeSuppressedCryptoClass)) &&
|
||||
!strcmp(kid->content_type, "text/x-vcard"))
|
||||
)
|
||||
{
|
||||
status = object->options->decompose_file_close_fn ( object->options->stream_closure );
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue