Browse Source

Add -resign and -md options to smime command to support resigning an
existing structure and using alternative digest for signing.

Dr. Stephen Henson 18 years ago
parent
commit
5531192151
7 changed files with 140 additions and 67 deletions
  1. 5 0
      CHANGES
  2. 84 65
      apps/smime.c
  3. 0 1
      crypto/pkcs7/pk7_doit.c
  4. 1 1
      crypto/pkcs7/pk7_mime.c
  5. 45 0
      crypto/pkcs7/pk7_smime.c
  6. 3 0
      crypto/pkcs7/pkcs7.h
  7. 2 0
      crypto/pkcs7/pkcs7err.c

+ 5 - 0
CHANGES

@@ -4,6 +4,11 @@
 
 
  Changes between 0.9.8b and 0.9.9  [xx XXX xxxx]
  Changes between 0.9.8b and 0.9.9  [xx XXX xxxx]
 
 
+  *) New -resign option to smime utility. This adds one or more signers
+     to an existing PKCS#7 signedData structure. Also -md option to use an
+     alternative message digest algorithm for signing.
+     [Steve Henson]
+
   *) Tidy up PKCS#7 routines and add new functions to make it easier to
   *) Tidy up PKCS#7 routines and add new functions to make it easier to
      create PKCS7 structures containing multiple signers. Update smime
      create PKCS7 structures containing multiple signers. Update smime
      application to support multiple signers.
      application to support multiple signers.

+ 84 - 65
apps/smime.c

@@ -73,11 +73,14 @@ static int save_certs(char *signerfile, STACK_OF(X509) *signers);
 static int smime_cb(int ok, X509_STORE_CTX *ctx);
 static int smime_cb(int ok, X509_STORE_CTX *ctx);
 
 
 #define SMIME_OP	0x10
 #define SMIME_OP	0x10
+#define SMIME_IP	0x20
+#define SMIME_SIGNERS	0x40
 #define SMIME_ENCRYPT	(1 | SMIME_OP)
 #define SMIME_ENCRYPT	(1 | SMIME_OP)
-#define SMIME_DECRYPT	2
-#define SMIME_SIGN	(3 | SMIME_OP)
-#define SMIME_VERIFY	4
-#define SMIME_PK7OUT	5
+#define SMIME_DECRYPT	(2 | SMIME_IP)
+#define SMIME_SIGN	(3 | SMIME_OP | SMIME_SIGNERS)
+#define SMIME_VERIFY	(4 | SMIME_IP)
+#define SMIME_PK7OUT	(5 | SMIME_OP)
+#define SMIME_RESIGN	(6 | SMIME_IP | SMIME_OP | SMIME_SIGNERS)
 
 
 int MAIN(int, char **);
 int MAIN(int, char **);
 
 
@@ -106,6 +109,7 @@ int MAIN(int argc, char **argv)
 	char *passargin = NULL, *passin = NULL;
 	char *passargin = NULL, *passin = NULL;
 	char *inrand = NULL;
 	char *inrand = NULL;
 	int need_rand = 0;
 	int need_rand = 0;
+	const EVP_MD *sign_md = NULL;
 	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
 	int informat = FORMAT_SMIME, outformat = FORMAT_SMIME;
         int keyform = FORMAT_PEM;
         int keyform = FORMAT_PEM;
 #ifndef OPENSSL_NO_ENGINE
 #ifndef OPENSSL_NO_ENGINE
@@ -136,6 +140,8 @@ int MAIN(int argc, char **argv)
 			operation = SMIME_DECRYPT;
 			operation = SMIME_DECRYPT;
 		else if (!strcmp (*args, "-sign"))
 		else if (!strcmp (*args, "-sign"))
 			operation = SMIME_SIGN;
 			operation = SMIME_SIGN;
+		else if (!strcmp (*args, "-resign"))
+			operation = SMIME_RESIGN;
 		else if (!strcmp (*args, "-verify"))
 		else if (!strcmp (*args, "-verify"))
 			operation = SMIME_VERIFY;
 			operation = SMIME_VERIFY;
 		else if (!strcmp (*args, "-pk7out"))
 		else if (!strcmp (*args, "-pk7out"))
@@ -252,6 +258,18 @@ int MAIN(int argc, char **argv)
 				goto argerr;
 				goto argerr;
 			recipfile = *++args;
 			recipfile = *++args;
 			}
 			}
+		else if (!strcmp (*args, "-md"))
+			{
+			if (!args[1])
+				goto argerr;
+			sign_md = EVP_get_digestbyname(*++args);
+			if (sign_md == NULL)
+				{
+				BIO_printf(bio_err, "Unknown digest %s\n",
+							*args);
+				goto argerr;
+				}
+			}
 		else if (!strcmp (*args, "-inkey"))
 		else if (!strcmp (*args, "-inkey"))
 			{
 			{
 			if (!args[1])	
 			if (!args[1])	
@@ -335,13 +353,13 @@ int MAIN(int argc, char **argv)
 		args++;
 		args++;
 		}
 		}
 
 
-	if ((operation != SMIME_SIGN) && (skkeys || sksigners))
+	if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners))
 		{
 		{
 		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
 		BIO_puts(bio_err, "Multiple signers or keys not allowed\n");
 		goto argerr;
 		goto argerr;
 		}
 		}
 
 
-	if (operation == SMIME_SIGN)
+	if (operation & SMIME_SIGNERS)
 		{
 		{
 		/* Check to see if any final signer needs to be appended */
 		/* Check to see if any final signer needs to be appended */
 		if (keyfile && !signerfile)
 		if (keyfile && !signerfile)
@@ -468,13 +486,11 @@ int MAIN(int argc, char **argv)
 
 
 	ret = 2;
 	ret = 2;
 
 
-	if (operation != SMIME_SIGN)
+	if (!(operation & SMIME_SIGNERS))
 		flags &= ~PKCS7_DETACHED;
 		flags &= ~PKCS7_DETACHED;
 
 
 	if (operation & SMIME_OP)
 	if (operation & SMIME_OP)
 		{
 		{
-		if (flags & PKCS7_BINARY)
-			inmode = "rb";
 		if (outformat == FORMAT_ASN1)
 		if (outformat == FORMAT_ASN1)
 			outmode = "wb";
 			outmode = "wb";
 		}
 		}
@@ -482,9 +498,18 @@ int MAIN(int argc, char **argv)
 		{
 		{
 		if (flags & PKCS7_BINARY)
 		if (flags & PKCS7_BINARY)
 			outmode = "wb";
 			outmode = "wb";
+		}
+
+	if (operation & SMIME_IP)
+		{
 		if (informat == FORMAT_ASN1)
 		if (informat == FORMAT_ASN1)
 			inmode = "rb";
 			inmode = "rb";
 		}
 		}
+	else
+		{
+		if (flags & PKCS7_BINARY)
+			inmode = "rb";
+		}
 
 
 	if (operation == SMIME_ENCRYPT)
 	if (operation == SMIME_ENCRYPT)
 		{
 		{
@@ -514,26 +539,11 @@ int MAIN(int argc, char **argv)
 			}
 			}
 		}
 		}
 
 
-	if (signerfile && (operation == SMIME_SIGN))
-		{
-		if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM, NULL,
-			e, "signer certificate")))
-			{
-#if 0			/* An appropri message has already been printed */
-			BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile);
-#endif
-			goto end;
-			}
-		}
-
 	if (certfile)
 	if (certfile)
 		{
 		{
 		if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
 		if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL,
 			e, "certificate file")))
 			e, "certificate file")))
 			{
 			{
-#if 0			/* An appropriate message has already been printed */
-			BIO_printf(bio_err, "Can't read certificate file %s\n", certfile);
-#endif
 			ERR_print_errors(bio_err);
 			ERR_print_errors(bio_err);
 			goto end;
 			goto end;
 			}
 			}
@@ -544,9 +554,6 @@ int MAIN(int argc, char **argv)
 		if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
 		if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL,
 			e, "recipient certificate file")))
 			e, "recipient certificate file")))
 			{
 			{
-#if 0			/* An appropriate message has alrady been printed */
-			BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile);
-#endif
 			ERR_print_errors(bio_err);
 			ERR_print_errors(bio_err);
 			goto end;
 			goto end;
 			}
 			}
@@ -584,6 +591,36 @@ int MAIN(int argc, char **argv)
 	else
 	else
 		in = BIO_new_fp(stdin, BIO_NOCLOSE);
 		in = BIO_new_fp(stdin, BIO_NOCLOSE);
 
 
+	if (operation & SMIME_IP)
+		{
+		if (informat == FORMAT_SMIME) 
+			p7 = SMIME_read_PKCS7(in, &indata);
+		else if (informat == FORMAT_PEM) 
+			p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
+		else if (informat == FORMAT_ASN1) 
+			p7 = d2i_PKCS7_bio(in, NULL);
+		else
+			{
+			BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
+			goto end;
+			}
+
+		if (!p7)
+			{
+			BIO_printf(bio_err, "Error reading S/MIME message\n");
+			goto end;
+			}
+		if (contfile)
+			{
+			BIO_free(indata);
+			if (!(indata = BIO_new_file(contfile, "rb")))
+				{
+				BIO_printf(bio_err, "Can't read content file %s\n", contfile);
+				goto end;
+				}
+			}
+		}
+
 	if (outfile)
 	if (outfile)
 		{
 		{
 		if (!(out = BIO_new_file(outfile, outmode)))
 		if (!(out = BIO_new_file(outfile, outmode)))
@@ -618,16 +655,22 @@ int MAIN(int argc, char **argv)
 
 
 	if (operation == SMIME_ENCRYPT)
 	if (operation == SMIME_ENCRYPT)
 		p7 = PKCS7_encrypt(encerts, in, cipher, flags);
 		p7 = PKCS7_encrypt(encerts, in, cipher, flags);
-	else if (operation == SMIME_SIGN)
+	else if (operation & SMIME_SIGNERS)
 		{
 		{
 		int i;
 		int i;
 		/* If detached data and SMIME output enable partial
 		/* If detached data and SMIME output enable partial
 		 * signing.
 		 * signing.
 		 */
 		 */
-		if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME))
-			flags |= PKCS7_STREAM;
-		flags |= PKCS7_PARTIAL;
-		p7 = PKCS7_sign(NULL, NULL, other, in, flags);
+		if (operation == SMIME_SIGN)
+			{
+			if ((flags & PKCS7_DETACHED)
+				&& (outformat == FORMAT_SMIME))
+				flags |= PKCS7_STREAM;
+			flags |= PKCS7_PARTIAL;
+			p7 = PKCS7_sign(NULL, NULL, other, in, flags);
+			}
+		else
+			flags |= PKCS7_REUSE_DIGEST;
 		for (i = 0; i < sk_num(sksigners); i++)
 		for (i = 0; i < sk_num(sksigners); i++)
 			{
 			{
 			signerfile = sk_value(sksigners, i);
 			signerfile = sk_value(sksigners, i);
@@ -641,15 +684,15 @@ int MAIN(int argc, char **argv)
 			if (!key)
 			if (!key)
 				goto end;
 				goto end;
 			if (!PKCS7_sign_add_signer(p7, signer, key,
 			if (!PKCS7_sign_add_signer(p7, signer, key,
-						NULL, flags))
+						sign_md, flags))
 				goto end;
 				goto end;
 			X509_free(signer);
 			X509_free(signer);
 			signer = NULL;
 			signer = NULL;
 			EVP_PKEY_free(key);
 			EVP_PKEY_free(key);
 			key = NULL;
 			key = NULL;
 			}
 			}
-		/* If not streaming finalize structure */
-		if (!(flags & PKCS7_STREAM))
+		/* If not streaming or resigning finalize structure */
+		if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM))
 			{
 			{
 			if (!PKCS7_final(p7, in, flags))
 			if (!PKCS7_final(p7, in, flags))
 				goto end;
 				goto end;
@@ -660,35 +703,6 @@ int MAIN(int argc, char **argv)
 				}
 				}
 			}
 			}
 		}
 		}
-	else
-		{
-		if (informat == FORMAT_SMIME) 
-			p7 = SMIME_read_PKCS7(in, &indata);
-		else if (informat == FORMAT_PEM) 
-			p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
-		else if (informat == FORMAT_ASN1) 
-			p7 = d2i_PKCS7_bio(in, NULL);
-		else
-			{
-			BIO_printf(bio_err, "Bad input format for PKCS#7 file\n");
-			goto end;
-			}
-
-		if (!p7)
-			{
-			BIO_printf(bio_err, "Error reading S/MIME message\n");
-			goto end;
-			}
-		if (contfile)
-			{
-			BIO_free(indata);
-			if (!(indata = BIO_new_file(contfile, "rb")))
-				{
-				BIO_printf(bio_err, "Can't read content file %s\n", contfile);
-				goto end;
-				}
-			}
-		}
 
 
 	if (!p7)
 	if (!p7)
 		{
 		{
@@ -736,7 +750,12 @@ int MAIN(int argc, char **argv)
 		if (subject)
 		if (subject)
 			BIO_printf(out, "Subject: %s\n", subject);
 			BIO_printf(out, "Subject: %s\n", subject);
 		if (outformat == FORMAT_SMIME) 
 		if (outformat == FORMAT_SMIME) 
-			SMIME_write_PKCS7(out, p7, in, flags);
+			{
+			if (operation == SMIME_RESIGN)
+				SMIME_write_PKCS7(out, p7, indata, flags);
+			else
+				SMIME_write_PKCS7(out, p7, in, flags);
+			}
 		else if (outformat == FORMAT_PEM) 
 		else if (outformat == FORMAT_PEM) 
 			PEM_write_bio_PKCS7(out,p7);
 			PEM_write_bio_PKCS7(out,p7);
 		else if (outformat == FORMAT_ASN1) 
 		else if (outformat == FORMAT_ASN1) 

+ 0 - 1
crypto/pkcs7/pk7_doit.c

@@ -854,7 +854,6 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
 	EVP_MD_CTX_cleanup(&mctx);
 	EVP_MD_CTX_cleanup(&mctx);
 
 
 	ASN1_STRING_set0(si->enc_digest, abuf, siglen);
 	ASN1_STRING_set0(si->enc_digest, abuf, siglen);
-	abuf = NULL;
 
 
 	return 1;
 	return 1;
 
 

+ 1 - 1
crypto/pkcs7/pk7_mime.c

@@ -204,7 +204,7 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
 		msg_type = "enveloped-data";
 		msg_type = "enveloped-data";
 	else if (PKCS7_type_is_signed(p7))
 	else if (PKCS7_type_is_signed(p7))
 		{
 		{
-		/* If we have any signers it is signed-data othewise 
+		/* If we have any signers it is signed-data otherwise 
 		 * certs-only.
 		 * certs-only.
 		 */
 		 */
 		STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
 		STACK_OF(PKCS7_SIGNER_INFO) *sinfos;

+ 45 - 0
crypto/pkcs7/pk7_smime.c

@@ -63,6 +63,8 @@
 #include <openssl/x509.h>
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 #include <openssl/x509v3.h>
 
 
+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
+
 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
 PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
 		  BIO *data, int flags)
 		  BIO *data, int flags)
 {
 {
@@ -198,6 +200,14 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
 				|| !PKCS7_add_attrib_smimecap (si, smcap))
 				|| !PKCS7_add_attrib_smimecap (si, smcap))
 				goto err;
 				goto err;
 			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
 			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
+			smcap = NULL;
+			}
+		if (flags & PKCS7_REUSE_DIGEST)
+			{
+			if (!pkcs7_copy_existing_digest(p7, si))
+				goto err;
+			if (!PKCS7_SIGNER_INFO_sign(si))
+				goto err;
 			}
 			}
 		}
 		}
 	return si;
 	return si;
@@ -209,6 +219,41 @@ PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
 	return NULL;
 	return NULL;
 	}
 	}
 
 
+/* Search for a digest matching SignerInfo digest type and if found
+ * copy across.
+ */
+
+static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
+	{
+	int i;
+	STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
+	PKCS7_SIGNER_INFO *sitmp;
+	ASN1_OCTET_STRING *osdig = NULL;
+	sinfos = PKCS7_get_signer_info(p7);
+	for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
+		{
+		sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
+		if (si == sitmp)
+			break;
+		if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
+			continue;
+		if (!OBJ_cmp(si->digest_alg->algorithm,
+				sitmp->digest_alg->algorithm))
+			{
+			osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
+			break;
+			}
+
+		}
+
+	if (osdig)
+		return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
+
+	PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
+			PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
+	return 0;
+	}
+
 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
 int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
 					BIO *indata, BIO *out, int flags)
 					BIO *indata, BIO *out, int flags)
 {
 {

+ 3 - 0
crypto/pkcs7/pkcs7.h

@@ -270,6 +270,7 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
 #define PKCS7_STREAM		0x1000
 #define PKCS7_STREAM		0x1000
 #define PKCS7_NOCRL		0x2000
 #define PKCS7_NOCRL		0x2000
 #define PKCS7_PARTIAL		0x4000
 #define PKCS7_PARTIAL		0x4000
+#define PKCS7_REUSE_DIGEST	0x8000
 
 
 /* Flags: for compatibility with older code */
 /* Flags: for compatibility with older code */
 
 
@@ -412,6 +413,7 @@ void ERR_load_PKCS7_strings(void);
 #define PKCS7_F_PKCS7_ADD_SIGNATURE			 131
 #define PKCS7_F_PKCS7_ADD_SIGNATURE			 131
 #define PKCS7_F_PKCS7_ADD_SIGNER			 103
 #define PKCS7_F_PKCS7_ADD_SIGNER			 103
 #define PKCS7_F_PKCS7_BIO_ADD_DIGEST			 125
 #define PKCS7_F_PKCS7_BIO_ADD_DIGEST			 125
+#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST		 138
 #define PKCS7_F_PKCS7_CTRL				 104
 #define PKCS7_F_PKCS7_CTRL				 104
 #define PKCS7_F_PKCS7_DATADECODE			 112
 #define PKCS7_F_PKCS7_DATADECODE			 112
 #define PKCS7_F_PKCS7_DATAFINAL				 128
 #define PKCS7_F_PKCS7_DATAFINAL				 128
@@ -462,6 +464,7 @@ void ERR_load_PKCS7_strings(void);
 #define PKCS7_R_NO_CONTENT				 122
 #define PKCS7_R_NO_CONTENT				 122
 #define PKCS7_R_NO_CONTENT_TYPE				 135
 #define PKCS7_R_NO_CONTENT_TYPE				 135
 #define PKCS7_R_NO_DEFAULT_DIGEST			 151
 #define PKCS7_R_NO_DEFAULT_DIGEST			 151
+#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND		 154
 #define PKCS7_R_NO_MULTIPART_BODY_FAILURE		 136
 #define PKCS7_R_NO_MULTIPART_BODY_FAILURE		 136
 #define PKCS7_R_NO_MULTIPART_BOUNDARY			 137
 #define PKCS7_R_NO_MULTIPART_BOUNDARY			 137
 #define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE	 115
 #define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE	 115

+ 2 - 0
crypto/pkcs7/pkcs7err.c

@@ -81,6 +81,7 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
 {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE),	"PKCS7_add_signature"},
 {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE),	"PKCS7_add_signature"},
 {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER),	"PKCS7_add_signer"},
 {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER),	"PKCS7_add_signer"},
 {ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST),	"PKCS7_BIO_ADD_DIGEST"},
 {ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST),	"PKCS7_BIO_ADD_DIGEST"},
+{ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST),	"PKCS7_COPY_EXISTING_DIGEST"},
 {ERR_FUNC(PKCS7_F_PKCS7_CTRL),	"PKCS7_CTRL"},
 {ERR_FUNC(PKCS7_F_PKCS7_CTRL),	"PKCS7_CTRL"},
 {ERR_FUNC(PKCS7_F_PKCS7_DATADECODE),	"PKCS7_dataDecode"},
 {ERR_FUNC(PKCS7_F_PKCS7_DATADECODE),	"PKCS7_dataDecode"},
 {ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL),	"PKCS7_dataFinal"},
 {ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL),	"PKCS7_dataFinal"},
@@ -134,6 +135,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
 {ERR_REASON(PKCS7_R_NO_CONTENT)          ,"no content"},
 {ERR_REASON(PKCS7_R_NO_CONTENT)          ,"no content"},
 {ERR_REASON(PKCS7_R_NO_CONTENT_TYPE)     ,"no content type"},
 {ERR_REASON(PKCS7_R_NO_CONTENT_TYPE)     ,"no content type"},
 {ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST)   ,"no default digest"},
 {ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST)   ,"no default digest"},
+{ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND),"no matching digest type found"},
 {ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
 {ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
 {ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
 {ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
 {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"},
 {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"},