Commit 27068df7 authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Single pass processing to cleartext S/MIME signing.

parent b12753df
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -4,6 +4,17 @@

 Changes between 0.9.7a and 0.9.8  [xx XXX xxxx]

  *) Support for single pass processing for S/MIME signing. This now
     means that S/MIME signing can be done from a pipe, in addition
     cleartext signing (multipart/signed type) is effectively streaming
     and the signed data does not need to be all held in memory.

     This is done with a new flag PKCS7_PARTSIGN. When this flag is set
     PKCS7_sign() only initializes the PKCS7 structure and the actual signing
     is done after the data is output (and digests calculated) in
     SMIME_write_PKCS7().
     [Steve Henson]

  *) Add full support for -rpath/-R, both in shared libraries and
     applications, at least on the platforms where it's known how
     to do it.
+9 −3
Original line number Diff line number Diff line
/* smime.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 1999.
 * project.
 */
/* ====================================================================
 * 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
@@ -478,8 +478,14 @@ int MAIN(int argc, char **argv)
	if(operation == SMIME_ENCRYPT) {
		p7 = PKCS7_encrypt(encerts, in, cipher, flags);
	} else if(operation == SMIME_SIGN) {
		/* If detached data and SMIME output enable partial
		 * signing.
		 */
		if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME))
			flags |= PKCS7_PARTSIGN;
		p7 = PKCS7_sign(signer, key, other, in, flags);
		if (BIO_reset(in) != 0 && (flags & PKCS7_DETACHED)) {
		/* Don't need to rewind for partial signing */
		if (!(flags & PKCS7_PARTSIGN) && (BIO_reset(in) != 0)) {
		  BIO_printf(bio_err, "Can't rewind input file\n");
		  goto end;
		}
+49 −7
Original line number Diff line number Diff line
/* pk7_mime.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 1999.
 * project.
 */
/* ====================================================================
 * 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
@@ -86,6 +86,7 @@ STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
DECLARE_STACK_OF(MIME_HEADER)
IMPLEMENT_STACK_OF(MIME_HEADER)

static int pkcs7_output_data(BIO *bio, BIO *data, PKCS7 *p7, int flags);
static int B64_write_PKCS7(BIO *bio, PKCS7 *p7);
static PKCS7 *B64_read_PKCS7(BIO *bio);
static char * strip_ends(char *name);
@@ -150,7 +151,6 @@ 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;
	if((flags & PKCS7_DETACHED) && data) {
@@ -171,9 +171,9 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
		BIO_printf(bio, "This is an S/MIME signed message\n\n");
		/* Now write out the first part */
		BIO_printf(bio, "------%s\r\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);

		pkcs7_output_data(bio, data, p7, flags);

		BIO_printf(bio, "\n------%s\n", bound);

		/* Headers for signature */
@@ -195,6 +195,47 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
	return 1;
}

/* Handle output of PKCS#7 data */


static int pkcs7_output_data(BIO *out, BIO *data, PKCS7 *p7, int flags)
	{
	BIO *tmpbio, *p7bio;

	if (!(flags & PKCS7_PARTSIGN))
		{
		SMIME_crlf_copy(data, out, flags);
		return 1;
		}

	/* Partial sign operation */

	/* Initialize sign operation */
	p7bio = PKCS7_dataInit(p7, out);

	/* Copy data across, computing digests etc */
	SMIME_crlf_copy(data, p7bio, flags);

	/* Must be detached */
	PKCS7_set_detached(p7, 1);

	/* Finalize signatures */
	PKCS7_dataFinal(p7, p7bio);

	/* Now remove any digests from output BIO */

	while (1)
		{
		tmpbio = BIO_pop(p7bio);
		if (tmpbio == out)
			break;
		BIO_free(tmpbio);
		}

	return 1;

	}

/* SMIME reader: handle multipart/signed and opaque signing.
 * in multipart case the content is placed in a memory BIO
 * pointed to by "bcont". In opaque this is set to NULL
@@ -314,7 +355,8 @@ int SMIME_crlf_copy(BIO *in, BIO *out, int flags)
						BIO_write(out, linebuf, len);
		return 1;
	}
	if(flags & PKCS7_TEXT) BIO_printf(out, "Content-Type: text/plain\r\n\r\n");
	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 = 0;
		while(iscrlf(linebuf[len - 1])) {
+12 −10
Original line number Diff line number Diff line
/* pk7_smime.c */
/* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
 * project 1999.
 * project.
 */
/* ====================================================================
 * 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
@@ -97,14 +97,6 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
			PKCS7_add_certificate(p7, sk_X509_value(certs, i));
	}

	if(!(p7bio = PKCS7_dataInit(p7, NULL))) {
		PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
		return NULL;
	}


	SMIME_crlf_copy(data, p7bio, flags);

	if(!(flags & PKCS7_NOATTR)) {
		PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
				V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));
@@ -133,6 +125,16 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
		}
	}

	if (flags & PKCS7_PARTSIGN)
		return p7;

	if (!(p7bio = PKCS7_dataInit(p7, NULL))) {
		PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
		return NULL;
	}

	SMIME_crlf_copy(data, p7bio, flags);

	if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1);

        if (!PKCS7_dataFinal(p7,p7bio)) {
+1 −0
Original line number Diff line number Diff line
@@ -260,6 +260,7 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
#define PKCS7_BINARY		0x80
#define PKCS7_NOATTR		0x100
#define	PKCS7_NOSMIMECAP	0x200
#define	PKCS7_PARTSIGN		0x400

/* Flags: for compatibility with older code */