/* 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
#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)
}
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;
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;
{
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
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);
/* Finalize signatures */
PKCS7_dataFinal(p7, p7bio);
- /* Now remove any digests from output BIO */
+ /* Now remove any digests prepended to the BIO */
- while (1)
+ while (p7bio != out)
{
tmpbio = BIO_pop(p7bio);
- if (tmpbio == out)
- break;
- BIO_free(tmpbio);
+ BIO_free(p7bio);
+ p7bio = tmpbio;
}
return 1;
}
-/* 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
*/