From 3410aa1aa82e9d4af7795c9a8d1d2c7a0be84f59 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Sun, 1 Jun 2003 20:45:44 +0000 Subject: [PATCH] Various S/MIME bug and compatibility fixes. --- CHANGES | 8 ++++- apps/smime.c | 4 +++ crypto/pkcs7/pk7_doit.c | 5 +++ crypto/pkcs7/pk7_mime.c | 70 ++++++++++++++++++++++++++-------------- crypto/pkcs7/pk7_smime.c | 2 +- crypto/pkcs7/pkcs7.h | 2 ++ 6 files changed, 65 insertions(+), 26 deletions(-) diff --git a/CHANGES b/CHANGES index 974c1b92ae..b1636083b1 100644 --- a/CHANGES +++ b/CHANGES @@ -4,7 +4,13 @@ Changes between 0.9.7b and 0.9.7c [xx XXX 2003] - *) + *) Various S/MIME bugfixes and compatibility changes: + output correct application/pkcs7 MIME type if + PKCS7_NOOLDMIMETYPE is set. Tolerate some broken signatures. + Output CR+LF for EOL if PKCS7_CRLFEOL is set (this makes opening + of files as .eml work). Correctly handle very long lines in MIME + parser. + [Steve Henson] Changes between 0.9.7a and 0.9.7b [10 Apr 2003] diff --git a/apps/smime.c b/apps/smime.c index cc248d377b..51bc893ffa 100644 --- a/apps/smime.c +++ b/apps/smime.c @@ -168,6 +168,10 @@ int MAIN(int argc, char **argv) flags |= PKCS7_BINARY; else if (!strcmp (*args, "-nosigs")) flags |= PKCS7_NOSIGS; + else if (!strcmp (*args, "-nooldmime")) + flags |= PKCS7_NOOLDMIMETYPE; + else if (!strcmp (*args, "-crlfeol")) + flags |= PKCS7_CRLFEOL; else if (!strcmp (*args, "-crl_check")) store_flags |= X509_V_FLAG_CRL_CHECK; else if (!strcmp (*args, "-crl_check_all")) diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c index 0060a2ea3d..190ca0e9bf 100644 --- a/crypto/pkcs7/pk7_doit.c +++ b/crypto/pkcs7/pk7_doit.c @@ -767,6 +767,11 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, } if (EVP_MD_CTX_type(mdc) == md_type) break; + /* Workaround for some broken clients that put the signature + * OID instead of the digest OID in digest_alg->algorithm + */ + if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) + break; btmp=BIO_next(btmp); } diff --git a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c index 086d394270..17098cc2e6 100644 --- a/crypto/pkcs7/pk7_mime.c +++ b/crypto/pkcs7/pk7_mime.c @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -150,9 +150,17 @@ static PKCS7 *B64_read_PKCS7(BIO *bio) int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) { - char linebuf[MAX_SMLEN]; char bound[33], c; int i; + char *mime_prefix, *mime_eol; + if (flags & PKCS7_NOOLDMIMETYPE) + mime_prefix = "application/pkcs7-"; + else + mime_prefix = "application/x-pkcs7-"; + if (flags & PKCS7_CRLFEOL) + mime_eol = "\r\n"; + else + mime_eol = "\n"; if((flags & PKCS7_DETACHED) && data) { /* We want multipart/signed */ /* Generate a random boundary */ @@ -164,34 +172,42 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) bound[i] = c; } bound[32] = 0; - BIO_printf(bio, "MIME-Version: 1.0\n"); + BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); BIO_printf(bio, "Content-Type: multipart/signed;"); - BIO_printf(bio, " protocol=\"application/x-pkcs7-signature\";"); - BIO_printf(bio, " micalg=sha1; boundary=\"----%s\"\n\n", bound); - BIO_printf(bio, "This is an S/MIME signed message\n\n"); + BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix); + BIO_printf(bio, " micalg=sha1; boundary=\"----%s\"%s%s", + bound, mime_eol, mime_eol); + BIO_printf(bio, "This is an S/MIME signed message%s%s", + mime_eol, mime_eol); /* Now write out the first part */ - BIO_printf(bio, "------%s\n", bound); - if(flags & PKCS7_TEXT) BIO_printf(bio, "Content-Type: text/plain\n\n"); - while((i = BIO_read(data, linebuf, MAX_SMLEN)) > 0) - BIO_write(bio, linebuf, i); - BIO_printf(bio, "\n------%s\n", bound); + BIO_printf(bio, "------%s%s", bound, mime_eol); + SMIME_crlf_copy(data, bio, flags); + BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol); /* Headers for signature */ - BIO_printf(bio, "Content-Type: application/x-pkcs7-signature; name=\"smime.p7s\"\n"); - BIO_printf(bio, "Content-Transfer-Encoding: base64\n"); - BIO_printf(bio, "Content-Disposition: attachment; filename=\"smime.p7s\"\n\n"); + BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix); + BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol); + BIO_printf(bio, "Content-Transfer-Encoding: base64%s", + mime_eol); + BIO_printf(bio, "Content-Disposition: attachment;"); + BIO_printf(bio, " filename=\"smime.p7s\"%s%s", + mime_eol, mime_eol); B64_write_PKCS7(bio, p7); - BIO_printf(bio,"\n------%s--\n\n", bound); + BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound, + mime_eol, mime_eol); return 1; } /* MIME headers */ - BIO_printf(bio, "MIME-Version: 1.0\n"); - BIO_printf(bio, "Content-Disposition: attachment; filename=\"smime.p7m\"\n"); - BIO_printf(bio, "Content-Type: application/x-pkcs7-mime; name=\"smime.p7m\"\n"); - BIO_printf(bio, "Content-Transfer-Encoding: base64\n\n"); + BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); + BIO_printf(bio, "Content-Disposition: attachment;"); + BIO_printf(bio, " filename=\"smime.p7m\"%s", mime_eol); + BIO_printf(bio, "Content-Type: %smime;", mime_prefix); + BIO_printf(bio, " name=\"smime.p7m\"%s", mime_eol); + BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s", + mime_eol, mime_eol); B64_write_PKCS7(bio, p7); - BIO_printf(bio, "\n"); + BIO_printf(bio, "%s", mime_eol); return 1; } @@ -364,6 +380,7 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret) { char linebuf[MAX_SMLEN]; int len, blen; + int eol = 0, next_eol = 0; BIO *bpart = NULL; STACK_OF(BIO) *parts; char state, part, first; @@ -383,14 +400,19 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret) sk_BIO_push(parts, bpart); return 1; } else if(part) { + /* Strip CR+LF from linebuf */ + next_eol = 0; + while(iscrlf(linebuf[len - 1])) { + next_eol = 1; + len--; + } if(first) { first = 0; if(bpart) sk_BIO_push(parts, bpart); bpart = BIO_new(BIO_s_mem()); - - } else BIO_write(bpart, "\r\n", 2); - /* Strip CR+LF from linebuf */ - while(iscrlf(linebuf[len - 1])) len--; + } else if (eol) + BIO_write(bpart, "\r\n", 2); + eol = next_eol; BIO_write(bpart, linebuf, len); } } diff --git a/crypto/pkcs7/pk7_smime.c b/crypto/pkcs7/pk7_smime.c index f0d071e282..6e5735de11 100644 --- a/crypto/pkcs7/pk7_smime.c +++ b/crypto/pkcs7/pk7_smime.c @@ -3,7 +3,7 @@ * project 1999. */ /* ==================================================================== - * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/crypto/pkcs7/pkcs7.h b/crypto/pkcs7/pkcs7.h index 5819700a85..15372e18f8 100644 --- a/crypto/pkcs7/pkcs7.h +++ b/crypto/pkcs7/pkcs7.h @@ -260,6 +260,8 @@ DECLARE_PKCS12_STACK_OF(PKCS7) #define PKCS7_BINARY 0x80 #define PKCS7_NOATTR 0x100 #define PKCS7_NOSMIMECAP 0x200 +#define PKCS7_NOOLDMIMETYPE 0x400 +#define PKCS7_CRLFEOL 0x800 /* Flags: for compatibility with older code */ -- 2.25.1