Various S/MIME bug and compatibility fixes.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 1 Jun 2003 20:45:44 +0000 (20:45 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 1 Jun 2003 20:45:44 +0000 (20:45 +0000)
CHANGES
apps/smime.c
crypto/pkcs7/pk7_doit.c
crypto/pkcs7/pk7_mime.c
crypto/pkcs7/pk7_smime.c
crypto/pkcs7/pkcs7.h

diff --git a/CHANGES b/CHANGES
index 974c1b92ae37ee0bb23677aeac00084f742dbee0..b1636083b1f8d7f635e7fc77ba895e60c914bba2 100644 (file)
--- 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]
 
index cc248d377bb4a39b6b76a82e8f4317753f47f138..51bc893ffa8ab3e4da3b4e195fe182ac282cde65 100644 (file)
@@ -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"))
index 0060a2ea3df29c3c2d4e424adca03075a4a9f7b3..190ca0e9bf576761369908257111e158da66fb50 100644 (file)
@@ -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);
                }
 
index 086d3942701263e232d1bb31d36dd704aac81e97..17098cc2e6a6662df3d6d8403e0e8bfb6a282322 100644 (file)
@@ -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);
                }
        }
index f0d071e2824a60b3305c918aac8f66a3cecd359b..6e5735de1187c49e814379372d4af5413a5eb883 100644 (file)
@@ -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
index 5819700a85029a8d0a700f0c82fc63594de7a828..15372e18f8c0f448e8baf173635de90f6ce45109 100644 (file)
@@ -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 */