In BIO_write(), update the write statistics, not the read statistics.
[oweals/openssl.git] / crypto / pkcs7 / pk7_mime.c
index 210ec1e8c4fb670bb596cf4a6140eae697145cf0..bf190360d75b802a69d0cd8e1d67bb514a15ed45 100644 (file)
@@ -1,9 +1,9 @@
 /* pk7_mime.c */
-/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
+/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project.
  */
 /* ====================================================================
- * Copyright (c) 1999-2003 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1999-2005 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
@@ -110,9 +110,6 @@ static void mime_hdr_free(MIME_HEADER *hdr);
 #define MAX_SMLEN 1024
 #define mime_debug(x) /* x */
 
-
-typedef void (*stkfree)();
-
 /* Base 64 read and write of PKCS#7 structure */
 
 static int B64_write_PKCS7(BIO *bio, PKCS7 *p7)
@@ -124,7 +121,7 @@ static int B64_write_PKCS7(BIO *bio, PKCS7 *p7)
        }
        bio = BIO_push(b64, bio);
        i2d_PKCS7_bio(bio, p7);
-       BIO_flush(bio);
+       (void)BIO_flush(bio);
        bio = BIO_pop(bio);
        BIO_free(b64);
        return 1;
@@ -141,7 +138,7 @@ static PKCS7 *B64_read_PKCS7(BIO *bio)
        bio = BIO_push(b64, bio);
        if(!(p7 = d2i_PKCS7_bio(bio, NULL))) 
                PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR);
-       BIO_flush(bio);
+       (void)BIO_flush(bio);
        bio = BIO_pop(bio);
        BIO_free(b64);
        return p7;
@@ -153,11 +150,12 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
 {
        char bound[33], c;
        int i;
-       char *mime_prefix, *mime_eol;
+       char *mime_prefix, *mime_eol, *msg_type=NULL;
        if (flags & PKCS7_NOOLDMIMETYPE)
                mime_prefix = "application/pkcs7-";
        else
                mime_prefix = "application/x-pkcs7-";
+
        if (flags & PKCS7_CRLFEOL)
                mime_eol = "\r\n";
        else
@@ -199,11 +197,30 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
                                                        mime_eol, mime_eol);
                return 1;
        }
+
+       /* Determine smime-type header */
+
+       if (PKCS7_type_is_enveloped(p7))
+               msg_type = "enveloped-data";
+       else if (PKCS7_type_is_signed(p7))
+               {
+               /* If we have any signers it is signed-data othewise 
+                * certs-only.
+                */
+               STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+               sinfos = PKCS7_get_signer_info(p7);
+               if (sk_PKCS7_SIGNER_INFO_num(sinfos) > 0)
+                       msg_type = "signed-data";
+               else
+                       msg_type = "certs-only";
+               }
        /* MIME headers */
        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);
+       if (msg_type)
+               BIO_printf(bio, " smime-type=%s;", msg_type);
        BIO_printf(bio, " name=\"smime.p7m\"%s", mime_eol);
        BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
                                                mime_eol, mime_eol);
@@ -360,57 +377,6 @@ PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
 
 }
 
-/* Copy text from one BIO to another making the output CRLF at EOL */
-int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
-{
-       char eol;
-       int len;
-       char linebuf[MAX_SMLEN];
-       if(flags & PKCS7_BINARY) {
-               while((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0)
-                                               BIO_write(out, linebuf, len);
-               return 1;
-       }
-       if(flags & PKCS7_TEXT)
-               BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
-       while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) {
-               eol = strip_eol(linebuf, &len);
-               if (len)
-                       BIO_write(out, linebuf, len);
-               if(eol) BIO_write(out, "\r\n", 2);
-       }
-       return 1;
-}
-
-/* Strip off headers if they are text/plain */
-int SMIME_text(BIO *in, BIO *out)
-{
-       char iobuf[4096];
-       int len;
-       STACK_OF(MIME_HEADER) *headers;
-       MIME_HEADER *hdr;
-
-       if (!(headers = mime_parse_hdr(in))) {
-               PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_PARSE_ERROR);
-               return 0;
-       }
-       if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
-               PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_MIME_NO_CONTENT_TYPE);
-               sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-               return 0;
-       }
-       if (strcmp (hdr->value, "text/plain")) {
-               PKCS7err(PKCS7_F_SMIME_TEXT,PKCS7_R_INVALID_MIME_TYPE);
-               ERR_add_error_data(2, "type: ", hdr->value);
-               sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-               return 0;
-       }
-       sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
-       while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0)
-                                               BIO_write(out, iobuf, len);
-       return 1;
-}
-
 /* Split a multipart/XXX message body into component parts: result is
  * canonical parts in a STACK of bios
  */