summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/pkcs7
diff options
context:
space:
mode:
authordjm <>2010-10-01 22:54:21 +0000
committerdjm <>2010-10-01 22:54:21 +0000
commit829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2 (patch)
treee03b9f1bd051e844b971936729e9df549a209130 /src/lib/libcrypto/pkcs7
parente6b755d2a53d3cac7a344dfdd6bf7c951cac754c (diff)
downloadopenbsd-829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2.tar.gz
openbsd-829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2.tar.bz2
openbsd-829fd51d4f8dde4a7f3bf54754f3c1d1a502f5e2.zip
import OpenSSL-1.0.0a
Diffstat (limited to 'src/lib/libcrypto/pkcs7')
-rw-r--r--src/lib/libcrypto/pkcs7/bio_pk7.c69
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_asn1.c43
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_attr.c66
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_doit.c486
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_lib.c192
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_mime.c669
-rw-r--r--src/lib/libcrypto/pkcs7/pk7_smime.c263
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7.h59
-rw-r--r--src/lib/libcrypto/pkcs7/pkcs7err.c22
9 files changed, 847 insertions, 1022 deletions
diff --git a/src/lib/libcrypto/pkcs7/bio_pk7.c b/src/lib/libcrypto/pkcs7/bio_pk7.c
new file mode 100644
index 0000000000..c8d06d6cdc
--- /dev/null
+++ b/src/lib/libcrypto/pkcs7/bio_pk7.c
@@ -0,0 +1,69 @@
1/* bio_pk7.c */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project.
4 */
5/* ====================================================================
6 * Copyright (c) 2008 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 */
54
55#include <openssl/asn1.h>
56#include <openssl/pkcs7.h>
57#include <openssl/bio.h>
58
59#ifndef OPENSSL_SYSNAME_NETWARE
60#include <memory.h>
61#endif
62#include <stdio.h>
63
64/* Streaming encode support for PKCS#7 */
65
66BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7)
67 {
68 return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7));
69 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_asn1.c b/src/lib/libcrypto/pkcs7/pk7_asn1.c
index 1f70d31386..b7ec2883cb 100644
--- a/src/lib/libcrypto/pkcs7/pk7_asn1.c
+++ b/src/lib/libcrypto/pkcs7/pk7_asn1.c
@@ -77,10 +77,39 @@ ASN1_ADB(PKCS7) = {
77 ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0)) 77 ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0))
78} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL); 78} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL);
79 79
80ASN1_NDEF_SEQUENCE(PKCS7) = { 80/* PKCS#7 streaming support */
81static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
82 void *exarg)
83{
84 ASN1_STREAM_ARG *sarg = exarg;
85 PKCS7 **pp7 = (PKCS7 **)pval;
86
87 switch(operation)
88 {
89
90 case ASN1_OP_STREAM_PRE:
91 if (PKCS7_stream(&sarg->boundary, *pp7) <= 0)
92 return 0;
93 case ASN1_OP_DETACHED_PRE:
94 sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out);
95 if (!sarg->ndef_bio)
96 return 0;
97 break;
98
99 case ASN1_OP_STREAM_POST:
100 case ASN1_OP_DETACHED_POST:
101 if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0)
102 return 0;
103 break;
104
105 }
106 return 1;
107}
108
109ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = {
81 ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT), 110 ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT),
82 ASN1_ADB_OBJECT(PKCS7) 111 ASN1_ADB_OBJECT(PKCS7)
83}ASN1_NDEF_SEQUENCE_END(PKCS7) 112}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7)
84 113
85IMPLEMENT_ASN1_FUNCTIONS(PKCS7) 114IMPLEMENT_ASN1_FUNCTIONS(PKCS7)
86IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7) 115IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7)
@@ -98,7 +127,8 @@ ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = {
98IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED) 127IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED)
99 128
100/* Minor tweak to operation: free up EVP_PKEY */ 129/* Minor tweak to operation: free up EVP_PKEY */
101static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 130static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
131 void *exarg)
102{ 132{
103 if(operation == ASN1_OP_FREE_POST) { 133 if(operation == ASN1_OP_FREE_POST) {
104 PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; 134 PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval;
@@ -140,7 +170,8 @@ ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = {
140IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE) 170IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE)
141 171
142/* Minor tweak to operation: free up X509 */ 172/* Minor tweak to operation: free up X509 */
143static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) 173static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
174 void *exarg)
144{ 175{
145 if(operation == ASN1_OP_FREE_POST) { 176 if(operation == ASN1_OP_FREE_POST) {
146 PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; 177 PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval;
@@ -161,7 +192,7 @@ IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
161ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = { 192ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = {
162 ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT), 193 ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT),
163 ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR), 194 ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR),
164 ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING, 0) 195 ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0)
165} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT) 196} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT)
166 197
167IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) 198IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT)
@@ -212,3 +243,5 @@ ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) =
212 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, 243 ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL,
213 V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) 244 V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE)
214ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY) 245ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY)
246
247IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7)
diff --git a/src/lib/libcrypto/pkcs7/pk7_attr.c b/src/lib/libcrypto/pkcs7/pk7_attr.c
index d549717169..a97db51210 100644
--- a/src/lib/libcrypto/pkcs7/pk7_attr.c
+++ b/src/lib/libcrypto/pkcs7/pk7_attr.c
@@ -60,6 +60,7 @@
60#include <stdlib.h> 60#include <stdlib.h>
61#include <openssl/bio.h> 61#include <openssl/bio.h>
62#include <openssl/asn1.h> 62#include <openssl/asn1.h>
63#include <openssl/asn1t.h>
63#include <openssl/pem.h> 64#include <openssl/pem.h>
64#include <openssl/pkcs7.h> 65#include <openssl/pkcs7.h>
65#include <openssl/x509.h> 66#include <openssl/x509.h>
@@ -68,27 +69,12 @@
68int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap) 69int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, STACK_OF(X509_ALGOR) *cap)
69{ 70{
70 ASN1_STRING *seq; 71 ASN1_STRING *seq;
71 unsigned char *p, *pp;
72 int len;
73 len=i2d_ASN1_SET_OF_X509_ALGOR(cap,NULL,i2d_X509_ALGOR,
74 V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL,
75 IS_SEQUENCE);
76 if(!(pp=(unsigned char *)OPENSSL_malloc(len))) {
77 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
78 return 0;
79 }
80 p=pp;
81 i2d_ASN1_SET_OF_X509_ALGOR(cap,&p,i2d_X509_ALGOR, V_ASN1_SEQUENCE,
82 V_ASN1_UNIVERSAL, IS_SEQUENCE);
83 if(!(seq = ASN1_STRING_new())) { 72 if(!(seq = ASN1_STRING_new())) {
84 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE); 73 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE);
85 return 0; 74 return 0;
86 } 75 }
87 if(!ASN1_STRING_set (seq, pp, len)) { 76 seq->length = ASN1_item_i2d((ASN1_VALUE *)cap,&seq->data,
88 PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP,ERR_R_MALLOC_FAILURE); 77 ASN1_ITEM_rptr(X509_ALGORS));
89 return 0;
90 }
91 OPENSSL_free (pp);
92 return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities, 78 return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities,
93 V_ASN1_SEQUENCE, seq); 79 V_ASN1_SEQUENCE, seq);
94} 80}
@@ -102,10 +88,9 @@ STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si)
102 if (!cap || (cap->type != V_ASN1_SEQUENCE)) 88 if (!cap || (cap->type != V_ASN1_SEQUENCE))
103 return NULL; 89 return NULL;
104 p = cap->value.sequence->data; 90 p = cap->value.sequence->data;
105 return d2i_ASN1_SET_OF_X509_ALGOR(NULL, &p, 91 return (STACK_OF(X509_ALGOR) *)
106 cap->value.sequence->length, 92 ASN1_item_d2i(NULL, &p, cap->value.sequence->length,
107 d2i_X509_ALGOR, X509_ALGOR_free, 93 ASN1_ITEM_rptr(X509_ALGORS));
108 V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
109 } 94 }
110 95
111/* Basic smime-capabilities OID and optional integer arg */ 96/* Basic smime-capabilities OID and optional integer arg */
@@ -139,3 +124,42 @@ int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
139 sk_X509_ALGOR_push (sk, alg); 124 sk_X509_ALGOR_push (sk, alg);
140 return 1; 125 return 1;
141} 126}
127
128int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid)
129 {
130 if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType))
131 return 0;
132 if (!coid)
133 coid = OBJ_nid2obj(NID_pkcs7_data);
134 return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
135 V_ASN1_OBJECT, coid);
136 }
137
138int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t)
139 {
140 if (!t && !(t=X509_gmtime_adj(NULL,0)))
141 {
142 PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME,
143 ERR_R_MALLOC_FAILURE);
144 return 0;
145 }
146 return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime,
147 V_ASN1_UTCTIME, t);
148 }
149
150int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
151 const unsigned char *md, int mdlen)
152 {
153 ASN1_OCTET_STRING *os;
154 os = ASN1_OCTET_STRING_new();
155 if (!os)
156 return 0;
157 if (!ASN1_STRING_set(os, md, mdlen)
158 || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest,
159 V_ASN1_OCTET_STRING, os))
160 {
161 ASN1_OCTET_STRING_free(os);
162 return 0;
163 }
164 return 1;
165 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_doit.c b/src/lib/libcrypto/pkcs7/pk7_doit.c
index a03d7ebedf..451de84489 100644
--- a/src/lib/libcrypto/pkcs7/pk7_doit.c
+++ b/src/lib/libcrypto/pkcs7/pk7_doit.c
@@ -138,6 +138,121 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
138 138
139 } 139 }
140 140
141static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
142 unsigned char *key, int keylen)
143 {
144 EVP_PKEY_CTX *pctx = NULL;
145 EVP_PKEY *pkey = NULL;
146 unsigned char *ek = NULL;
147 int ret = 0;
148 size_t eklen;
149
150 pkey = X509_get_pubkey(ri->cert);
151
152 if (!pkey)
153 return 0;
154
155 pctx = EVP_PKEY_CTX_new(pkey, NULL);
156 if (!pctx)
157 return 0;
158
159 if (EVP_PKEY_encrypt_init(pctx) <= 0)
160 goto err;
161
162 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
163 EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0)
164 {
165 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
166 goto err;
167 }
168
169 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
170 goto err;
171
172 ek = OPENSSL_malloc(eklen);
173
174 if (ek == NULL)
175 {
176 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
177 goto err;
178 }
179
180 if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
181 goto err;
182
183 ASN1_STRING_set0(ri->enc_key, ek, eklen);
184 ek = NULL;
185
186 ret = 1;
187
188 err:
189 if (pkey)
190 EVP_PKEY_free(pkey);
191 if (pctx)
192 EVP_PKEY_CTX_free(pctx);
193 if (ek)
194 OPENSSL_free(ek);
195 return ret;
196
197 }
198
199
200static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
201 PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
202 {
203 EVP_PKEY_CTX *pctx = NULL;
204 unsigned char *ek = NULL;
205 size_t eklen;
206
207 int ret = 0;
208
209 pctx = EVP_PKEY_CTX_new(pkey, NULL);
210 if (!pctx)
211 return 0;
212
213 if (EVP_PKEY_decrypt_init(pctx) <= 0)
214 goto err;
215
216 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
217 EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0)
218 {
219 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
220 goto err;
221 }
222
223 if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
224 ri->enc_key->data, ri->enc_key->length) <= 0)
225 goto err;
226
227 ek = OPENSSL_malloc(eklen);
228
229 if (ek == NULL)
230 {
231 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
232 goto err;
233 }
234
235 if (EVP_PKEY_decrypt(pctx, ek, &eklen,
236 ri->enc_key->data, ri->enc_key->length) <= 0)
237 {
238 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
239 goto err;
240 }
241
242 ret = 1;
243
244 *pek = ek;
245 *peklen = eklen;
246
247 err:
248 if (pctx)
249 EVP_PKEY_CTX_free(pctx);
250 if (!ret && ek)
251 OPENSSL_free(ek);
252
253 return ret;
254 }
255
141BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) 256BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
142 { 257 {
143 int i; 258 int i;
@@ -148,7 +263,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
148 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; 263 STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
149 X509_ALGOR *xalg=NULL; 264 X509_ALGOR *xalg=NULL;
150 PKCS7_RECIP_INFO *ri=NULL; 265 PKCS7_RECIP_INFO *ri=NULL;
151 EVP_PKEY *pkey;
152 ASN1_OCTET_STRING *os=NULL; 266 ASN1_OCTET_STRING *os=NULL;
153 267
154 i=OBJ_obj2nid(p7->type); 268 i=OBJ_obj2nid(p7->type);
@@ -187,6 +301,8 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
187 xa = p7->d.digest->md; 301 xa = p7->d.digest->md;
188 os = PKCS7_get_octet_string(p7->d.digest->contents); 302 os = PKCS7_get_octet_string(p7->d.digest->contents);
189 break; 303 break;
304 case NID_pkcs7_data:
305 break;
190 default: 306 default:
191 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE); 307 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
192 goto err; 308 goto err;
@@ -204,8 +320,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
204 unsigned char key[EVP_MAX_KEY_LENGTH]; 320 unsigned char key[EVP_MAX_KEY_LENGTH];
205 unsigned char iv[EVP_MAX_IV_LENGTH]; 321 unsigned char iv[EVP_MAX_IV_LENGTH];
206 int keylen,ivlen; 322 int keylen,ivlen;
207 int jj,max;
208 unsigned char *tmp;
209 EVP_CIPHER_CTX *ctx; 323 EVP_CIPHER_CTX *ctx;
210 324
211 if ((btmp=BIO_new(BIO_f_cipher())) == NULL) 325 if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
@@ -234,52 +348,16 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
234 goto err; 348 goto err;
235 } 349 }
236 if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) 350 if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
237 goto err; 351 goto err;
238 } 352 }
239 353
240 /* Lets do the pub key stuff :-) */ 354 /* Lets do the pub key stuff :-) */
241 max=0;
242 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 355 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
243 { 356 {
244 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 357 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
245 if (ri->cert == NULL) 358 if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
246 {
247 PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
248 goto err;
249 }
250 if ((pkey=X509_get_pubkey(ri->cert)) == NULL)
251 goto err;
252 jj=EVP_PKEY_size(pkey);
253 EVP_PKEY_free(pkey);
254 if (max < jj) max=jj;
255 }
256 if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
257 {
258 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
259 goto err;
260 }
261 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
262 {
263 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
264 if ((pkey=X509_get_pubkey(ri->cert)) == NULL)
265 goto err;
266 jj=EVP_PKEY_encrypt(tmp,key,keylen,pkey);
267 EVP_PKEY_free(pkey);
268 if (jj <= 0)
269 {
270 PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
271 OPENSSL_free(tmp);
272 goto err; 359 goto err;
273 }
274 if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj))
275 {
276 PKCS7err(PKCS7_F_PKCS7_DATAINIT,
277 ERR_R_MALLOC_FAILURE);
278 OPENSSL_free(tmp);
279 goto err;
280 }
281 } 360 }
282 OPENSSL_free(tmp);
283 OPENSSL_cleanse(key, keylen); 361 OPENSSL_cleanse(key, keylen);
284 362
285 if (out == NULL) 363 if (out == NULL)
@@ -303,7 +381,10 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
303 BIO_set_mem_eof_return(bio,0); 381 BIO_set_mem_eof_return(bio,0);
304 } 382 }
305 } 383 }
306 BIO_push(out,bio); 384 if (out)
385 BIO_push(out,bio);
386 else
387 out = bio;
307 bio=NULL; 388 bio=NULL;
308 if (0) 389 if (0)
309 { 390 {
@@ -333,7 +414,6 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
333 { 414 {
334 int i,j; 415 int i,j;
335 BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL; 416 BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
336 unsigned char *tmp=NULL;
337 X509_ALGOR *xa; 417 X509_ALGOR *xa;
338 ASN1_OCTET_STRING *data_body=NULL; 418 ASN1_OCTET_STRING *data_body=NULL;
339 const EVP_MD *evp_md; 419 const EVP_MD *evp_md;
@@ -423,7 +503,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
423 int max; 503 int max;
424 X509_OBJECT ret; 504 X509_OBJECT ret;
425#endif 505#endif
426 int jj; 506 unsigned char *ek = NULL;
507 int eklen;
427 508
428 if ((etmp=BIO_new(BIO_f_cipher())) == NULL) 509 if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
429 { 510 {
@@ -438,26 +519,21 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
438 * (if any) 519 * (if any)
439 */ 520 */
440 521
441 if (pcert) { 522 if (pcert)
442 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) { 523 {
524 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
525 {
443 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 526 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
444 if (!pkcs7_cmp_ri(ri, pcert)) 527 if (!pkcs7_cmp_ri(ri, pcert))
445 break; 528 break;
446 ri=NULL; 529 ri=NULL;
447 } 530 }
448 if (ri == NULL) { 531 if (ri == NULL)
532 {
449 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 533 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
450 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); 534 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
451 goto err; 535 goto err;
452 } 536 }
453 }
454
455 jj=EVP_PKEY_size(pkey);
456 tmp=(unsigned char *)OPENSSL_malloc(jj+10);
457 if (tmp == NULL)
458 {
459 PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
460 goto err;
461 } 537 }
462 538
463 /* If we haven't got a certificate try each ri in turn */ 539 /* If we haven't got a certificate try each ri in turn */
@@ -467,11 +543,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
467 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) 543 for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
468 { 544 {
469 ri=sk_PKCS7_RECIP_INFO_value(rsk,i); 545 ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
470 jj=EVP_PKEY_decrypt(tmp, 546 if (pkcs7_decrypt_rinfo(&ek, &eklen,
471 M_ASN1_STRING_data(ri->enc_key), 547 ri, pkey) > 0)
472 M_ASN1_STRING_length(ri->enc_key),
473 pkey);
474 if (jj > 0)
475 break; 548 break;
476 ERR_clear_error(); 549 ERR_clear_error();
477 ri = NULL; 550 ri = NULL;
@@ -485,15 +558,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
485 } 558 }
486 else 559 else
487 { 560 {
488 jj=EVP_PKEY_decrypt(tmp, 561 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) <= 0)
489 M_ASN1_STRING_data(ri->enc_key),
490 M_ASN1_STRING_length(ri->enc_key), pkey);
491 if (jj <= 0)
492 {
493 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
494 ERR_R_EVP_LIB);
495 goto err; 562 goto err;
496 }
497 } 563 }
498 564
499 evp_ctx=NULL; 565 evp_ctx=NULL;
@@ -503,22 +569,26 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
503 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0) 569 if (EVP_CIPHER_asn1_to_param(evp_ctx,enc_alg->parameter) < 0)
504 goto err; 570 goto err;
505 571
506 if (jj != EVP_CIPHER_CTX_key_length(evp_ctx)) { 572 if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
507 /* Some S/MIME clients don't use the same key 573 /* Some S/MIME clients don't use the same key
508 * and effective key length. The key length is 574 * and effective key length. The key length is
509 * determined by the size of the decrypted RSA key. 575 * determined by the size of the decrypted RSA key.
510 */ 576 */
511 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, jj)) 577 if(!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen))
512 { 578 {
513 PKCS7err(PKCS7_F_PKCS7_DATADECODE, 579 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
514 PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH); 580 PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
515 goto err; 581 goto err;
516 } 582 }
517 } 583 }
518 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,tmp,NULL,0) <= 0) 584 if (EVP_CipherInit_ex(evp_ctx,NULL,NULL,ek,NULL,0) <= 0)
519 goto err; 585 goto err;
520 586
521 OPENSSL_cleanse(tmp,jj); 587 if (ek)
588 {
589 OPENSSL_cleanse(ek,eklen);
590 OPENSSL_free(ek);
591 }
522 592
523 if (out == NULL) 593 if (out == NULL)
524 out=etmp; 594 out=etmp;
@@ -566,8 +636,6 @@ err:
566 if (bio != NULL) BIO_free_all(bio); 636 if (bio != NULL) BIO_free_all(bio);
567 out=NULL; 637 out=NULL;
568 } 638 }
569 if (tmp != NULL)
570 OPENSSL_free(tmp);
571 return(out); 639 return(out);
572 } 640 }
573 641
@@ -594,13 +662,43 @@ static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
594 return NULL; 662 return NULL;
595 } 663 }
596 664
665static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
666 {
667 unsigned char md_data[EVP_MAX_MD_SIZE];
668 unsigned int md_len;
669
670 /* Add signing time if not already present */
671 if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime))
672 {
673 if (!PKCS7_add0_attrib_signing_time(si, NULL))
674 {
675 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB,
676 ERR_R_MALLOC_FAILURE);
677 return 0;
678 }
679 }
680
681 /* Add digest */
682 EVP_DigestFinal_ex(mctx, md_data,&md_len);
683 if (!PKCS7_add1_attrib_digest(si, md_data, md_len))
684 {
685 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
686 return 0;
687 }
688
689 /* Now sign the attributes */
690 if (!PKCS7_SIGNER_INFO_sign(si))
691 return 0;
692
693 return 1;
694 }
695
696
597int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) 697int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
598 { 698 {
599 int ret=0; 699 int ret=0;
600 int i,j; 700 int i,j;
601 BIO *btmp; 701 BIO *btmp;
602 BUF_MEM *buf_mem=NULL;
603 BUF_MEM *buf=NULL;
604 PKCS7_SIGNER_INFO *si; 702 PKCS7_SIGNER_INFO *si;
605 EVP_MD_CTX *mdc,ctx_tmp; 703 EVP_MD_CTX *mdc,ctx_tmp;
606 STACK_OF(X509_ATTRIBUTE) *sk; 704 STACK_OF(X509_ATTRIBUTE) *sk;
@@ -613,24 +711,37 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
613 711
614 switch (i) 712 switch (i)
615 { 713 {
714 case NID_pkcs7_data:
715 os = p7->d.data;
716 break;
616 case NID_pkcs7_signedAndEnveloped: 717 case NID_pkcs7_signedAndEnveloped:
617 /* XXXXXXXXXXXXXXXX */ 718 /* XXXXXXXXXXXXXXXX */
618 si_sk=p7->d.signed_and_enveloped->signer_info; 719 si_sk=p7->d.signed_and_enveloped->signer_info;
619 if (!(os=M_ASN1_OCTET_STRING_new())) 720 os = p7->d.signed_and_enveloped->enc_data->enc_data;
721 if (!os)
620 { 722 {
621 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 723 os=M_ASN1_OCTET_STRING_new();
622 goto err; 724 if (!os)
725 {
726 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
727 goto err;
728 }
729 p7->d.signed_and_enveloped->enc_data->enc_data=os;
623 } 730 }
624 p7->d.signed_and_enveloped->enc_data->enc_data=os;
625 break; 731 break;
626 case NID_pkcs7_enveloped: 732 case NID_pkcs7_enveloped:
627 /* XXXXXXXXXXXXXXXX */ 733 /* XXXXXXXXXXXXXXXX */
628 if (!(os=M_ASN1_OCTET_STRING_new())) 734 os = p7->d.enveloped->enc_data->enc_data;
735 if (!os)
629 { 736 {
630 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE); 737 os=M_ASN1_OCTET_STRING_new();
631 goto err; 738 if (!os)
739 {
740 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
741 goto err;
742 }
743 p7->d.enveloped->enc_data->enc_data=os;
632 } 744 }
633 p7->d.enveloped->enc_data->enc_data=os;
634 break; 745 break;
635 case NID_pkcs7_signed: 746 case NID_pkcs7_signed:
636 si_sk=p7->d.sign->signer_info; 747 si_sk=p7->d.sign->signer_info;
@@ -652,21 +763,20 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
652 } 763 }
653 break; 764 break;
654 765
766 default:
767 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
768 goto err;
655 } 769 }
656 770
657 if (si_sk != NULL) 771 if (si_sk != NULL)
658 { 772 {
659 if ((buf=BUF_MEM_new()) == NULL)
660 {
661 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
662 goto err;
663 }
664 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++) 773 for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
665 { 774 {
666 si=sk_PKCS7_SIGNER_INFO_value(si_sk,i); 775 si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
667 if (si->pkey == NULL) continue; 776 if (si->pkey == NULL)
777 continue;
668 778
669 j=OBJ_obj2nid(si->digest_alg->algorithm); 779 j = OBJ_obj2nid(si->digest_alg->algorithm);
670 780
671 btmp=bio; 781 btmp=bio;
672 782
@@ -678,97 +788,33 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
678 /* We now have the EVP_MD_CTX, lets do the 788 /* We now have the EVP_MD_CTX, lets do the
679 * signing. */ 789 * signing. */
680 EVP_MD_CTX_copy_ex(&ctx_tmp,mdc); 790 EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
681 if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
682 {
683 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
684 goto err;
685 }
686 791
687 sk=si->auth_attr; 792 sk=si->auth_attr;
688 793
689 /* If there are attributes, we add the digest 794 /* If there are attributes, we add the digest
690 * attribute and only sign the attributes */ 795 * attribute and only sign the attributes */
691 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 796 if (sk_X509_ATTRIBUTE_num(sk) > 0)
692 { 797 {
693 unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL; 798 if (!do_pkcs7_signed_attrib(si, &ctx_tmp))
694 unsigned int md_len, alen;
695 ASN1_OCTET_STRING *digest;
696 ASN1_UTCTIME *sign_time;
697 const EVP_MD *md_tmp;
698
699 /* Add signing time if not already present */
700 if (!PKCS7_get_signed_attribute(si,
701 NID_pkcs9_signingTime))
702 {
703 if (!(sign_time=X509_gmtime_adj(NULL,0)))
704 {
705 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
706 ERR_R_MALLOC_FAILURE);
707 goto err;
708 }
709 if (!PKCS7_add_signed_attribute(si,
710 NID_pkcs9_signingTime,
711 V_ASN1_UTCTIME,sign_time))
712 {
713 M_ASN1_UTCTIME_free(sign_time);
714 goto err;
715 }
716 }
717
718 /* Add digest */
719 md_tmp=EVP_MD_CTX_md(&ctx_tmp);
720 EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
721 if (!(digest=M_ASN1_OCTET_STRING_new()))
722 {
723 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
724 ERR_R_MALLOC_FAILURE);
725 goto err; 799 goto err;
726 } 800 }
727 if (!M_ASN1_OCTET_STRING_set(digest,md_data, 801 else
728 md_len)) 802 {
729 { 803 unsigned char *abuf = NULL;
730 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, 804 unsigned int abuflen;
731 ERR_R_MALLOC_FAILURE); 805 abuflen = EVP_PKEY_size(si->pkey);
732 M_ASN1_OCTET_STRING_free(digest); 806 abuf = OPENSSL_malloc(abuflen);
807 if (!abuf)
733 goto err; 808 goto err;
734 } 809
735 if (!PKCS7_add_signed_attribute(si, 810 if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen,
736 NID_pkcs9_messageDigest, 811 si->pkey))
737 V_ASN1_OCTET_STRING,digest))
738 { 812 {
739 M_ASN1_OCTET_STRING_free(digest); 813 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
814 ERR_R_EVP_LIB);
740 goto err; 815 goto err;
741 } 816 }
742 817 ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
743 /* Now sign the attributes */
744 EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
745 alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
746 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
747 if(!abuf) goto err;
748 EVP_SignUpdate(&ctx_tmp,abuf,alen);
749 OPENSSL_free(abuf);
750 }
751
752#ifndef OPENSSL_NO_DSA
753 if (si->pkey->type == EVP_PKEY_DSA)
754 ctx_tmp.digest=EVP_dss1();
755#endif
756#ifndef OPENSSL_NO_ECDSA
757 if (si->pkey->type == EVP_PKEY_EC)
758 ctx_tmp.digest=EVP_ecdsa();
759#endif
760
761 if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
762 (unsigned int *)&buf->length,si->pkey))
763 {
764 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB);
765 goto err;
766 }
767 if (!ASN1_STRING_set(si->enc_digest,
768 (unsigned char *)buf->data,buf->length))
769 {
770 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB);
771 goto err;
772 } 818 }
773 } 819 }
774 } 820 }
@@ -783,34 +829,90 @@ int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
783 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); 829 M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
784 } 830 }
785 831
786 if (!PKCS7_is_detached(p7)) 832 if (!PKCS7_is_detached(p7) && !(os->flags & ASN1_STRING_FLAG_NDEF))
787 { 833 {
834 char *cont;
835 long contlen;
788 btmp=BIO_find_type(bio,BIO_TYPE_MEM); 836 btmp=BIO_find_type(bio,BIO_TYPE_MEM);
789 if (btmp == NULL) 837 if (btmp == NULL)
790 { 838 {
791 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO); 839 PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
792 goto err; 840 goto err;
793 } 841 }
794 BIO_get_mem_ptr(btmp,&buf_mem); 842 contlen = BIO_get_mem_data(btmp, &cont);
795 /* Mark the BIO read only then we can use its copy of the data 843 /* Mark the BIO read only then we can use its copy of the data
796 * instead of making an extra copy. 844 * instead of making an extra copy.
797 */ 845 */
798 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); 846 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
799 BIO_set_mem_eof_return(btmp, 0); 847 BIO_set_mem_eof_return(btmp, 0);
800 os->data = (unsigned char *)buf_mem->data; 848 ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
801 os->length = buf_mem->length;
802#if 0
803 M_ASN1_OCTET_STRING_set(os,
804 (unsigned char *)buf_mem->data,buf_mem->length);
805#endif
806 } 849 }
807 ret=1; 850 ret=1;
808err: 851err:
809 EVP_MD_CTX_cleanup(&ctx_tmp); 852 EVP_MD_CTX_cleanup(&ctx_tmp);
810 if (buf != NULL) BUF_MEM_free(buf);
811 return(ret); 853 return(ret);
812 } 854 }
813 855
856int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
857 {
858 EVP_MD_CTX mctx;
859 EVP_PKEY_CTX *pctx;
860 unsigned char *abuf = NULL;
861 int alen;
862 size_t siglen;
863 const EVP_MD *md = NULL;
864
865 md = EVP_get_digestbyobj(si->digest_alg->algorithm);
866 if (md == NULL)
867 return 0;
868
869 EVP_MD_CTX_init(&mctx);
870 if (EVP_DigestSignInit(&mctx, &pctx, md,NULL, si->pkey) <= 0)
871 goto err;
872
873 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
874 EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0)
875 {
876 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
877 goto err;
878 }
879
880 alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr,&abuf,
881 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
882 if(!abuf)
883 goto err;
884 if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0)
885 goto err;
886 OPENSSL_free(abuf);
887 if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
888 goto err;
889 abuf = OPENSSL_malloc(siglen);
890 if(!abuf)
891 goto err;
892 if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
893 goto err;
894
895 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
896 EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0)
897 {
898 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
899 goto err;
900 }
901
902 EVP_MD_CTX_cleanup(&mctx);
903
904 ASN1_STRING_set0(si->enc_digest, abuf, siglen);
905
906 return 1;
907
908 err:
909 if (abuf)
910 OPENSSL_free(abuf);
911 EVP_MD_CTX_cleanup(&mctx);
912 return 0;
913
914 }
915
814int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, 916int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
815 PKCS7 *p7, PKCS7_SIGNER_INFO *si) 917 PKCS7 *p7, PKCS7_SIGNER_INFO *si)
816 { 918 {
@@ -922,7 +1024,8 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
922 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) 1024 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
923 { 1025 {
924 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; 1026 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
925 unsigned int md_len, alen; 1027 unsigned int md_len;
1028 int alen;
926 ASN1_OCTET_STRING *message_digest; 1029 ASN1_OCTET_STRING *message_digest;
927 1030
928 EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len); 1031 EVP_DigestFinal_ex(&mdc_tmp,md_dat,&md_len);
@@ -954,6 +1057,12 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
954 1057
955 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, 1058 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
956 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); 1059 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
1060 if (alen <= 0)
1061 {
1062 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,ERR_R_ASN1_LIB);
1063 ret = -1;
1064 goto err;
1065 }
957 EVP_VerifyUpdate(&mdc_tmp, abuf, alen); 1066 EVP_VerifyUpdate(&mdc_tmp, abuf, alen);
958 1067
959 OPENSSL_free(abuf); 1068 OPENSSL_free(abuf);
@@ -966,12 +1075,6 @@ for (ii=0; ii<md_len; ii++) printf("%02X",md_dat[ii]); printf(" calc\n");
966 ret = -1; 1075 ret = -1;
967 goto err; 1076 goto err;
968 } 1077 }
969#ifndef OPENSSL_NO_DSA
970 if(pkey->type == EVP_PKEY_DSA) mdc_tmp.digest=EVP_dss1();
971#endif
972#ifndef OPENSSL_NO_ECDSA
973 if (pkey->type == EVP_PKEY_EC) mdc_tmp.digest=EVP_ecdsa();
974#endif
975 1078
976 i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey); 1079 i=EVP_VerifyFinal(&mdc_tmp,os->data,os->length, pkey);
977 EVP_PKEY_free(pkey); 1080 EVP_PKEY_free(pkey);
@@ -1107,8 +1210,9 @@ static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
1107 1210
1108 if (*sk == NULL) 1211 if (*sk == NULL)
1109 { 1212 {
1110 if (!(*sk = sk_X509_ATTRIBUTE_new_null())) 1213 *sk = sk_X509_ATTRIBUTE_new_null();
1111 return 0; 1214 if (*sk == NULL)
1215 return 0;
1112new_attrib: 1216new_attrib:
1113 if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value))) 1217 if (!(attr=X509_ATTRIBUTE_create(nid,atrtype,value)))
1114 return 0; 1218 return 0;
diff --git a/src/lib/libcrypto/pkcs7/pk7_lib.c b/src/lib/libcrypto/pkcs7/pk7_lib.c
index f2490941a3..3ca0952792 100644
--- a/src/lib/libcrypto/pkcs7/pk7_lib.c
+++ b/src/lib/libcrypto/pkcs7/pk7_lib.c
@@ -60,6 +60,7 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/objects.h> 61#include <openssl/objects.h>
62#include <openssl/x509.h> 62#include <openssl/x509.h>
63#include "asn1_locl.h"
63 64
64long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) 65long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
65 { 66 {
@@ -314,7 +315,7 @@ int PKCS7_add_certificate(PKCS7 *p7, X509 *x509)
314 *sk=sk_X509_new_null(); 315 *sk=sk_X509_new_null();
315 if (*sk == NULL) 316 if (*sk == NULL)
316 { 317 {
317 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE,ERR_R_MALLOC_FAILURE); 318 PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE);
318 return 0; 319 return 0;
319 } 320 }
320 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); 321 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
@@ -365,13 +366,8 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
365int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, 366int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
366 const EVP_MD *dgst) 367 const EVP_MD *dgst)
367 { 368 {
368 int nid; 369 int ret;
369 char is_dsa;
370 370
371 if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
372 is_dsa = 1;
373 else
374 is_dsa = 0;
375 /* We now need to add another PKCS7_SIGNER_INFO entry */ 371 /* We now need to add another PKCS7_SIGNER_INFO entry */
376 if (!ASN1_INTEGER_set(p7i->version,1)) 372 if (!ASN1_INTEGER_set(p7i->version,1))
377 goto err; 373 goto err;
@@ -391,65 +387,55 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
391 p7i->pkey=pkey; 387 p7i->pkey=pkey;
392 388
393 /* Set the algorithms */ 389 /* Set the algorithms */
394 if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
395 else
396 p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
397 390
398 if (p7i->digest_alg->parameter != NULL) 391 X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
399 ASN1_TYPE_free(p7i->digest_alg->parameter); 392 V_ASN1_NULL, NULL);
400 if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
401 goto err;
402 p7i->digest_alg->parameter->type=V_ASN1_NULL;
403 393
404 if (p7i->digest_enc_alg->parameter != NULL) 394 if (pkey->ameth && pkey->ameth->pkey_ctrl)
405 ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
406 nid = EVP_PKEY_type(pkey->type);
407 if (nid == EVP_PKEY_RSA)
408 { 395 {
409 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption); 396 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
410 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new())) 397 0, p7i);
411 goto err; 398 if (ret > 0)
412 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL; 399 return 1;
413 } 400 if (ret != -2)
414 else if (nid == EVP_PKEY_DSA) 401 {
415 { 402 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
416#if 1 403 PKCS7_R_SIGNING_CTRL_FAILURE);
417 /* use 'dsaEncryption' OID for compatibility with other software 404 return 0;
418 * (PKCS #7 v1.5 does specify how to handle DSA) ... */ 405 }
419 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa);
420#else
421 /* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS)
422 * would make more sense. */
423 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1);
424#endif
425 p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */
426 }
427 else if (nid == EVP_PKEY_EC)
428 {
429 p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1);
430 if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
431 goto err;
432 p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
433 } 406 }
434 else 407 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
435 return(0); 408 PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
436
437 return(1);
438err: 409err:
439 return(0); 410 return 0;
440 } 411 }
441 412
442PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, 413PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
443 const EVP_MD *dgst) 414 const EVP_MD *dgst)
444 { 415 {
445 PKCS7_SIGNER_INFO *si; 416 PKCS7_SIGNER_INFO *si = NULL;
417
418 if (dgst == NULL)
419 {
420 int def_nid;
421 if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0)
422 goto err;
423 dgst = EVP_get_digestbynid(def_nid);
424 if (dgst == NULL)
425 {
426 PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE,
427 PKCS7_R_NO_DEFAULT_DIGEST);
428 goto err;
429 }
430 }
446 431
447 if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err; 432 if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err;
448 if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err; 433 if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err;
449 if (!PKCS7_add_signer(p7,si)) goto err; 434 if (!PKCS7_add_signer(p7,si)) goto err;
450 return(si); 435 return(si);
451err: 436err:
452 PKCS7_SIGNER_INFO_free(si); 437 if (si)
438 PKCS7_SIGNER_INFO_free(si);
453 return(NULL); 439 return(NULL);
454 } 440 }
455 441
@@ -485,6 +471,23 @@ STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
485 return(NULL); 471 return(NULL);
486 } 472 }
487 473
474void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
475 X509_ALGOR **pdig, X509_ALGOR **psig)
476 {
477 if (pk)
478 *pk = si->pkey;
479 if (pdig)
480 *pdig = si->digest_alg;
481 if (psig)
482 *psig = si->digest_enc_alg;
483 }
484
485void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc)
486 {
487 if (penc)
488 *penc = ri->key_enc_algor;
489 }
490
488PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) 491PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
489 { 492 {
490 PKCS7_RECIP_INFO *ri; 493 PKCS7_RECIP_INFO *ri;
@@ -492,10 +495,11 @@ PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
492 if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err; 495 if ((ri=PKCS7_RECIP_INFO_new()) == NULL) goto err;
493 if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err; 496 if (!PKCS7_RECIP_INFO_set(ri,x509)) goto err;
494 if (!PKCS7_add_recipient_info(p7,ri)) goto err; 497 if (!PKCS7_add_recipient_info(p7,ri)) goto err;
495 return(ri); 498 return ri;
496err: 499err:
497 PKCS7_RECIP_INFO_free(ri); 500 if (ri)
498 return(NULL); 501 PKCS7_RECIP_INFO_free(ri);
502 return NULL;
499 } 503 }
500 504
501int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) 505int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
@@ -524,6 +528,8 @@ int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri)
524 528
525int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) 529int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
526 { 530 {
531 int ret;
532 EVP_PKEY *pkey = NULL;
527 if (!ASN1_INTEGER_set(p7i->version,0)) 533 if (!ASN1_INTEGER_set(p7i->version,0))
528 return 0; 534 return 0;
529 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, 535 if (!X509_NAME_set(&p7i->issuer_and_serial->issuer,
@@ -535,14 +541,41 @@ int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
535 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) 541 M_ASN1_INTEGER_dup(X509_get_serialNumber(x509))))
536 return 0; 542 return 0;
537 543
538 X509_ALGOR_free(p7i->key_enc_algor); 544 pkey = X509_get_pubkey(x509);
539 if (!(p7i->key_enc_algor= X509_ALGOR_dup(x509->cert_info->key->algor))) 545
540 return 0; 546 if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl)
547 {
548 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
549 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
550 goto err;
551 }
552
553 ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT,
554 0, p7i);
555 if (ret == -2)
556 {
557 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
558 PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
559 goto err;
560 }
561 if (ret <= 0)
562 {
563 PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET,
564 PKCS7_R_ENCRYPTION_CTRL_FAILURE);
565 goto err;
566 }
567
568 EVP_PKEY_free(pkey);
541 569
542 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509); 570 CRYPTO_add(&x509->references,1,CRYPTO_LOCK_X509);
543 p7i->cert=x509; 571 p7i->cert=x509;
544 572
545 return(1); 573 return 1;
574
575 err:
576 if (pkey)
577 EVP_PKEY_free(pkey);
578 return 0;
546 } 579 }
547 580
548X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) 581X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
@@ -587,3 +620,48 @@ int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
587 return 1; 620 return 1;
588 } 621 }
589 622
623int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7)
624 {
625 ASN1_OCTET_STRING *os = NULL;
626
627 switch (OBJ_obj2nid(p7->type))
628 {
629 case NID_pkcs7_data:
630 os = p7->d.data;
631 break;
632
633 case NID_pkcs7_signedAndEnveloped:
634 os = p7->d.signed_and_enveloped->enc_data->enc_data;
635 if (os == NULL)
636 {
637 os=M_ASN1_OCTET_STRING_new();
638 p7->d.signed_and_enveloped->enc_data->enc_data=os;
639 }
640 break;
641
642 case NID_pkcs7_enveloped:
643 os = p7->d.enveloped->enc_data->enc_data;
644 if (os == NULL)
645 {
646 os=M_ASN1_OCTET_STRING_new();
647 p7->d.enveloped->enc_data->enc_data=os;
648 }
649 break;
650
651 case NID_pkcs7_signed:
652 os=p7->d.sign->contents->d.data;
653 break;
654
655 default:
656 os = NULL;
657 break;
658 }
659
660 if (os == NULL)
661 return 0;
662
663 os->flags |= ASN1_STRING_FLAG_NDEF;
664 *boundary = &os->data;
665
666 return 1;
667 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_mime.c b/src/lib/libcrypto/pkcs7/pk7_mime.c
index bf190360d7..938f79a646 100644
--- a/src/lib/libcrypto/pkcs7/pk7_mime.c
+++ b/src/lib/libcrypto/pkcs7/pk7_mime.c
@@ -50,10 +50,6 @@
50 * OF THE POSSIBILITY OF SUCH DAMAGE. 50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ==================================================================== 51 * ====================================================================
52 * 52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */ 53 */
58 54
59#include <stdio.h> 55#include <stdio.h>
@@ -61,662 +57,41 @@
61#include "cryptlib.h" 57#include "cryptlib.h"
62#include <openssl/rand.h> 58#include <openssl/rand.h>
63#include <openssl/x509.h> 59#include <openssl/x509.h>
60#include <openssl/asn1.h>
64 61
65/* MIME and related routines */ 62/* PKCS#7 wrappers round generalised stream and MIME routines */
66
67/* MIME format structures
68 * Note that all are translated to lower case apart from
69 * parameter values. Quotes are stripped off
70 */
71
72typedef struct {
73char *param_name; /* Param name e.g. "micalg" */
74char *param_value; /* Param value e.g. "sha1" */
75} MIME_PARAM;
76
77DECLARE_STACK_OF(MIME_PARAM)
78IMPLEMENT_STACK_OF(MIME_PARAM)
79
80typedef struct {
81char *name; /* Name of line e.g. "content-type" */
82char *value; /* Value of line e.g. "text/plain" */
83STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */
84} MIME_HEADER;
85 63
86DECLARE_STACK_OF(MIME_HEADER) 64int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
87IMPLEMENT_STACK_OF(MIME_HEADER) 65 {
88 66 return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags,
89static int pkcs7_output_data(BIO *bio, BIO *data, PKCS7 *p7, int flags); 67 ASN1_ITEM_rptr(PKCS7));
90static int B64_write_PKCS7(BIO *bio, PKCS7 *p7);
91static PKCS7 *B64_read_PKCS7(BIO *bio);
92static char * strip_ends(char *name);
93static char * strip_start(char *name);
94static char * strip_end(char *name);
95static MIME_HEADER *mime_hdr_new(char *name, char *value);
96static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value);
97static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio);
98static int mime_hdr_cmp(const MIME_HEADER * const *a,
99 const MIME_HEADER * const *b);
100static int mime_param_cmp(const MIME_PARAM * const *a,
101 const MIME_PARAM * const *b);
102static void mime_param_free(MIME_PARAM *param);
103static int mime_bound_check(char *line, int linelen, char *bound, int blen);
104static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret);
105static int strip_eol(char *linebuf, int *plen);
106static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name);
107static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name);
108static void mime_hdr_free(MIME_HEADER *hdr);
109
110#define MAX_SMLEN 1024
111#define mime_debug(x) /* x */
112
113/* Base 64 read and write of PKCS#7 structure */
114
115static int B64_write_PKCS7(BIO *bio, PKCS7 *p7)
116{
117 BIO *b64;
118 if(!(b64 = BIO_new(BIO_f_base64()))) {
119 PKCS7err(PKCS7_F_B64_WRITE_PKCS7,ERR_R_MALLOC_FAILURE);
120 return 0;
121 } 68 }
122 bio = BIO_push(b64, bio);
123 i2d_PKCS7_bio(bio, p7);
124 (void)BIO_flush(bio);
125 bio = BIO_pop(bio);
126 BIO_free(b64);
127 return 1;
128}
129 69
130static PKCS7 *B64_read_PKCS7(BIO *bio) 70int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags)
131{ 71 {
132 BIO *b64; 72 return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *) p7, in, flags,
133 PKCS7 *p7; 73 "PKCS7",
134 if(!(b64 = BIO_new(BIO_f_base64()))) { 74 ASN1_ITEM_rptr(PKCS7));
135 PKCS7err(PKCS7_F_B64_READ_PKCS7,ERR_R_MALLOC_FAILURE);
136 return 0;
137 } 75 }
138 bio = BIO_push(b64, bio);
139 if(!(p7 = d2i_PKCS7_bio(bio, NULL)))
140 PKCS7err(PKCS7_F_B64_READ_PKCS7,PKCS7_R_DECODE_ERROR);
141 (void)BIO_flush(bio);
142 bio = BIO_pop(bio);
143 BIO_free(b64);
144 return p7;
145}
146
147/* SMIME sender */
148 76
149int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) 77int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
150{
151 char bound[33], c;
152 int i;
153 char *mime_prefix, *mime_eol, *msg_type=NULL;
154 if (flags & PKCS7_NOOLDMIMETYPE)
155 mime_prefix = "application/pkcs7-";
156 else
157 mime_prefix = "application/x-pkcs7-";
158
159 if (flags & PKCS7_CRLFEOL)
160 mime_eol = "\r\n";
161 else
162 mime_eol = "\n";
163 if((flags & PKCS7_DETACHED) && data) {
164 /* We want multipart/signed */
165 /* Generate a random boundary */
166 RAND_pseudo_bytes((unsigned char *)bound, 32);
167 for(i = 0; i < 32; i++) {
168 c = bound[i] & 0xf;
169 if(c < 10) c += '0';
170 else c += 'A' - 10;
171 bound[i] = c;
172 }
173 bound[32] = 0;
174 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
175 BIO_printf(bio, "Content-Type: multipart/signed;");
176 BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix);
177 BIO_printf(bio, " micalg=sha1; boundary=\"----%s\"%s%s",
178 bound, mime_eol, mime_eol);
179 BIO_printf(bio, "This is an S/MIME signed message%s%s",
180 mime_eol, mime_eol);
181 /* Now write out the first part */
182 BIO_printf(bio, "------%s%s", bound, mime_eol);
183 pkcs7_output_data(bio, data, p7, flags);
184 BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol);
185
186 /* Headers for signature */
187
188 BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix);
189 BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol);
190 BIO_printf(bio, "Content-Transfer-Encoding: base64%s",
191 mime_eol);
192 BIO_printf(bio, "Content-Disposition: attachment;");
193 BIO_printf(bio, " filename=\"smime.p7s\"%s%s",
194 mime_eol, mime_eol);
195 B64_write_PKCS7(bio, p7);
196 BIO_printf(bio,"%s------%s--%s%s", mime_eol, bound,
197 mime_eol, mime_eol);
198 return 1;
199 }
200
201 /* Determine smime-type header */
202
203 if (PKCS7_type_is_enveloped(p7))
204 msg_type = "enveloped-data";
205 else if (PKCS7_type_is_signed(p7))
206 {
207 /* If we have any signers it is signed-data othewise
208 * certs-only.
209 */
210 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
211 sinfos = PKCS7_get_signer_info(p7);
212 if (sk_PKCS7_SIGNER_INFO_num(sinfos) > 0)
213 msg_type = "signed-data";
214 else
215 msg_type = "certs-only";
216 }
217 /* MIME headers */
218 BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol);
219 BIO_printf(bio, "Content-Disposition: attachment;");
220 BIO_printf(bio, " filename=\"smime.p7m\"%s", mime_eol);
221 BIO_printf(bio, "Content-Type: %smime;", mime_prefix);
222 if (msg_type)
223 BIO_printf(bio, " smime-type=%s;", msg_type);
224 BIO_printf(bio, " name=\"smime.p7m\"%s", mime_eol);
225 BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s",
226 mime_eol, mime_eol);
227 B64_write_PKCS7(bio, p7);
228 BIO_printf(bio, "%s", mime_eol);
229 return 1;
230}
231
232/* Handle output of PKCS#7 data */
233
234
235static int pkcs7_output_data(BIO *out, BIO *data, PKCS7 *p7, int flags)
236 { 78 {
237 BIO *tmpbio, *p7bio; 79 STACK_OF(X509_ALGOR) *mdalgs;
238 80 int ctype_nid = OBJ_obj2nid(p7->type);
239 if (!(flags & PKCS7_STREAM)) 81 if (ctype_nid == NID_pkcs7_signed)
240 { 82 mdalgs = p7->d.sign->md_algs;
241 SMIME_crlf_copy(data, out, flags); 83 else
242 return 1; 84 mdalgs = NULL;
243 }
244
245 /* Partial sign operation */
246
247 /* Initialize sign operation */
248 p7bio = PKCS7_dataInit(p7, out);
249
250 /* Copy data across, computing digests etc */
251 SMIME_crlf_copy(data, p7bio, flags);
252
253 /* Must be detached */
254 PKCS7_set_detached(p7, 1);
255
256 /* Finalize signatures */
257 PKCS7_dataFinal(p7, p7bio);
258
259 /* Now remove any digests prepended to the BIO */
260 85
261 while (p7bio != out) 86 flags ^= SMIME_OLDMIME;
262 {
263 tmpbio = BIO_pop(p7bio);
264 BIO_free(p7bio);
265 p7bio = tmpbio;
266 }
267 87
268 return 1;
269 88
89 return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags,
90 ctype_nid, NID_undef, mdalgs,
91 ASN1_ITEM_rptr(PKCS7));
270 } 92 }
271 93
272/* SMIME reader: handle multipart/signed and opaque signing.
273 * in multipart case the content is placed in a memory BIO
274 * pointed to by "bcont". In opaque this is set to NULL
275 */
276
277PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) 94PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont)
278{
279 BIO *p7in;
280 STACK_OF(MIME_HEADER) *headers = NULL;
281 STACK_OF(BIO) *parts = NULL;
282 MIME_HEADER *hdr;
283 MIME_PARAM *prm;
284 PKCS7 *p7;
285 int ret;
286
287 if(bcont) *bcont = NULL;
288
289 if (!(headers = mime_parse_hdr(bio))) {
290 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_PARSE_ERROR);
291 return NULL;
292 }
293
294 if(!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) {
295 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
296 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_CONTENT_TYPE);
297 return NULL;
298 }
299
300 /* Handle multipart/signed */
301
302 if(!strcmp(hdr->value, "multipart/signed")) {
303 /* Split into two parts */
304 prm = mime_param_find(hdr, "boundary");
305 if(!prm || !prm->param_value) {
306 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
307 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BOUNDARY);
308 return NULL;
309 }
310 ret = multi_split(bio, prm->param_value, &parts);
311 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
312 if(!ret || (sk_BIO_num(parts) != 2) ) {
313 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_MULTIPART_BODY_FAILURE);
314 sk_BIO_pop_free(parts, BIO_vfree);
315 return NULL;
316 }
317
318 /* Parse the signature piece */
319 p7in = sk_BIO_value(parts, 1);
320
321 if (!(headers = mime_parse_hdr(p7in))) {
322 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_MIME_SIG_PARSE_ERROR);
323 sk_BIO_pop_free(parts, BIO_vfree);
324 return NULL;
325 }
326
327 /* Get content type */
328
329 if(!(hdr = mime_hdr_find(headers, "content-type")) ||
330 !hdr->value) {
331 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
332 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_NO_SIG_CONTENT_TYPE);
333 return NULL;
334 }
335
336 if(strcmp(hdr->value, "application/x-pkcs7-signature") &&
337 strcmp(hdr->value, "application/pkcs7-signature")) {
338 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
339 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_SIG_INVALID_MIME_TYPE);
340 ERR_add_error_data(2, "type: ", hdr->value);
341 sk_BIO_pop_free(parts, BIO_vfree);
342 return NULL;
343 }
344 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
345 /* Read in PKCS#7 */
346 if(!(p7 = B64_read_PKCS7(p7in))) {
347 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_PKCS7_SIG_PARSE_ERROR);
348 sk_BIO_pop_free(parts, BIO_vfree);
349 return NULL;
350 }
351
352 if(bcont) {
353 *bcont = sk_BIO_value(parts, 0);
354 BIO_free(p7in);
355 sk_BIO_free(parts);
356 } else sk_BIO_pop_free(parts, BIO_vfree);
357 return p7;
358 }
359
360 /* OK, if not multipart/signed try opaque signature */
361
362 if (strcmp (hdr->value, "application/x-pkcs7-mime") &&
363 strcmp (hdr->value, "application/pkcs7-mime")) {
364 PKCS7err(PKCS7_F_SMIME_READ_PKCS7,PKCS7_R_INVALID_MIME_TYPE);
365 ERR_add_error_data(2, "type: ", hdr->value);
366 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
367 return NULL;
368 }
369
370 sk_MIME_HEADER_pop_free(headers, mime_hdr_free);
371
372 if(!(p7 = B64_read_PKCS7(bio))) {
373 PKCS7err(PKCS7_F_SMIME_READ_PKCS7, PKCS7_R_PKCS7_PARSE_ERROR);
374 return NULL;
375 }
376 return p7;
377
378}
379
380/* Split a multipart/XXX message body into component parts: result is
381 * canonical parts in a STACK of bios
382 */
383
384static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
385{
386 char linebuf[MAX_SMLEN];
387 int len, blen;
388 int eol = 0, next_eol = 0;
389 BIO *bpart = NULL;
390 STACK_OF(BIO) *parts;
391 char state, part, first;
392
393 blen = strlen(bound);
394 part = 0;
395 state = 0;
396 first = 1;
397 parts = sk_BIO_new_null();
398 *ret = parts;
399 while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
400 state = mime_bound_check(linebuf, len, bound, blen);
401 if(state == 1) {
402 first = 1;
403 part++;
404 } else if(state == 2) {
405 sk_BIO_push(parts, bpart);
406 return 1;
407 } else if(part) {
408 /* Strip CR+LF from linebuf */
409 next_eol = strip_eol(linebuf, &len);
410 if(first) {
411 first = 0;
412 if(bpart) sk_BIO_push(parts, bpart);
413 bpart = BIO_new(BIO_s_mem());
414 BIO_set_mem_eof_return(bpart, 0);
415 } else if (eol)
416 BIO_write(bpart, "\r\n", 2);
417 eol = next_eol;
418 if (len)
419 BIO_write(bpart, linebuf, len);
420 }
421 }
422 return 0;
423}
424
425/* This is the big one: parse MIME header lines up to message body */
426
427#define MIME_INVALID 0
428#define MIME_START 1
429#define MIME_TYPE 2
430#define MIME_NAME 3
431#define MIME_VALUE 4
432#define MIME_QUOTE 5
433#define MIME_COMMENT 6
434
435
436static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio)
437{
438 char *p, *q, c;
439 char *ntmp;
440 char linebuf[MAX_SMLEN];
441 MIME_HEADER *mhdr = NULL;
442 STACK_OF(MIME_HEADER) *headers;
443 int len, state, save_state = 0;
444
445 headers = sk_MIME_HEADER_new(mime_hdr_cmp);
446 while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) {
447 /* If whitespace at line start then continuation line */
448 if(mhdr && isspace((unsigned char)linebuf[0])) state = MIME_NAME;
449 else state = MIME_START;
450 ntmp = NULL;
451 /* Go through all characters */
452 for(p = linebuf, q = linebuf; (c = *p) && (c!='\r') && (c!='\n'); p++) {
453
454 /* State machine to handle MIME headers
455 * if this looks horrible that's because it *is*
456 */
457
458 switch(state) {
459 case MIME_START:
460 if(c == ':') {
461 state = MIME_TYPE;
462 *p = 0;
463 ntmp = strip_ends(q);
464 q = p + 1;
465 }
466 break;
467
468 case MIME_TYPE:
469 if(c == ';') {
470 mime_debug("Found End Value\n");
471 *p = 0;
472 mhdr = mime_hdr_new(ntmp, strip_ends(q));
473 sk_MIME_HEADER_push(headers, mhdr);
474 ntmp = NULL;
475 q = p + 1;
476 state = MIME_NAME;
477 } else if(c == '(') {
478 save_state = state;
479 state = MIME_COMMENT;
480 }
481 break;
482
483 case MIME_COMMENT:
484 if(c == ')') {
485 state = save_state;
486 }
487 break;
488
489 case MIME_NAME:
490 if(c == '=') {
491 state = MIME_VALUE;
492 *p = 0;
493 ntmp = strip_ends(q);
494 q = p + 1;
495 }
496 break ;
497
498 case MIME_VALUE:
499 if(c == ';') {
500 state = MIME_NAME;
501 *p = 0;
502 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
503 ntmp = NULL;
504 q = p + 1;
505 } else if (c == '"') {
506 mime_debug("Found Quote\n");
507 state = MIME_QUOTE;
508 } else if(c == '(') {
509 save_state = state;
510 state = MIME_COMMENT;
511 }
512 break;
513
514 case MIME_QUOTE:
515 if(c == '"') {
516 mime_debug("Found Match Quote\n");
517 state = MIME_VALUE;
518 }
519 break;
520 }
521 }
522
523 if(state == MIME_TYPE) {
524 mhdr = mime_hdr_new(ntmp, strip_ends(q));
525 sk_MIME_HEADER_push(headers, mhdr);
526 } else if(state == MIME_VALUE)
527 mime_hdr_addparam(mhdr, ntmp, strip_ends(q));
528 if(p == linebuf) break; /* Blank line means end of headers */
529}
530
531return headers;
532
533}
534
535static char *strip_ends(char *name)
536{
537 return strip_end(strip_start(name));
538}
539
540/* Strip a parameter of whitespace from start of param */
541static char *strip_start(char *name)
542{
543 char *p, c;
544 /* Look for first non white space or quote */
545 for(p = name; (c = *p) ;p++) {
546 if(c == '"') {
547 /* Next char is start of string if non null */
548 if(p[1]) return p + 1;
549 /* Else null string */
550 return NULL;
551 }
552 if(!isspace((unsigned char)c)) return p;
553 }
554 return NULL;
555}
556
557/* As above but strip from end of string : maybe should handle brackets? */
558static char *strip_end(char *name)
559{
560 char *p, c;
561 if(!name) return NULL;
562 /* Look for first non white space or quote */
563 for(p = name + strlen(name) - 1; p >= name ;p--) {
564 c = *p;
565 if(c == '"') {
566 if(p - 1 == name) return NULL;
567 *p = 0;
568 return name;
569 }
570 if(isspace((unsigned char)c)) *p = 0;
571 else return name;
572 }
573 return NULL;
574}
575
576static MIME_HEADER *mime_hdr_new(char *name, char *value)
577{
578 MIME_HEADER *mhdr;
579 char *tmpname, *tmpval, *p;
580 int c;
581 if(name) {
582 if(!(tmpname = BUF_strdup(name))) return NULL;
583 for(p = tmpname ; *p; p++) {
584 c = *p;
585 if(isupper(c)) {
586 c = tolower(c);
587 *p = c;
588 }
589 }
590 } else tmpname = NULL;
591 if(value) {
592 if(!(tmpval = BUF_strdup(value))) return NULL;
593 for(p = tmpval ; *p; p++) {
594 c = *p;
595 if(isupper(c)) {
596 c = tolower(c);
597 *p = c;
598 }
599 }
600 } else tmpval = NULL;
601 mhdr = (MIME_HEADER *) OPENSSL_malloc(sizeof(MIME_HEADER));
602 if(!mhdr) return NULL;
603 mhdr->name = tmpname;
604 mhdr->value = tmpval;
605 if(!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) return NULL;
606 return mhdr;
607}
608
609static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value)
610{
611 char *tmpname, *tmpval, *p;
612 int c;
613 MIME_PARAM *mparam;
614 if(name) {
615 tmpname = BUF_strdup(name);
616 if(!tmpname) return 0;
617 for(p = tmpname ; *p; p++) {
618 c = *p;
619 if(isupper(c)) {
620 c = tolower(c);
621 *p = c;
622 }
623 }
624 } else tmpname = NULL;
625 if(value) {
626 tmpval = BUF_strdup(value);
627 if(!tmpval) return 0;
628 } else tmpval = NULL;
629 /* Parameter values are case sensitive so leave as is */
630 mparam = (MIME_PARAM *) OPENSSL_malloc(sizeof(MIME_PARAM));
631 if(!mparam) return 0;
632 mparam->param_name = tmpname;
633 mparam->param_value = tmpval;
634 sk_MIME_PARAM_push(mhdr->params, mparam);
635 return 1;
636}
637
638static int mime_hdr_cmp(const MIME_HEADER * const *a,
639 const MIME_HEADER * const *b)
640{
641 return(strcmp((*a)->name, (*b)->name));
642}
643
644static int mime_param_cmp(const MIME_PARAM * const *a,
645 const MIME_PARAM * const *b)
646{
647 return(strcmp((*a)->param_name, (*b)->param_name));
648}
649
650/* Find a header with a given name (if possible) */
651
652static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name)
653{
654 MIME_HEADER htmp;
655 int idx;
656 htmp.name = name;
657 idx = sk_MIME_HEADER_find(hdrs, &htmp);
658 if(idx < 0) return NULL;
659 return sk_MIME_HEADER_value(hdrs, idx);
660}
661
662static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name)
663{
664 MIME_PARAM param;
665 int idx;
666 param.param_name = name;
667 idx = sk_MIME_PARAM_find(hdr->params, &param);
668 if(idx < 0) return NULL;
669 return sk_MIME_PARAM_value(hdr->params, idx);
670}
671
672static void mime_hdr_free(MIME_HEADER *hdr)
673{
674 if(hdr->name) OPENSSL_free(hdr->name);
675 if(hdr->value) OPENSSL_free(hdr->value);
676 if(hdr->params) sk_MIME_PARAM_pop_free(hdr->params, mime_param_free);
677 OPENSSL_free(hdr);
678}
679
680static void mime_param_free(MIME_PARAM *param)
681{
682 if(param->param_name) OPENSSL_free(param->param_name);
683 if(param->param_value) OPENSSL_free(param->param_value);
684 OPENSSL_free(param);
685}
686
687/* Check for a multipart boundary. Returns:
688 * 0 : no boundary
689 * 1 : part boundary
690 * 2 : final boundary
691 */
692static int mime_bound_check(char *line, int linelen, char *bound, int blen)
693{
694 if(linelen == -1) linelen = strlen(line);
695 if(blen == -1) blen = strlen(bound);
696 /* Quickly eliminate if line length too short */
697 if(blen + 2 > linelen) return 0;
698 /* Check for part boundary */
699 if(!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) {
700 if(!strncmp(line + blen + 2, "--", 2)) return 2;
701 else return 1;
702 }
703 return 0;
704}
705
706static int strip_eol(char *linebuf, int *plen)
707 { 95 {
708 int len = *plen; 96 return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7));
709 char *p, c;
710 int is_eol = 0;
711 p = linebuf + len - 1;
712 for (p = linebuf + len - 1; len > 0; len--, p--)
713 {
714 c = *p;
715 if (c == '\n')
716 is_eol = 1;
717 else if (c != '\r')
718 break;
719 }
720 *plen = len;
721 return is_eol;
722 } 97 }
diff --git a/src/lib/libcrypto/pkcs7/pk7_smime.c b/src/lib/libcrypto/pkcs7/pk7_smime.c
index fd18ec3d95..86742d0dcd 100644
--- a/src/lib/libcrypto/pkcs7/pk7_smime.c
+++ b/src/lib/libcrypto/pkcs7/pk7_smime.c
@@ -63,24 +63,19 @@
63#include <openssl/x509.h> 63#include <openssl/x509.h>
64#include <openssl/x509v3.h> 64#include <openssl/x509v3.h>
65 65
66static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si);
67
66PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, 68PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
67 BIO *data, int flags) 69 BIO *data, int flags)
68{ 70{
69 PKCS7 *p7 = NULL; 71 PKCS7 *p7;
70 PKCS7_SIGNER_INFO *si;
71 BIO *p7bio = NULL;
72 STACK_OF(X509_ALGOR) *smcap = NULL;
73 int i; 72 int i;
74 73
75 if(!X509_check_private_key(signcert, pkey)) { 74 if(!(p7 = PKCS7_new()))
76 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); 75 {
77 return NULL;
78 }
79
80 if(!(p7 = PKCS7_new())) {
81 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); 76 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE);
82 return NULL; 77 return NULL;
83 } 78 }
84 79
85 if (!PKCS7_set_type(p7, NID_pkcs7_signed)) 80 if (!PKCS7_set_type(p7, NID_pkcs7_signed))
86 goto err; 81 goto err;
@@ -88,82 +83,185 @@ PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
88 if (!PKCS7_content_new(p7, NID_pkcs7_data)) 83 if (!PKCS7_content_new(p7, NID_pkcs7_data))
89 goto err; 84 goto err;
90 85
91 if (!(si = PKCS7_add_signature(p7,signcert,pkey,EVP_sha1()))) { 86 if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags))
92 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); 87 {
88 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_ADD_SIGNER_ERROR);
93 goto err; 89 goto err;
94 } 90 }
95 91
96 if(!(flags & PKCS7_NOCERTS)) { 92 if(!(flags & PKCS7_NOCERTS))
97 if (!PKCS7_add_certificate(p7, signcert)) 93 {
98 goto err; 94 for(i = 0; i < sk_X509_num(certs); i++)
99 if(certs) for(i = 0; i < sk_X509_num(certs); i++) 95 {
100 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) 96 if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i)))
101 goto err; 97 goto err;
102 } 98 }
99 }
103 100
104 if(!(flags & PKCS7_NOATTR)) { 101 if(flags & PKCS7_DETACHED)
105 if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, 102 PKCS7_set_detached(p7, 1);
106 V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) 103
107 goto err; 104 if (flags & (PKCS7_STREAM|PKCS7_PARTIAL))
108 /* Add SMIMECapabilities */ 105 return p7;
109 if(!(flags & PKCS7_NOSMIMECAP)) 106
107 if (PKCS7_final(p7, data, flags))
108 return p7;
109
110 err:
111 PKCS7_free(p7);
112 return NULL;
113}
114
115int PKCS7_final(PKCS7 *p7, BIO *data, int flags)
116 {
117 BIO *p7bio;
118 int ret = 0;
119 if (!(p7bio = PKCS7_dataInit(p7, NULL)))
110 { 120 {
111 if(!(smcap = sk_X509_ALGOR_new_null())) { 121 PKCS7err(PKCS7_F_PKCS7_FINAL,ERR_R_MALLOC_FAILURE);
112 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); 122 return 0;
113 goto err;
114 }
115#ifndef OPENSSL_NO_DES
116 if (!PKCS7_simple_smimecap (smcap, NID_des_ede3_cbc, -1))
117 goto err;
118#endif
119#ifndef OPENSSL_NO_RC2
120 if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 128))
121 goto err;
122 if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 64))
123 goto err;
124#endif
125#ifndef OPENSSL_NO_DES
126 if (!PKCS7_simple_smimecap (smcap, NID_des_cbc, -1))
127 goto err;
128#endif
129#ifndef OPENSSL_NO_RC2
130 if (!PKCS7_simple_smimecap (smcap, NID_rc2_cbc, 40))
131 goto err;
132#endif
133 if (!PKCS7_add_attrib_smimecap (si, smcap))
134 goto err;
135 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
136 smcap = NULL;
137 } 123 }
138 }
139 124
140 if(flags & PKCS7_DETACHED)PKCS7_set_detached(p7, 1); 125 SMIME_crlf_copy(data, p7bio, flags);
141 126
142 if (flags & PKCS7_STREAM) 127 (void)BIO_flush(p7bio);
143 return p7;
144 128
145 129
146 if (!(p7bio = PKCS7_dataInit(p7, NULL))) { 130 if (!PKCS7_dataFinal(p7,p7bio))
147 PKCS7err(PKCS7_F_PKCS7_SIGN,ERR_R_MALLOC_FAILURE); 131 {
132 PKCS7err(PKCS7_F_PKCS7_FINAL,PKCS7_R_PKCS7_DATASIGN);
148 goto err; 133 goto err;
134 }
135
136 ret = 1;
137
138 err:
139 BIO_free_all(p7bio);
140
141 return ret;
142
149 } 143 }
150 144
151 SMIME_crlf_copy(data, p7bio, flags); 145/* Check to see if a cipher exists and if so add S/MIME capabilities */
152 146
147static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
148 {
149 if (EVP_get_cipherbynid(nid))
150 return PKCS7_simple_smimecap(sk, nid, arg);
151 return 1;
152 }
153 153
154 if (!PKCS7_dataFinal(p7,p7bio)) { 154static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg)
155 PKCS7err(PKCS7_F_PKCS7_SIGN,PKCS7_R_PKCS7_DATASIGN); 155 {
156 goto err; 156 if (EVP_get_digestbynid(nid))
157 return PKCS7_simple_smimecap(sk, nid, arg);
158 return 1;
157 } 159 }
158 160
159 BIO_free_all(p7bio); 161PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert,
160 return p7; 162 EVP_PKEY *pkey, const EVP_MD *md,
161err: 163 int flags)
162 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); 164 {
163 BIO_free_all(p7bio); 165 PKCS7_SIGNER_INFO *si = NULL;
164 PKCS7_free(p7); 166 STACK_OF(X509_ALGOR) *smcap = NULL;
167 if(!X509_check_private_key(signcert, pkey))
168 {
169 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
170 PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
171 return NULL;
172 }
173
174 if (!(si = PKCS7_add_signature(p7,signcert,pkey, md)))
175 {
176 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
177 PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR);
178 return NULL;
179 }
180
181 if(!(flags & PKCS7_NOCERTS))
182 {
183 if (!PKCS7_add_certificate(p7, signcert))
184 goto err;
185 }
186
187 if(!(flags & PKCS7_NOATTR))
188 {
189 if (!PKCS7_add_attrib_content_type(si, NULL))
190 goto err;
191 /* Add SMIMECapabilities */
192 if(!(flags & PKCS7_NOSMIMECAP))
193 {
194 if(!(smcap = sk_X509_ALGOR_new_null()))
195 {
196 PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER,
197 ERR_R_MALLOC_FAILURE);
198 goto err;
199 }
200 if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
201 || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
202 || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
203 || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
204 || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
205 || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
206 || !add_cipher_smcap(smcap, NID_rc2_cbc, 128)
207 || !add_cipher_smcap(smcap, NID_rc2_cbc, 64)
208 || !add_cipher_smcap(smcap, NID_des_cbc, -1)
209 || !add_cipher_smcap(smcap, NID_rc2_cbc, 40)
210 || !PKCS7_add_attrib_smimecap (si, smcap))
211 goto err;
212 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
213 smcap = NULL;
214 }
215 if (flags & PKCS7_REUSE_DIGEST)
216 {
217 if (!pkcs7_copy_existing_digest(p7, si))
218 goto err;
219 if (!(flags & PKCS7_PARTIAL) &&
220 !PKCS7_SIGNER_INFO_sign(si))
221 goto err;
222 }
223 }
224 return si;
225 err:
226 if (smcap)
227 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
165 return NULL; 228 return NULL;
166} 229 }
230
231/* Search for a digest matching SignerInfo digest type and if found
232 * copy across.
233 */
234
235static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si)
236 {
237 int i;
238 STACK_OF(PKCS7_SIGNER_INFO) *sinfos;
239 PKCS7_SIGNER_INFO *sitmp;
240 ASN1_OCTET_STRING *osdig = NULL;
241 sinfos = PKCS7_get_signer_info(p7);
242 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++)
243 {
244 sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i);
245 if (si == sitmp)
246 break;
247 if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0)
248 continue;
249 if (!OBJ_cmp(si->digest_alg->algorithm,
250 sitmp->digest_alg->algorithm))
251 {
252 osdig = PKCS7_digest_from_attributes(sitmp->auth_attr);
253 break;
254 }
255
256 }
257
258 if (osdig)
259 return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length);
260
261 PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST,
262 PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND);
263 return 0;
264 }
167 265
168int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, 266int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
169 BIO *indata, BIO *out, int flags) 267 BIO *indata, BIO *out, int flags)
@@ -354,7 +452,7 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
354 452
355 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { 453 if(sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) {
356 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS); 454 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_NO_SIGNERS);
357 return NULL; 455 return 0;
358 } 456 }
359 457
360 if(!(signers = sk_X509_new_null())) { 458 if(!(signers = sk_X509_new_null())) {
@@ -377,12 +475,12 @@ STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags)
377 if (!signer) { 475 if (!signer) {
378 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); 476 PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS,PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND);
379 sk_X509_free(signers); 477 sk_X509_free(signers);
380 return NULL; 478 return 0;
381 } 479 }
382 480
383 if (!sk_X509_push(signers, signer)) { 481 if (!sk_X509_push(signers, signer)) {
384 sk_X509_free(signers); 482 sk_X509_free(signers);
385 return NULL; 483 return NULL;
386 } 484 }
387 } 485 }
388 return signers; 486 return signers;
@@ -405,7 +503,7 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
405 503
406 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) 504 if (!PKCS7_set_type(p7, NID_pkcs7_enveloped))
407 goto err; 505 goto err;
408 if(!PKCS7_set_cipher(p7, cipher)) { 506 if (!PKCS7_set_cipher(p7, cipher)) {
409 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER); 507 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
410 goto err; 508 goto err;
411 } 509 }
@@ -419,22 +517,11 @@ PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher,
419 } 517 }
420 } 518 }
421 519
422 if(!(p7bio = PKCS7_dataInit(p7, NULL))) { 520 if (flags & PKCS7_STREAM)
423 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,ERR_R_MALLOC_FAILURE); 521 return p7;
424 goto err;
425 }
426
427 SMIME_crlf_copy(in, p7bio, flags);
428
429 (void)BIO_flush(p7bio);
430
431 if (!PKCS7_dataFinal(p7,p7bio)) {
432 PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_PKCS7_DATAFINAL_ERROR);
433 goto err;
434 }
435 BIO_free_all(p7bio);
436 522
437 return p7; 523 if (PKCS7_final(p7, in, flags))
524 return p7;
438 525
439 err: 526 err:
440 527
diff --git a/src/lib/libcrypto/pkcs7/pkcs7.h b/src/lib/libcrypto/pkcs7/pkcs7.h
index cc092d262d..e4d443193c 100644
--- a/src/lib/libcrypto/pkcs7/pkcs7.h
+++ b/src/lib/libcrypto/pkcs7/pkcs7.h
@@ -232,6 +232,9 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
232#define PKCS7_type_is_signedAndEnveloped(a) \ 232#define PKCS7_type_is_signedAndEnveloped(a) \
233 (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) 233 (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped)
234#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) 234#define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data)
235#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
236#define PKCS7_type_is_encrypted(a) \
237 (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted)
235 238
236#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) 239#define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest)
237 240
@@ -242,14 +245,6 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
242 245
243#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) 246#define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7))
244 247
245#ifdef SSLEAY_MACROS
246#ifndef PKCS7_ISSUER_AND_SERIAL_digest
247#define PKCS7_ISSUER_AND_SERIAL_digest(data,type,md,len) \
248 ASN1_digest((int (*)())i2d_PKCS7_ISSUER_AND_SERIAL,type,\
249 (char *)data,md,len)
250#endif
251#endif
252
253/* S/MIME related flags */ 248/* S/MIME related flags */
254 249
255#define PKCS7_TEXT 0x1 250#define PKCS7_TEXT 0x1
@@ -266,6 +261,8 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
266#define PKCS7_CRLFEOL 0x800 261#define PKCS7_CRLFEOL 0x800
267#define PKCS7_STREAM 0x1000 262#define PKCS7_STREAM 0x1000
268#define PKCS7_NOCRL 0x2000 263#define PKCS7_NOCRL 0x2000
264#define PKCS7_PARTIAL 0x4000
265#define PKCS7_REUSE_DIGEST 0x8000
269 266
270/* Flags: for compatibility with older code */ 267/* Flags: for compatibility with older code */
271 268
@@ -281,7 +278,6 @@ DECLARE_PKCS12_STACK_OF(PKCS7)
281 278
282DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) 279DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL)
283 280
284#ifndef SSLEAY_MACROS
285int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type, 281int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data,const EVP_MD *type,
286 unsigned char *md,unsigned int *len); 282 unsigned char *md,unsigned int *len);
287#ifndef OPENSSL_NO_FP_API 283#ifndef OPENSSL_NO_FP_API
@@ -291,7 +287,8 @@ int i2d_PKCS7_fp(FILE *fp,PKCS7 *p7);
291PKCS7 *PKCS7_dup(PKCS7 *p7); 287PKCS7 *PKCS7_dup(PKCS7 *p7);
292PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7); 288PKCS7 *d2i_PKCS7_bio(BIO *bp,PKCS7 **p7);
293int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7); 289int i2d_PKCS7_bio(BIO *bp,PKCS7 *p7);
294#endif 290int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
291int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags);
295 292
296DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) 293DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO)
297DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) 294DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO)
@@ -307,6 +304,7 @@ DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN)
307DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) 304DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY)
308 305
309DECLARE_ASN1_NDEF_FUNCTION(PKCS7) 306DECLARE_ASN1_NDEF_FUNCTION(PKCS7)
307DECLARE_ASN1_PRINT_FUNCTION(PKCS7)
310 308
311long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); 309long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
312 310
@@ -315,6 +313,7 @@ int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
315int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); 313int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
316int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, 314int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
317 const EVP_MD *dgst); 315 const EVP_MD *dgst);
316int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
318int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); 317int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
319int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); 318int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
320int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); 319int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
@@ -336,9 +335,13 @@ int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
336STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); 335STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
337 336
338PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); 337PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
338void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
339 X509_ALGOR **pdig, X509_ALGOR **psig);
340void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc);
339int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); 341int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
340int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); 342int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
341int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); 343int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
344int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7);
342 345
343PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); 346PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
344ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); 347ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk);
@@ -355,6 +358,12 @@ int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,STACK_OF(X509_ATTRIBUTE) *sk);
355 358
356PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, 359PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs,
357 BIO *data, int flags); 360 BIO *data, int flags);
361
362PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7,
363 X509 *signcert, EVP_PKEY *pkey, const EVP_MD *md,
364 int flags);
365
366int PKCS7_final(PKCS7 *p7, BIO *data, int flags);
358int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, 367int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store,
359 BIO *indata, BIO *out, int flags); 368 BIO *indata, BIO *out, int flags);
360STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags); 369STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, int flags);
@@ -367,10 +376,16 @@ int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si,
367STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); 376STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si);
368int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); 377int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg);
369 378
379int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid);
380int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t);
381int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si,
382 const unsigned char *md, int mdlen);
383
370int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); 384int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags);
371PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); 385PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont);
372int SMIME_crlf_copy(BIO *in, BIO *out, int flags); 386
373int SMIME_text(BIO *in, BIO *out); 387BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7);
388
374 389
375/* BEGIN ERROR CODES */ 390/* BEGIN ERROR CODES */
376/* The following lines are auto generated by the script mkerr.pl. Any changes 391/* The following lines are auto generated by the script mkerr.pl. Any changes
@@ -383,12 +398,17 @@ void ERR_load_PKCS7_strings(void);
383/* Function codes. */ 398/* Function codes. */
384#define PKCS7_F_B64_READ_PKCS7 120 399#define PKCS7_F_B64_READ_PKCS7 120
385#define PKCS7_F_B64_WRITE_PKCS7 121 400#define PKCS7_F_B64_WRITE_PKCS7 121
401#define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136
402#define PKCS7_F_I2D_PKCS7_BIO_STREAM 140
403#define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135
386#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 404#define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118
387#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 405#define PKCS7_F_PKCS7_ADD_CERTIFICATE 100
388#define PKCS7_F_PKCS7_ADD_CRL 101 406#define PKCS7_F_PKCS7_ADD_CRL 101
389#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 407#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102
408#define PKCS7_F_PKCS7_ADD_SIGNATURE 131
390#define PKCS7_F_PKCS7_ADD_SIGNER 103 409#define PKCS7_F_PKCS7_ADD_SIGNER 103
391#define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 410#define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125
411#define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138
392#define PKCS7_F_PKCS7_CTRL 104 412#define PKCS7_F_PKCS7_CTRL 104
393#define PKCS7_F_PKCS7_DATADECODE 112 413#define PKCS7_F_PKCS7_DATADECODE 112
394#define PKCS7_F_PKCS7_DATAFINAL 128 414#define PKCS7_F_PKCS7_DATAFINAL 128
@@ -396,15 +416,22 @@ void ERR_load_PKCS7_strings(void);
396#define PKCS7_F_PKCS7_DATASIGN 106 416#define PKCS7_F_PKCS7_DATASIGN 106
397#define PKCS7_F_PKCS7_DATAVERIFY 107 417#define PKCS7_F_PKCS7_DATAVERIFY 107
398#define PKCS7_F_PKCS7_DECRYPT 114 418#define PKCS7_F_PKCS7_DECRYPT 114
419#define PKCS7_F_PKCS7_DECRYPT_RINFO 133
420#define PKCS7_F_PKCS7_ENCODE_RINFO 132
399#define PKCS7_F_PKCS7_ENCRYPT 115 421#define PKCS7_F_PKCS7_ENCRYPT 115
422#define PKCS7_F_PKCS7_FINAL 134
400#define PKCS7_F_PKCS7_FIND_DIGEST 127 423#define PKCS7_F_PKCS7_FIND_DIGEST 127
401#define PKCS7_F_PKCS7_GET0_SIGNERS 124 424#define PKCS7_F_PKCS7_GET0_SIGNERS 124
425#define PKCS7_F_PKCS7_RECIP_INFO_SET 130
402#define PKCS7_F_PKCS7_SET_CIPHER 108 426#define PKCS7_F_PKCS7_SET_CIPHER 108
403#define PKCS7_F_PKCS7_SET_CONTENT 109 427#define PKCS7_F_PKCS7_SET_CONTENT 109
404#define PKCS7_F_PKCS7_SET_DIGEST 126 428#define PKCS7_F_PKCS7_SET_DIGEST 126
405#define PKCS7_F_PKCS7_SET_TYPE 110 429#define PKCS7_F_PKCS7_SET_TYPE 110
406#define PKCS7_F_PKCS7_SIGN 116 430#define PKCS7_F_PKCS7_SIGN 116
407#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 431#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113
432#define PKCS7_F_PKCS7_SIGNER_INFO_SET 129
433#define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139
434#define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137
408#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 435#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119
409#define PKCS7_F_PKCS7_VERIFY 117 436#define PKCS7_F_PKCS7_VERIFY 117
410#define PKCS7_F_SMIME_READ_PKCS7 122 437#define PKCS7_F_SMIME_READ_PKCS7 122
@@ -415,10 +442,13 @@ void ERR_load_PKCS7_strings(void);
415#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 442#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144
416#define PKCS7_R_CIPHER_NOT_INITIALIZED 116 443#define PKCS7_R_CIPHER_NOT_INITIALIZED 116
417#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 444#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118
445#define PKCS7_R_CTRL_ERROR 152
418#define PKCS7_R_DECODE_ERROR 130 446#define PKCS7_R_DECODE_ERROR 130
419#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 447#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100
420#define PKCS7_R_DECRYPT_ERROR 119 448#define PKCS7_R_DECRYPT_ERROR 119
421#define PKCS7_R_DIGEST_FAILURE 101 449#define PKCS7_R_DIGEST_FAILURE 101
450#define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149
451#define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150
422#define PKCS7_R_ERROR_ADDING_RECIPIENT 120 452#define PKCS7_R_ERROR_ADDING_RECIPIENT 120
423#define PKCS7_R_ERROR_SETTING_CIPHER 121 453#define PKCS7_R_ERROR_SETTING_CIPHER 121
424#define PKCS7_R_INVALID_MIME_TYPE 131 454#define PKCS7_R_INVALID_MIME_TYPE 131
@@ -429,6 +459,8 @@ void ERR_load_PKCS7_strings(void);
429#define PKCS7_R_MISSING_CERIPEND_INFO 103 459#define PKCS7_R_MISSING_CERIPEND_INFO 103
430#define PKCS7_R_NO_CONTENT 122 460#define PKCS7_R_NO_CONTENT 122
431#define PKCS7_R_NO_CONTENT_TYPE 135 461#define PKCS7_R_NO_CONTENT_TYPE 135
462#define PKCS7_R_NO_DEFAULT_DIGEST 151
463#define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154
432#define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 464#define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136
433#define PKCS7_R_NO_MULTIPART_BOUNDARY 137 465#define PKCS7_R_NO_MULTIPART_BOUNDARY 137
434#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 466#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115
@@ -438,6 +470,7 @@ void ERR_load_PKCS7_strings(void);
438#define PKCS7_R_NO_SIG_CONTENT_TYPE 138 470#define PKCS7_R_NO_SIG_CONTENT_TYPE 138
439#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 471#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104
440#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 472#define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124
473#define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153
441#define PKCS7_R_PKCS7_DATAFINAL 126 474#define PKCS7_R_PKCS7_DATAFINAL 126
442#define PKCS7_R_PKCS7_DATAFINAL_ERROR 125 475#define PKCS7_R_PKCS7_DATAFINAL_ERROR 125
443#define PKCS7_R_PKCS7_DATASIGN 145 476#define PKCS7_R_PKCS7_DATASIGN 145
@@ -446,6 +479,8 @@ void ERR_load_PKCS7_strings(void);
446#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 479#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127
447#define PKCS7_R_SIGNATURE_FAILURE 105 480#define PKCS7_R_SIGNATURE_FAILURE 105
448#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 481#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128
482#define PKCS7_R_SIGNING_CTRL_FAILURE 147
483#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148
449#define PKCS7_R_SIG_INVALID_MIME_TYPE 141 484#define PKCS7_R_SIG_INVALID_MIME_TYPE 141
450#define PKCS7_R_SMIME_TEXT_ERROR 129 485#define PKCS7_R_SMIME_TEXT_ERROR 129
451#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 486#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106
diff --git a/src/lib/libcrypto/pkcs7/pkcs7err.c b/src/lib/libcrypto/pkcs7/pkcs7err.c
index c0e3d4cd33..d0af32a265 100644
--- a/src/lib/libcrypto/pkcs7/pkcs7err.c
+++ b/src/lib/libcrypto/pkcs7/pkcs7err.c
@@ -1,6 +1,6 @@
1/* crypto/pkcs7/pkcs7err.c */ 1/* crypto/pkcs7/pkcs7err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -72,12 +72,17 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
72 { 72 {
73{ERR_FUNC(PKCS7_F_B64_READ_PKCS7), "B64_READ_PKCS7"}, 73{ERR_FUNC(PKCS7_F_B64_READ_PKCS7), "B64_READ_PKCS7"},
74{ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7), "B64_WRITE_PKCS7"}, 74{ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7), "B64_WRITE_PKCS7"},
75{ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB), "DO_PKCS7_SIGNED_ATTRIB"},
76{ERR_FUNC(PKCS7_F_I2D_PKCS7_BIO_STREAM), "i2d_PKCS7_bio_stream"},
77{ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME), "PKCS7_add0_attrib_signing_time"},
75{ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP), "PKCS7_add_attrib_smimecap"}, 78{ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP), "PKCS7_add_attrib_smimecap"},
76{ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"}, 79{ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"},
77{ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"}, 80{ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"},
78{ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"}, 81{ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"},
82{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE), "PKCS7_add_signature"},
79{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"}, 83{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"},
80{ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_BIO_ADD_DIGEST"}, 84{ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_BIO_ADD_DIGEST"},
85{ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST), "PKCS7_COPY_EXISTING_DIGEST"},
81{ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"}, 86{ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"},
82{ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"}, 87{ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"},
83{ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"}, 88{ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"},
@@ -85,15 +90,22 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
85{ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"}, 90{ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"},
86{ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"}, 91{ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"},
87{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"}, 92{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"},
93{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO), "PKCS7_DECRYPT_RINFO"},
94{ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO), "PKCS7_ENCODE_RINFO"},
88{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"}, 95{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"},
96{ERR_FUNC(PKCS7_F_PKCS7_FINAL), "PKCS7_final"},
89{ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"}, 97{ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"},
90{ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"}, 98{ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"},
99{ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET), "PKCS7_RECIP_INFO_set"},
91{ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"}, 100{ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"},
92{ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"}, 101{ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"},
93{ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"}, 102{ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"},
94{ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"}, 103{ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"},
95{ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"}, 104{ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"},
96{ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"}, 105{ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"},
106{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET), "PKCS7_SIGNER_INFO_set"},
107{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN), "PKCS7_SIGNER_INFO_sign"},
108{ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER), "PKCS7_sign_add_signer"},
97{ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"}, 109{ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"},
98{ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"}, 110{ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"},
99{ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7), "SMIME_read_PKCS7"}, 111{ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7), "SMIME_read_PKCS7"},
@@ -107,10 +119,13 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
107{ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"}, 119{ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
108{ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"}, 120{ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"},
109{ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"}, 121{ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"},
122{ERR_REASON(PKCS7_R_CTRL_ERROR) ,"ctrl error"},
110{ERR_REASON(PKCS7_R_DECODE_ERROR) ,"decode error"}, 123{ERR_REASON(PKCS7_R_DECODE_ERROR) ,"decode error"},
111{ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"}, 124{ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"},
112{ERR_REASON(PKCS7_R_DECRYPT_ERROR) ,"decrypt error"}, 125{ERR_REASON(PKCS7_R_DECRYPT_ERROR) ,"decrypt error"},
113{ERR_REASON(PKCS7_R_DIGEST_FAILURE) ,"digest failure"}, 126{ERR_REASON(PKCS7_R_DIGEST_FAILURE) ,"digest failure"},
127{ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE),"encryption ctrl failure"},
128{ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"encryption not supported for this key type"},
114{ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT),"error adding recipient"}, 129{ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT),"error adding recipient"},
115{ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"}, 130{ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER),"error setting cipher"},
116{ERR_REASON(PKCS7_R_INVALID_MIME_TYPE) ,"invalid mime type"}, 131{ERR_REASON(PKCS7_R_INVALID_MIME_TYPE) ,"invalid mime type"},
@@ -121,6 +136,8 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
121{ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO),"missing ceripend info"}, 136{ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO),"missing ceripend info"},
122{ERR_REASON(PKCS7_R_NO_CONTENT) ,"no content"}, 137{ERR_REASON(PKCS7_R_NO_CONTENT) ,"no content"},
123{ERR_REASON(PKCS7_R_NO_CONTENT_TYPE) ,"no content type"}, 138{ERR_REASON(PKCS7_R_NO_CONTENT_TYPE) ,"no content type"},
139{ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST) ,"no default digest"},
140{ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND),"no matching digest type found"},
124{ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"}, 141{ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
125{ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"}, 142{ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
126{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"}, 143{ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE),"no recipient matches certificate"},
@@ -130,6 +147,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
130{ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"}, 147{ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"},
131{ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),"operation not supported on this type"}, 148{ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE),"operation not supported on this type"},
132{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"}, 149{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR),"pkcs7 add signature error"},
150{ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR),"pkcs7 add signer error"},
133{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL) ,"pkcs7 datafinal"}, 151{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL) ,"pkcs7 datafinal"},
134{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR),"pkcs7 datafinal error"}, 152{ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR),"pkcs7 datafinal error"},
135{ERR_REASON(PKCS7_R_PKCS7_DATASIGN) ,"pkcs7 datasign"}, 153{ERR_REASON(PKCS7_R_PKCS7_DATASIGN) ,"pkcs7 datasign"},
@@ -138,6 +156,8 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
138{ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"}, 156{ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
139{ERR_REASON(PKCS7_R_SIGNATURE_FAILURE) ,"signature failure"}, 157{ERR_REASON(PKCS7_R_SIGNATURE_FAILURE) ,"signature failure"},
140{ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"}, 158{ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
159{ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE),"signing ctrl failure"},
160{ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"signing not supported for this key type"},
141{ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"}, 161{ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
142{ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR) ,"smime text error"}, 162{ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR) ,"smime text error"},
143{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),"unable to find certificate"}, 163{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),"unable to find certificate"},