summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/cms/cms_smime.c
diff options
context:
space:
mode:
authorjsing <>2019-08-10 16:42:20 +0000
committerjsing <>2019-08-10 16:42:20 +0000
commit348e8055f6b4ea773466a117767c16e615a549ab (patch)
treefd2cdff41f524a9488d8863f2cd9058c06fe6058 /src/lib/libcrypto/cms/cms_smime.c
parentd2294fe6ec6b67e094cc8b699125f5d1027c17e3 (diff)
downloadopenbsd-348e8055f6b4ea773466a117767c16e615a549ab.tar.gz
openbsd-348e8055f6b4ea773466a117767c16e615a549ab.tar.bz2
openbsd-348e8055f6b4ea773466a117767c16e615a549ab.zip
First pass at style(9).
Whitespace only and no change according to diff -w.
Diffstat (limited to 'src/lib/libcrypto/cms/cms_smime.c')
-rw-r--r--src/lib/libcrypto/cms/cms_smime.c1326
1 files changed, 663 insertions, 663 deletions
diff --git a/src/lib/libcrypto/cms/cms_smime.c b/src/lib/libcrypto/cms/cms_smime.c
index fcb263da64..f3dcd05ee1 100644
--- a/src/lib/libcrypto/cms/cms_smime.c
+++ b/src/lib/libcrypto/cms/cms_smime.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: cms_smime.c,v 1.18 2019/08/10 16:39:17 jsing Exp $ */ 1/* $OpenBSD: cms_smime.c,v 1.19 2019/08/10 16:42:20 jsing Exp $ */
2/* 2/*
3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 3 * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4 * project. 4 * project.
@@ -63,826 +63,826 @@
63 63
64static BIO *cms_get_text_bio(BIO *out, unsigned int flags) 64static BIO *cms_get_text_bio(BIO *out, unsigned int flags)
65{ 65{
66 BIO *rbio; 66 BIO *rbio;
67 if (out == NULL) 67 if (out == NULL)
68 rbio = BIO_new(BIO_s_null()); 68 rbio = BIO_new(BIO_s_null());
69 else if (flags & CMS_TEXT) { 69 else if (flags & CMS_TEXT) {
70 rbio = BIO_new(BIO_s_mem()); 70 rbio = BIO_new(BIO_s_mem());
71 BIO_set_mem_eof_return(rbio, 0); 71 BIO_set_mem_eof_return(rbio, 0);
72 } else 72 } else
73 rbio = out; 73 rbio = out;
74 return rbio; 74 return rbio;
75} 75}
76 76
77static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) 77static int cms_copy_content(BIO *out, BIO *in, unsigned int flags)
78{ 78{
79 unsigned char buf[4096]; 79 unsigned char buf[4096];
80 int r = 0, i; 80 int r = 0, i;
81 BIO *tmpout; 81 BIO *tmpout;
82 82
83 tmpout = cms_get_text_bio(out, flags); 83 tmpout = cms_get_text_bio(out, flags);
84 84
85 if (tmpout == NULL) { 85 if (tmpout == NULL) {
86 CMSerr(CMS_F_CMS_COPY_CONTENT, ERR_R_MALLOC_FAILURE); 86 CMSerr(CMS_F_CMS_COPY_CONTENT, ERR_R_MALLOC_FAILURE);
87 goto err; 87 goto err;
88 } 88 }
89 89
90 /* Read all content through chain to process digest, decrypt etc */ 90 /* Read all content through chain to process digest, decrypt etc */
91 for (;;) { 91 for (;;) {
92 i = BIO_read(in, buf, sizeof(buf)); 92 i = BIO_read(in, buf, sizeof(buf));
93 if (i <= 0) { 93 if (i <= 0) {
94 if (BIO_method_type(in) == BIO_TYPE_CIPHER) { 94 if (BIO_method_type(in) == BIO_TYPE_CIPHER) {
95 if (!BIO_get_cipher_status(in)) 95 if (!BIO_get_cipher_status(in))
96 goto err; 96 goto err;
97 } 97 }
98 if (i < 0) 98 if (i < 0)
99 goto err; 99 goto err;
100 break; 100 break;
101 } 101 }
102 102
103 if (tmpout && (BIO_write(tmpout, buf, i) != i)) 103 if (tmpout && (BIO_write(tmpout, buf, i) != i))
104 goto err; 104 goto err;
105 } 105 }
106 106
107 if (flags & CMS_TEXT) { 107 if (flags & CMS_TEXT) {
108 if (!SMIME_text(tmpout, out)) { 108 if (!SMIME_text(tmpout, out)) {
109 CMSerr(CMS_F_CMS_COPY_CONTENT, CMS_R_SMIME_TEXT_ERROR); 109 CMSerr(CMS_F_CMS_COPY_CONTENT, CMS_R_SMIME_TEXT_ERROR);
110 goto err; 110 goto err;
111 } 111 }
112 } 112 }
113 113
114 r = 1; 114 r = 1;
115 115
116 err: 116 err:
117 if (tmpout != out) 117 if (tmpout != out)
118 BIO_free(tmpout); 118 BIO_free(tmpout);
119 return r; 119 return r;
120 120
121} 121}
122 122
123static int check_content(CMS_ContentInfo *cms) 123static int check_content(CMS_ContentInfo *cms)
124{ 124{
125 ASN1_OCTET_STRING **pos = CMS_get0_content(cms); 125 ASN1_OCTET_STRING **pos = CMS_get0_content(cms);
126 if (!pos || !*pos) { 126 if (!pos || !*pos) {
127 CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT); 127 CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT);
128 return 0; 128 return 0;
129 } 129 }
130 return 1; 130 return 1;
131} 131}
132 132
133static void do_free_upto(BIO *f, BIO *upto) 133static void do_free_upto(BIO *f, BIO *upto)
134{ 134{
135 if (upto) { 135 if (upto) {
136 BIO *tbio; 136 BIO *tbio;
137 do { 137 do {
138 tbio = BIO_pop(f); 138 tbio = BIO_pop(f);
139 BIO_free(f); 139 BIO_free(f);
140 f = tbio; 140 f = tbio;
141 } 141 }
142 while (f && f != upto); 142 while (f && f != upto);
143 } else 143 } else
144 BIO_free_all(f); 144 BIO_free_all(f);
145} 145}
146 146
147int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) 147int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags)
148{ 148{
149 BIO *cont; 149 BIO *cont;
150 int r; 150 int r;
151 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) { 151 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) {
152 CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA); 152 CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA);
153 return 0; 153 return 0;
154 } 154 }
155 cont = CMS_dataInit(cms, NULL); 155 cont = CMS_dataInit(cms, NULL);
156 if (!cont) 156 if (!cont)
157 return 0; 157 return 0;
158 r = cms_copy_content(out, cont, flags); 158 r = cms_copy_content(out, cont, flags);
159 BIO_free_all(cont); 159 BIO_free_all(cont);
160 return r; 160 return r;
161} 161}
162 162
163CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) 163CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags)
164{ 164{
165 CMS_ContentInfo *cms; 165 CMS_ContentInfo *cms;
166 cms = cms_Data_create(); 166 cms = cms_Data_create();
167 if (!cms) 167 if (!cms)
168 return NULL; 168 return NULL;
169 169
170 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 170 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
171 return cms; 171 return cms;
172 172
173 CMS_ContentInfo_free(cms); 173 CMS_ContentInfo_free(cms);
174 174
175 return NULL; 175 return NULL;
176} 176}
177 177
178int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, 178int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
179 unsigned int flags) 179 unsigned int flags)
180{ 180{
181 BIO *cont; 181 BIO *cont;
182 int r; 182 int r;
183 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) { 183 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) {
184 CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA); 184 CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA);
185 return 0; 185 return 0;
186 } 186 }
187 187
188 if (!dcont && !check_content(cms)) 188 if (!dcont && !check_content(cms))
189 return 0; 189 return 0;
190 190
191 cont = CMS_dataInit(cms, dcont); 191 cont = CMS_dataInit(cms, dcont);
192 if (!cont) 192 if (!cont)
193 return 0; 193 return 0;
194 r = cms_copy_content(out, cont, flags); 194 r = cms_copy_content(out, cont, flags);
195 if (r) 195 if (r)
196 r = cms_DigestedData_do_final(cms, cont, 1); 196 r = cms_DigestedData_do_final(cms, cont, 1);
197 do_free_upto(cont, dcont); 197 do_free_upto(cont, dcont);
198 return r; 198 return r;
199} 199}
200 200
201CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, 201CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md,
202 unsigned int flags) 202 unsigned int flags)
203{ 203{
204 CMS_ContentInfo *cms; 204 CMS_ContentInfo *cms;
205 if (!md) 205 if (!md)
206 md = EVP_sha1(); 206 md = EVP_sha1();
207 cms = cms_DigestedData_create(md); 207 cms = cms_DigestedData_create(md);
208 if (!cms) 208 if (!cms)
209 return NULL; 209 return NULL;
210 210
211 if (!(flags & CMS_DETACHED)) 211 if (!(flags & CMS_DETACHED))
212 CMS_set_detached(cms, 0); 212 CMS_set_detached(cms, 0);
213 213
214 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 214 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
215 return cms; 215 return cms;
216 216
217 CMS_ContentInfo_free(cms); 217 CMS_ContentInfo_free(cms);
218 return NULL; 218 return NULL;
219} 219}
220 220
221int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, 221int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms,
222 const unsigned char *key, size_t keylen, 222 const unsigned char *key, size_t keylen,
223 BIO *dcont, BIO *out, unsigned int flags) 223 BIO *dcont, BIO *out, unsigned int flags)
224{ 224{
225 BIO *cont; 225 BIO *cont;
226 int r; 226 int r;
227 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) { 227 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) {
228 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, 228 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT,
229 CMS_R_TYPE_NOT_ENCRYPTED_DATA); 229 CMS_R_TYPE_NOT_ENCRYPTED_DATA);
230 return 0; 230 return 0;
231 } 231 }
232 232
233 if (!dcont && !check_content(cms)) 233 if (!dcont && !check_content(cms))
234 return 0; 234 return 0;
235 235
236 if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) 236 if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0)
237 return 0; 237 return 0;
238 cont = CMS_dataInit(cms, dcont); 238 cont = CMS_dataInit(cms, dcont);
239 if (!cont) 239 if (!cont)
240 return 0; 240 return 0;
241 r = cms_copy_content(out, cont, flags); 241 r = cms_copy_content(out, cont, flags);
242 do_free_upto(cont, dcont); 242 do_free_upto(cont, dcont);
243 return r; 243 return r;
244} 244}
245 245
246CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, 246CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher,
247 const unsigned char *key, 247 const unsigned char *key,
248 size_t keylen, unsigned int flags) 248 size_t keylen, unsigned int flags)
249{ 249{
250 CMS_ContentInfo *cms; 250 CMS_ContentInfo *cms;
251 if (!cipher) { 251 if (!cipher) {
252 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER); 252 CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER);
253 return NULL; 253 return NULL;
254 } 254 }
255 cms = CMS_ContentInfo_new(); 255 cms = CMS_ContentInfo_new();
256 if (cms == NULL) 256 if (cms == NULL)
257 return NULL; 257 return NULL;
258 if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) 258 if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen))
259 return NULL; 259 return NULL;
260 260
261 if (!(flags & CMS_DETACHED)) 261 if (!(flags & CMS_DETACHED))
262 CMS_set_detached(cms, 0); 262 CMS_set_detached(cms, 0);
263 263
264 if ((flags & (CMS_STREAM | CMS_PARTIAL)) 264 if ((flags & (CMS_STREAM | CMS_PARTIAL))
265 || CMS_final(cms, in, NULL, flags)) 265 || CMS_final(cms, in, NULL, flags))
266 return cms; 266 return cms;
267 267
268 CMS_ContentInfo_free(cms); 268 CMS_ContentInfo_free(cms);
269 return NULL; 269 return NULL;
270} 270}
271 271
272static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, 272static int cms_signerinfo_verify_cert(CMS_SignerInfo *si,
273 X509_STORE *store, 273 X509_STORE *store,
274 STACK_OF(X509) *certs, 274 STACK_OF(X509) *certs,
275 STACK_OF(X509_CRL) *crls) 275 STACK_OF(X509_CRL) *crls)
276{ 276{
277 X509_STORE_CTX *ctx = X509_STORE_CTX_new(); 277 X509_STORE_CTX *ctx = X509_STORE_CTX_new();
278 X509 *signer; 278 X509 *signer;
279 int i, j, r = 0; 279 int i, j, r = 0;
280 280
281 if (ctx == NULL) { 281 if (ctx == NULL) {
282 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, ERR_R_MALLOC_FAILURE); 282 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
283 goto err; 283 goto err;
284 } 284 }
285 CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); 285 CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
286 if (!X509_STORE_CTX_init(ctx, store, signer, certs)) { 286 if (!X509_STORE_CTX_init(ctx, store, signer, certs)) {
287 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR); 287 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR);
288 goto err; 288 goto err;
289 } 289 }
290 X509_STORE_CTX_set_default(ctx, "smime_sign"); 290 X509_STORE_CTX_set_default(ctx, "smime_sign");
291 if (crls) 291 if (crls)
292 X509_STORE_CTX_set0_crls(ctx, crls); 292 X509_STORE_CTX_set0_crls(ctx, crls);
293 293
294 i = X509_verify_cert(ctx); 294 i = X509_verify_cert(ctx);
295 if (i <= 0) { 295 if (i <= 0) {
296 j = X509_STORE_CTX_get_error(ctx); 296 j = X509_STORE_CTX_get_error(ctx);
297 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, 297 CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT,
298 CMS_R_CERTIFICATE_VERIFY_ERROR); 298 CMS_R_CERTIFICATE_VERIFY_ERROR);
299 ERR_add_error_data(2, "Verify error:", 299 ERR_add_error_data(2, "Verify error:",
300 X509_verify_cert_error_string(j)); 300 X509_verify_cert_error_string(j));
301 goto err; 301 goto err;
302 } 302 }
303 r = 1; 303 r = 1;
304 err: 304 err:
305 X509_STORE_CTX_free(ctx); 305 X509_STORE_CTX_free(ctx);
306 return r; 306 return r;
307 307
308} 308}
309 309
310int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, 310int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs,
311 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags) 311 X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags)
312{ 312{
313 CMS_SignerInfo *si; 313 CMS_SignerInfo *si;
314 STACK_OF(CMS_SignerInfo) *sinfos; 314 STACK_OF(CMS_SignerInfo) *sinfos;
315 STACK_OF(X509) *cms_certs = NULL; 315 STACK_OF(X509) *cms_certs = NULL;
316 STACK_OF(X509_CRL) *crls = NULL; 316 STACK_OF(X509_CRL) *crls = NULL;
317 X509 *signer; 317 X509 *signer;
318 int i, scount = 0, ret = 0; 318 int i, scount = 0, ret = 0;
319 BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL; 319 BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL;
320 320
321 if (!dcont && !check_content(cms)) 321 if (!dcont && !check_content(cms))
322 return 0; 322 return 0;
323 if (dcont && !(flags & CMS_BINARY)) { 323 if (dcont && !(flags & CMS_BINARY)) {
324 const ASN1_OBJECT *coid = CMS_get0_eContentType(cms); 324 const ASN1_OBJECT *coid = CMS_get0_eContentType(cms);
325 if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF) 325 if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF)
326 flags |= CMS_ASCIICRLF; 326 flags |= CMS_ASCIICRLF;
327 } 327 }
328 328
329 /* Attempt to find all signer certificates */ 329 /* Attempt to find all signer certificates */
330 330
331 sinfos = CMS_get0_SignerInfos(cms); 331 sinfos = CMS_get0_SignerInfos(cms);
332 332
333 if (sk_CMS_SignerInfo_num(sinfos) <= 0) { 333 if (sk_CMS_SignerInfo_num(sinfos) <= 0) {
334 CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS); 334 CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS);
335 goto err; 335 goto err;
336 } 336 }
337 337
338 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 338 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
339 si = sk_CMS_SignerInfo_value(sinfos, i); 339 si = sk_CMS_SignerInfo_value(sinfos, i);
340 CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); 340 CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL);
341 if (signer) 341 if (signer)
342 scount++; 342 scount++;
343 } 343 }
344 344
345 if (scount != sk_CMS_SignerInfo_num(sinfos)) 345 if (scount != sk_CMS_SignerInfo_num(sinfos))
346 scount += CMS_set1_signers_certs(cms, certs, flags); 346 scount += CMS_set1_signers_certs(cms, certs, flags);
347 347
348 if (scount != sk_CMS_SignerInfo_num(sinfos)) { 348 if (scount != sk_CMS_SignerInfo_num(sinfos)) {
349 CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); 349 CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND);
350 goto err; 350 goto err;
351 } 351 }
352 352
353 /* Attempt to verify all signers certs */ 353 /* Attempt to verify all signers certs */
354 354
355 if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) { 355 if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) {
356 cms_certs = CMS_get1_certs(cms); 356 cms_certs = CMS_get1_certs(cms);
357 if (!(flags & CMS_NOCRL)) 357 if (!(flags & CMS_NOCRL))
358 crls = CMS_get1_crls(cms); 358 crls = CMS_get1_crls(cms);
359 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 359 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
360 si = sk_CMS_SignerInfo_value(sinfos, i); 360 si = sk_CMS_SignerInfo_value(sinfos, i);
361 if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls)) 361 if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls))
362 goto err; 362 goto err;
363 } 363 }
364 } 364 }
365 365
366 /* Attempt to verify all SignerInfo signed attribute signatures */ 366 /* Attempt to verify all SignerInfo signed attribute signatures */
367 367
368 if (!(flags & CMS_NO_ATTR_VERIFY)) { 368 if (!(flags & CMS_NO_ATTR_VERIFY)) {
369 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 369 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
370 si = sk_CMS_SignerInfo_value(sinfos, i); 370 si = sk_CMS_SignerInfo_value(sinfos, i);
371 if (CMS_signed_get_attr_count(si) < 0) 371 if (CMS_signed_get_attr_count(si) < 0)
372 continue; 372 continue;
373 if (CMS_SignerInfo_verify(si) <= 0) 373 if (CMS_SignerInfo_verify(si) <= 0)
374 goto err; 374 goto err;
375 } 375 }
376 } 376 }
377 377
378 /* 378 /*
379 * Performance optimization: if the content is a memory BIO then store 379 * Performance optimization: if the content is a memory BIO then store
380 * its contents in a temporary read only memory BIO. This avoids 380 * its contents in a temporary read only memory BIO. This avoids
381 * potentially large numbers of slow copies of data which will occur when 381 * potentially large numbers of slow copies of data which will occur when
382 * reading from a read write memory BIO when signatures are calculated. 382 * reading from a read write memory BIO when signatures are calculated.
383 */ 383 */
384 384
385 if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { 385 if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) {
386 char *ptr; 386 char *ptr;
387 long len; 387 long len;
388 len = BIO_get_mem_data(dcont, &ptr); 388 len = BIO_get_mem_data(dcont, &ptr);
389 tmpin = BIO_new_mem_buf(ptr, len); 389 tmpin = BIO_new_mem_buf(ptr, len);
390 if (tmpin == NULL) { 390 if (tmpin == NULL) {
391 CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); 391 CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
392 goto err2; 392 goto err2;
393 } 393 }
394 } else 394 } else
395 tmpin = dcont; 395 tmpin = dcont;
396 /* 396 /*
397 * If not binary mode and detached generate digests by *writing* through 397 * If not binary mode and detached generate digests by *writing* through
398 * the BIO. That makes it possible to canonicalise the input. 398 * the BIO. That makes it possible to canonicalise the input.
399 */ 399 */
400 if (!(flags & SMIME_BINARY) && dcont) { 400 if (!(flags & SMIME_BINARY) && dcont) {
401 /* 401 /*
402 * Create output BIO so we can either handle text or to ensure 402 * Create output BIO so we can either handle text or to ensure
403 * included content doesn't override detached content. 403 * included content doesn't override detached content.
404 */ 404 */
405 tmpout = cms_get_text_bio(out, flags); 405 tmpout = cms_get_text_bio(out, flags);
406 if (!tmpout) { 406 if (!tmpout) {
407 CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); 407 CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE);
408 goto err; 408 goto err;
409 } 409 }
410 cmsbio = CMS_dataInit(cms, tmpout); 410 cmsbio = CMS_dataInit(cms, tmpout);
411 if (!cmsbio) 411 if (!cmsbio)
412 goto err; 412 goto err;
413 /* 413 /*
414 * Don't use SMIME_TEXT for verify: it adds headers and we want to 414 * Don't use SMIME_TEXT for verify: it adds headers and we want to
415 * remove them. 415 * remove them.
416 */ 416 */
417 SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT); 417 SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT);
418 418
419 if (flags & CMS_TEXT) { 419 if (flags & CMS_TEXT) {
420 if (!SMIME_text(tmpout, out)) { 420 if (!SMIME_text(tmpout, out)) {
421 CMSerr(CMS_F_CMS_VERIFY, CMS_R_SMIME_TEXT_ERROR); 421 CMSerr(CMS_F_CMS_VERIFY, CMS_R_SMIME_TEXT_ERROR);
422 goto err; 422 goto err;
423 } 423 }
424 } 424 }
425 } else { 425 } else {
426 cmsbio = CMS_dataInit(cms, tmpin); 426 cmsbio = CMS_dataInit(cms, tmpin);
427 if (!cmsbio) 427 if (!cmsbio)
428 goto err; 428 goto err;
429 429
430 if (!cms_copy_content(out, cmsbio, flags)) 430 if (!cms_copy_content(out, cmsbio, flags))
431 goto err; 431 goto err;
432 432
433 } 433 }
434 if (!(flags & CMS_NO_CONTENT_VERIFY)) { 434 if (!(flags & CMS_NO_CONTENT_VERIFY)) {
435 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { 435 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
436 si = sk_CMS_SignerInfo_value(sinfos, i); 436 si = sk_CMS_SignerInfo_value(sinfos, i);
437 if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) { 437 if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) {
438 CMSerr(CMS_F_CMS_VERIFY, CMS_R_CONTENT_VERIFY_ERROR); 438 CMSerr(CMS_F_CMS_VERIFY, CMS_R_CONTENT_VERIFY_ERROR);
439 goto err; 439 goto err;
440 } 440 }
441 } 441 }
442 } 442 }
443 443
444 ret = 1; 444 ret = 1;
445 445
446 err: 446 err:
447 if (!(flags & SMIME_BINARY) && dcont) { 447 if (!(flags & SMIME_BINARY) && dcont) {
448 do_free_upto(cmsbio, tmpout); 448 do_free_upto(cmsbio, tmpout);
449 if (tmpin != dcont) 449 if (tmpin != dcont)
450 BIO_free(tmpin); 450 BIO_free(tmpin);
451 } else { 451 } else {
452 if (dcont && (tmpin == dcont)) 452 if (dcont && (tmpin == dcont))
453 do_free_upto(cmsbio, dcont); 453 do_free_upto(cmsbio, dcont);
454 else 454 else
455 BIO_free_all(cmsbio); 455 BIO_free_all(cmsbio);
456 } 456 }
457 457
458 if (out != tmpout) 458 if (out != tmpout)
459 BIO_free_all(tmpout); 459 BIO_free_all(tmpout);
460 460
461 err2: 461 err2:
462 sk_X509_pop_free(cms_certs, X509_free); 462 sk_X509_pop_free(cms_certs, X509_free);
463 sk_X509_CRL_pop_free(crls, X509_CRL_free); 463 sk_X509_CRL_pop_free(crls, X509_CRL_free);
464 464
465 return ret; 465 return ret;
466} 466}
467 467
468int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, 468int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms,
469 STACK_OF(X509) *certs, 469 STACK_OF(X509) *certs,
470 X509_STORE *store, unsigned int flags) 470 X509_STORE *store, unsigned int flags)
471{ 471{
472 int r; 472 int r;
473 flags &= ~(CMS_DETACHED | CMS_TEXT); 473 flags &= ~(CMS_DETACHED | CMS_TEXT);
474 r = CMS_verify(rcms, certs, store, NULL, NULL, flags); 474 r = CMS_verify(rcms, certs, store, NULL, NULL, flags);
475 if (r <= 0) 475 if (r <= 0)
476 return r; 476 return r;
477 return cms_Receipt_verify(rcms, ocms); 477 return cms_Receipt_verify(rcms, ocms);
478} 478}
479 479
480CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, 480CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey,
481 STACK_OF(X509) *certs, BIO *data, 481 STACK_OF(X509) *certs, BIO *data,
482 unsigned int flags) 482 unsigned int flags)
483{ 483{
484 CMS_ContentInfo *cms; 484 CMS_ContentInfo *cms;
485 int i; 485 int i;
486 486
487 cms = CMS_ContentInfo_new(); 487 cms = CMS_ContentInfo_new();
488 if (cms == NULL || !CMS_SignedData_init(cms)) 488 if (cms == NULL || !CMS_SignedData_init(cms))
489 goto merr; 489 goto merr;
490 if (flags & CMS_ASCIICRLF 490 if (flags & CMS_ASCIICRLF
491 && !CMS_set1_eContentType(cms, 491 && !CMS_set1_eContentType(cms,
492 OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF))) 492 OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF)))
493 goto err; 493 goto err;
494 494
495 if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { 495 if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) {
496 CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR); 496 CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR);
497 goto err; 497 goto err;
498 } 498 }
499 499
500 for (i = 0; i < sk_X509_num(certs); i++) { 500 for (i = 0; i < sk_X509_num(certs); i++) {
501 X509 *x = sk_X509_value(certs, i); 501 X509 *x = sk_X509_value(certs, i);
502 if (!CMS_add1_cert(cms, x)) 502 if (!CMS_add1_cert(cms, x))
503 goto merr; 503 goto merr;
504 } 504 }
505 505
506 if (!(flags & CMS_DETACHED)) 506 if (!(flags & CMS_DETACHED))
507 CMS_set_detached(cms, 0); 507 CMS_set_detached(cms, 0);
508 508
509 if ((flags & (CMS_STREAM | CMS_PARTIAL)) 509 if ((flags & (CMS_STREAM | CMS_PARTIAL))
510 || CMS_final(cms, data, NULL, flags)) 510 || CMS_final(cms, data, NULL, flags))
511 return cms; 511 return cms;
512 else 512 else
513 goto err; 513 goto err;
514 514
515 merr: 515 merr:
516 CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE); 516 CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE);
517 517
518 err: 518 err:
519 CMS_ContentInfo_free(cms); 519 CMS_ContentInfo_free(cms);
520 return NULL; 520 return NULL;
521} 521}
522 522
523CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, 523CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si,
524 X509 *signcert, EVP_PKEY *pkey, 524 X509 *signcert, EVP_PKEY *pkey,
525 STACK_OF(X509) *certs, unsigned int flags) 525 STACK_OF(X509) *certs, unsigned int flags)
526{ 526{
527 CMS_SignerInfo *rct_si; 527 CMS_SignerInfo *rct_si;
528 CMS_ContentInfo *cms = NULL; 528 CMS_ContentInfo *cms = NULL;
529 ASN1_OCTET_STRING **pos, *os; 529 ASN1_OCTET_STRING **pos, *os;
530 BIO *rct_cont = NULL; 530 BIO *rct_cont = NULL;
531 int r = 0; 531 int r = 0;
532 532
533 flags &= ~(CMS_STREAM | CMS_TEXT); 533 flags &= ~(CMS_STREAM | CMS_TEXT);
534 /* Not really detached but avoids content being allocated */ 534 /* Not really detached but avoids content being allocated */
535 flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED; 535 flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED;
536 if (!pkey || !signcert) { 536 if (!pkey || !signcert) {
537 CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT); 537 CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT);
538 return NULL; 538 return NULL;
539 } 539 }
540 540
541 /* Initialize signed data */ 541 /* Initialize signed data */
542 542
543 cms = CMS_sign(NULL, NULL, certs, NULL, flags); 543 cms = CMS_sign(NULL, NULL, certs, NULL, flags);
544 if (!cms) 544 if (!cms)
545 goto err; 545 goto err;
546 546
547 /* Set inner content type to signed receipt */ 547 /* Set inner content type to signed receipt */
548 if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt))) 548 if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt)))
549 goto err; 549 goto err;
550 550
551 rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); 551 rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags);
552 if (!rct_si) { 552 if (!rct_si) {
553 CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR); 553 CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR);
554 goto err; 554 goto err;
555 } 555 }
556 556
557 os = cms_encode_Receipt(si); 557 os = cms_encode_Receipt(si);
558 558
559 if (!os) 559 if (!os)
560 goto err; 560 goto err;
561 561
562 /* Set content to digest */ 562 /* Set content to digest */
563 rct_cont = BIO_new_mem_buf(os->data, os->length); 563 rct_cont = BIO_new_mem_buf(os->data, os->length);
564 if (!rct_cont) 564 if (!rct_cont)
565 goto err; 565 goto err;
566 566
567 /* Add msgSigDigest attribute */ 567 /* Add msgSigDigest attribute */
568 568
569 if (!cms_msgSigDigest_add1(rct_si, si)) 569 if (!cms_msgSigDigest_add1(rct_si, si))
570 goto err; 570 goto err;
571 571
572 /* Finalize structure */ 572 /* Finalize structure */
573 if (!CMS_final(cms, rct_cont, NULL, flags)) 573 if (!CMS_final(cms, rct_cont, NULL, flags))
574 goto err; 574 goto err;
575 575
576 /* Set embedded content */ 576 /* Set embedded content */
577 pos = CMS_get0_content(cms); 577 pos = CMS_get0_content(cms);
578 *pos = os; 578 *pos = os;
579 579
580 r = 1; 580 r = 1;
581 581
582 err: 582 err:
583 BIO_free(rct_cont); 583 BIO_free(rct_cont);
584 if (r) 584 if (r)
585 return cms; 585 return cms;
586 CMS_ContentInfo_free(cms); 586 CMS_ContentInfo_free(cms);
587 return NULL; 587 return NULL;
588 588
589} 589}
590 590
591CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, 591CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data,
592 const EVP_CIPHER *cipher, unsigned int flags) 592 const EVP_CIPHER *cipher, unsigned int flags)
593{ 593{
594 CMS_ContentInfo *cms; 594 CMS_ContentInfo *cms;
595 int i; 595 int i;
596 X509 *recip; 596 X509 *recip;
597 cms = CMS_EnvelopedData_create(cipher); 597 cms = CMS_EnvelopedData_create(cipher);
598 if (!cms) 598 if (!cms)
599 goto merr; 599 goto merr;
600 for (i = 0; i < sk_X509_num(certs); i++) { 600 for (i = 0; i < sk_X509_num(certs); i++) {
601 recip = sk_X509_value(certs, i); 601 recip = sk_X509_value(certs, i);
602 if (!CMS_add1_recipient_cert(cms, recip, flags)) { 602 if (!CMS_add1_recipient_cert(cms, recip, flags)) {
603 CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR); 603 CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR);
604 goto err; 604 goto err;
605 } 605 }
606 } 606 }
607 607
608 if (!(flags & CMS_DETACHED)) 608 if (!(flags & CMS_DETACHED))
609 CMS_set_detached(cms, 0); 609 CMS_set_detached(cms, 0);
610 610
611 if ((flags & (CMS_STREAM | CMS_PARTIAL)) 611 if ((flags & (CMS_STREAM | CMS_PARTIAL))
612 || CMS_final(cms, data, NULL, flags)) 612 || CMS_final(cms, data, NULL, flags))
613 return cms; 613 return cms;
614 else 614 else
615 goto err; 615 goto err;
616 616
617 merr: 617 merr:
618 CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE); 618 CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE);
619 err: 619 err:
620 CMS_ContentInfo_free(cms); 620 CMS_ContentInfo_free(cms);
621 return NULL; 621 return NULL;
622} 622}
623 623
624static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, 624static int cms_kari_set1_pkey(CMS_ContentInfo *cms, CMS_RecipientInfo *ri,
625 EVP_PKEY *pk, X509 *cert) 625 EVP_PKEY *pk, X509 *cert)
626{ 626{
627 int i; 627 int i;
628 STACK_OF(CMS_RecipientEncryptedKey) *reks; 628 STACK_OF(CMS_RecipientEncryptedKey) *reks;
629 CMS_RecipientEncryptedKey *rek; 629 CMS_RecipientEncryptedKey *rek;
630 reks = CMS_RecipientInfo_kari_get0_reks(ri); 630 reks = CMS_RecipientInfo_kari_get0_reks(ri);
631 for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { 631 for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) {
632 int rv; 632 int rv;
633 rek = sk_CMS_RecipientEncryptedKey_value(reks, i); 633 rek = sk_CMS_RecipientEncryptedKey_value(reks, i);
634 if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert)) 634 if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert))
635 continue; 635 continue;
636 CMS_RecipientInfo_kari_set0_pkey(ri, pk); 636 CMS_RecipientInfo_kari_set0_pkey(ri, pk);
637 rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek); 637 rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek);
638 CMS_RecipientInfo_kari_set0_pkey(ri, NULL); 638 CMS_RecipientInfo_kari_set0_pkey(ri, NULL);
639 if (rv > 0) 639 if (rv > 0)
640 return 1; 640 return 1;
641 return cert == NULL ? 0 : -1; 641 return cert == NULL ? 0 : -1;
642 } 642 }
643 return 0; 643 return 0;
644} 644}
645 645
646int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) 646int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert)
647{ 647{
648 STACK_OF(CMS_RecipientInfo) *ris; 648 STACK_OF(CMS_RecipientInfo) *ris;
649 CMS_RecipientInfo *ri; 649 CMS_RecipientInfo *ri;
650 int i, r, ri_type; 650 int i, r, ri_type;
651 int debug = 0, match_ri = 0; 651 int debug = 0, match_ri = 0;
652 ris = CMS_get0_RecipientInfos(cms); 652 ris = CMS_get0_RecipientInfos(cms);
653 if (ris) 653 if (ris)
654 debug = cms->d.envelopedData->encryptedContentInfo->debug; 654 debug = cms->d.envelopedData->encryptedContentInfo->debug;
655 ri_type = cms_pkey_get_ri_type(pk); 655 ri_type = cms_pkey_get_ri_type(pk);
656 if (ri_type == CMS_RECIPINFO_NONE) { 656 if (ri_type == CMS_RECIPINFO_NONE) {
657 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, 657 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY,
658 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); 658 CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
659 return 0; 659 return 0;
660 } 660 }
661 661
662 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { 662 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
663 ri = sk_CMS_RecipientInfo_value(ris, i); 663 ri = sk_CMS_RecipientInfo_value(ris, i);
664 if (CMS_RecipientInfo_type(ri) != ri_type) 664 if (CMS_RecipientInfo_type(ri) != ri_type)
665 continue; 665 continue;
666 match_ri = 1; 666 match_ri = 1;
667 if (ri_type == CMS_RECIPINFO_AGREE) { 667 if (ri_type == CMS_RECIPINFO_AGREE) {
668 r = cms_kari_set1_pkey(cms, ri, pk, cert); 668 r = cms_kari_set1_pkey(cms, ri, pk, cert);
669 if (r > 0) 669 if (r > 0)
670 return 1; 670 return 1;
671 if (r < 0) 671 if (r < 0)
672 return 0; 672 return 0;
673 } 673 }
674 /* 674 /*
675 * If we have a cert try matching RecipientInfo otherwise try them 675 * If we have a cert try matching RecipientInfo otherwise try them
676 * all. 676 * all.
677 */ 677 */
678 else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) { 678 else if (!cert || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
679 EVP_PKEY_up_ref(pk); 679 EVP_PKEY_up_ref(pk);
680 CMS_RecipientInfo_set0_pkey(ri, pk); 680 CMS_RecipientInfo_set0_pkey(ri, pk);
681 r = CMS_RecipientInfo_decrypt(cms, ri); 681 r = CMS_RecipientInfo_decrypt(cms, ri);
682 CMS_RecipientInfo_set0_pkey(ri, NULL); 682 CMS_RecipientInfo_set0_pkey(ri, NULL);
683 if (cert) { 683 if (cert) {
684 /* 684 /*
685 * If not debugging clear any error and return success to 685 * If not debugging clear any error and return success to
686 * avoid leaking of information useful to MMA 686 * avoid leaking of information useful to MMA
687 */ 687 */
688 if (!debug) { 688 if (!debug) {
689 ERR_clear_error(); 689 ERR_clear_error();
690 return 1; 690 return 1;
691 } 691 }
692 if (r > 0) 692 if (r > 0)
693 return 1; 693 return 1;
694 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR); 694 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR);
695 return 0; 695 return 0;
696 } 696 }
697 /* 697 /*
698 * If no cert and not debugging don't leave loop after first 698 * If no cert and not debugging don't leave loop after first
699 * successful decrypt. Always attempt to decrypt all recipients 699 * successful decrypt. Always attempt to decrypt all recipients
700 * to avoid leaking timing of a successful decrypt. 700 * to avoid leaking timing of a successful decrypt.
701 */ 701 */
702 else if (r > 0 && debug) 702 else if (r > 0 && debug)
703 return 1; 703 return 1;
704 } 704 }
705 } 705 }
706 /* If no cert, key transport and not debugging always return success */ 706 /* If no cert, key transport and not debugging always return success */
707 if (cert == NULL && ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) { 707 if (cert == NULL && ri_type == CMS_RECIPINFO_TRANS && match_ri && !debug) {
708 ERR_clear_error(); 708 ERR_clear_error();
709 return 1; 709 return 1;
710 } 710 }
711 711
712 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); 712 CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT);
713 return 0; 713 return 0;
714 714
715} 715}
716 716
717int CMS_decrypt_set1_key(CMS_ContentInfo *cms, 717int CMS_decrypt_set1_key(CMS_ContentInfo *cms,
718 unsigned char *key, size_t keylen, 718 unsigned char *key, size_t keylen,
719 const unsigned char *id, size_t idlen) 719 const unsigned char *id, size_t idlen)
720{ 720{
721 STACK_OF(CMS_RecipientInfo) *ris; 721 STACK_OF(CMS_RecipientInfo) *ris;
722 CMS_RecipientInfo *ri; 722 CMS_RecipientInfo *ri;
723 int i, r; 723 int i, r;
724 ris = CMS_get0_RecipientInfos(cms); 724 ris = CMS_get0_RecipientInfos(cms);
725 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { 725 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
726 ri = sk_CMS_RecipientInfo_value(ris, i); 726 ri = sk_CMS_RecipientInfo_value(ris, i);
727 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK) 727 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK)
728 continue; 728 continue;
729 729
730 /* 730 /*
731 * If we have an id try matching RecipientInfo otherwise try them 731 * If we have an id try matching RecipientInfo otherwise try them
732 * all. 732 * all.
733 */ 733 */
734 if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { 734 if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) {
735 CMS_RecipientInfo_set0_key(ri, key, keylen); 735 CMS_RecipientInfo_set0_key(ri, key, keylen);
736 r = CMS_RecipientInfo_decrypt(cms, ri); 736 r = CMS_RecipientInfo_decrypt(cms, ri);
737 CMS_RecipientInfo_set0_key(ri, NULL, 0); 737 CMS_RecipientInfo_set0_key(ri, NULL, 0);
738 if (r > 0) 738 if (r > 0)
739 return 1; 739 return 1;
740 if (id) { 740 if (id) {
741 CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR); 741 CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR);
742 return 0; 742 return 0;
743 } 743 }
744 ERR_clear_error(); 744 ERR_clear_error();
745 } 745 }
746 } 746 }
747 747
748 CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT); 748 CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT);
749 return 0; 749 return 0;
750 750
751} 751}
752 752
753int CMS_decrypt_set1_password(CMS_ContentInfo *cms, 753int CMS_decrypt_set1_password(CMS_ContentInfo *cms,
754 unsigned char *pass, ossl_ssize_t passlen) 754 unsigned char *pass, ossl_ssize_t passlen)
755{ 755{
756 STACK_OF(CMS_RecipientInfo) *ris; 756 STACK_OF(CMS_RecipientInfo) *ris;
757 CMS_RecipientInfo *ri; 757 CMS_RecipientInfo *ri;
758 int i, r; 758 int i, r;
759 ris = CMS_get0_RecipientInfos(cms); 759 ris = CMS_get0_RecipientInfos(cms);
760 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { 760 for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) {
761 ri = sk_CMS_RecipientInfo_value(ris, i); 761 ri = sk_CMS_RecipientInfo_value(ris, i);
762 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS) 762 if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS)
763 continue; 763 continue;
764 CMS_RecipientInfo_set0_password(ri, pass, passlen); 764 CMS_RecipientInfo_set0_password(ri, pass, passlen);
765 r = CMS_RecipientInfo_decrypt(cms, ri); 765 r = CMS_RecipientInfo_decrypt(cms, ri);
766 CMS_RecipientInfo_set0_password(ri, NULL, 0); 766 CMS_RecipientInfo_set0_password(ri, NULL, 0);
767 if (r > 0) 767 if (r > 0)
768 return 1; 768 return 1;
769 } 769 }
770 770
771 CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT); 771 CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT);
772 return 0; 772 return 0;
773 773
774} 774}
775 775
776int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, 776int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert,
777 BIO *dcont, BIO *out, unsigned int flags) 777 BIO *dcont, BIO *out, unsigned int flags)
778{ 778{
779 int r; 779 int r;
780 BIO *cont; 780 BIO *cont;
781 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) { 781 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) {
782 CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA); 782 CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA);
783 return 0; 783 return 0;
784 } 784 }
785 if (!dcont && !check_content(cms)) 785 if (!dcont && !check_content(cms))
786 return 0; 786 return 0;
787 if (flags & CMS_DEBUG_DECRYPT) 787 if (flags & CMS_DEBUG_DECRYPT)
788 cms->d.envelopedData->encryptedContentInfo->debug = 1; 788 cms->d.envelopedData->encryptedContentInfo->debug = 1;
789 else 789 else
790 cms->d.envelopedData->encryptedContentInfo->debug = 0; 790 cms->d.envelopedData->encryptedContentInfo->debug = 0;
791 if (!pk && !cert && !dcont && !out) 791 if (!pk && !cert && !dcont && !out)
792 return 1; 792 return 1;
793 if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) 793 if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert))
794 return 0; 794 return 0;
795 cont = CMS_dataInit(cms, dcont); 795 cont = CMS_dataInit(cms, dcont);
796 if (!cont) 796 if (!cont)
797 return 0; 797 return 0;
798 r = cms_copy_content(out, cont, flags); 798 r = cms_copy_content(out, cont, flags);
799 do_free_upto(cont, dcont); 799 do_free_upto(cont, dcont);
800 return r; 800 return r;
801} 801}
802 802
803int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) 803int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags)
804{ 804{
805 BIO *cmsbio; 805 BIO *cmsbio;
806 int ret = 0; 806 int ret = 0;
807 807
808 if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) { 808 if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) {
809 CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_LIB); 809 CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_LIB);
810 return 0; 810 return 0;
811 } 811 }
812 812
813 SMIME_crlf_copy(data, cmsbio, flags); 813 SMIME_crlf_copy(data, cmsbio, flags);
814 814
815 (void)BIO_flush(cmsbio); 815 (void)BIO_flush(cmsbio);
816 816
817 if (!CMS_dataFinal(cms, cmsbio)) { 817 if (!CMS_dataFinal(cms, cmsbio)) {
818 CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR); 818 CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR);
819 goto err; 819 goto err;
820 } 820 }
821 821
822 ret = 1; 822 ret = 1;
823 823
824 err: 824 err:
825 do_free_upto(cmsbio, dcont); 825 do_free_upto(cmsbio, dcont);
826 826
827 return ret; 827 return ret;
828 828
829} 829}
830 830
831#ifdef ZLIB 831#ifdef ZLIB
832 832
833int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, 833int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
834 unsigned int flags) 834 unsigned int flags)
835{ 835{
836 BIO *cont; 836 BIO *cont;
837 int r; 837 int r;
838 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) { 838 if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) {
839 CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA); 839 CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA);
840 return 0; 840 return 0;
841 } 841 }
842 842
843 if (!dcont && !check_content(cms)) 843 if (!dcont && !check_content(cms))
844 return 0; 844 return 0;
845 845
846 cont = CMS_dataInit(cms, dcont); 846 cont = CMS_dataInit(cms, dcont);
847 if (!cont) 847 if (!cont)
848 return 0; 848 return 0;
849 r = cms_copy_content(out, cont, flags); 849 r = cms_copy_content(out, cont, flags);
850 do_free_upto(cont, dcont); 850 do_free_upto(cont, dcont);
851 return r; 851 return r;
852} 852}
853 853
854CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) 854CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
855{ 855{
856 CMS_ContentInfo *cms; 856 CMS_ContentInfo *cms;
857 if (comp_nid <= 0) 857 if (comp_nid <= 0)
858 comp_nid = NID_zlib_compression; 858 comp_nid = NID_zlib_compression;
859 cms = cms_CompressedData_create(comp_nid); 859 cms = cms_CompressedData_create(comp_nid);
860 if (!cms) 860 if (!cms)
861 return NULL; 861 return NULL;
862 862
863 if (!(flags & CMS_DETACHED)) 863 if (!(flags & CMS_DETACHED))
864 CMS_set_detached(cms, 0); 864 CMS_set_detached(cms, 0);
865 865
866 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) 866 if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags))
867 return cms; 867 return cms;
868 868
869 CMS_ContentInfo_free(cms); 869 CMS_ContentInfo_free(cms);
870 return NULL; 870 return NULL;
871} 871}
872 872
873#else 873#else
874 874
875int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, 875int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out,
876 unsigned int flags) 876 unsigned int flags)
877{ 877{
878 CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 878 CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
879 return 0; 879 return 0;
880} 880}
881 881
882CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) 882CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags)
883{ 883{
884 CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); 884 CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
885 return NULL; 885 return NULL;
886} 886}
887 887
888#endif 888#endif