]>
Commit | Line | Data |
---|---|---|
0f113f3e | 1 | /* |
4333b89f | 2 | * Copyright 2008-2021 The OpenSSL Project Authors. All Rights Reserved. |
8931b30d | 3 | * |
08ddd302 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
b1322259 RS |
5 | * this file except in compliance with the License. You can obtain a copy |
6 | * in the file LICENSE in the source distribution or at | |
7 | * https://www.openssl.org/source/license.html | |
8931b30d DSH |
8 | */ |
9 | ||
b39fc560 | 10 | #include "internal/cryptlib.h" |
8931b30d DSH |
11 | #include <openssl/asn1t.h> |
12 | #include <openssl/x509.h> | |
13 | #include <openssl/x509v3.h> | |
14 | #include <openssl/err.h> | |
15 | #include <openssl/cms.h> | |
706457b7 | 16 | #include "cms_local.h" |
25f2138b | 17 | #include "crypto/asn1.h" |
8931b30d | 18 | |
cd30f03a | 19 | static BIO *cms_get_text_bio(BIO *out, unsigned int flags) |
0f113f3e MC |
20 | { |
21 | BIO *rbio; | |
c1669f41 | 22 | |
0f113f3e MC |
23 | if (out == NULL) |
24 | rbio = BIO_new(BIO_s_null()); | |
25 | else if (flags & CMS_TEXT) { | |
26 | rbio = BIO_new(BIO_s_mem()); | |
27 | BIO_set_mem_eof_return(rbio, 0); | |
28 | } else | |
29 | rbio = out; | |
30 | return rbio; | |
31 | } | |
cd30f03a DSH |
32 | |
33 | static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) | |
0f113f3e MC |
34 | { |
35 | unsigned char buf[4096]; | |
36 | int r = 0, i; | |
37 | BIO *tmpout; | |
38 | ||
39 | tmpout = cms_get_text_bio(out, flags); | |
40 | ||
90945fa3 | 41 | if (tmpout == NULL) { |
9311d0c4 | 42 | ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); |
0f113f3e MC |
43 | goto err; |
44 | } | |
45 | ||
46 | /* Read all content through chain to process digest, decrypt etc */ | |
47 | for (;;) { | |
48 | i = BIO_read(in, buf, sizeof(buf)); | |
49 | if (i <= 0) { | |
50 | if (BIO_method_type(in) == BIO_TYPE_CIPHER) { | |
51 | if (!BIO_get_cipher_status(in)) | |
52 | goto err; | |
53 | } | |
54 | if (i < 0) | |
55 | goto err; | |
56 | break; | |
57 | } | |
58 | ||
c1669f41 | 59 | if (tmpout != NULL && (BIO_write(tmpout, buf, i) != i)) |
0f113f3e MC |
60 | goto err; |
61 | } | |
62 | ||
63 | if (flags & CMS_TEXT) { | |
64 | if (!SMIME_text(tmpout, out)) { | |
9311d0c4 | 65 | ERR_raise(ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR); |
0f113f3e MC |
66 | goto err; |
67 | } | |
68 | } | |
69 | ||
70 | r = 1; | |
0f113f3e | 71 | err: |
ca3a82c3 | 72 | if (tmpout != out) |
0f113f3e MC |
73 | BIO_free(tmpout); |
74 | return r; | |
75 | ||
76 | } | |
8931b30d | 77 | |
4f1aa191 | 78 | static int check_content(CMS_ContentInfo *cms) |
0f113f3e MC |
79 | { |
80 | ASN1_OCTET_STRING **pos = CMS_get0_content(cms); | |
12a765a5 RS |
81 | |
82 | if (pos == NULL || *pos == NULL) { | |
9311d0c4 | 83 | ERR_raise(ERR_LIB_CMS, CMS_R_NO_CONTENT); |
0f113f3e MC |
84 | return 0; |
85 | } | |
86 | return 1; | |
87 | } | |
4f1aa191 | 88 | |
852bd350 | 89 | static void do_free_upto(BIO *f, BIO *upto) |
0f113f3e | 90 | { |
12a765a5 | 91 | if (upto != NULL) { |
0f113f3e | 92 | BIO *tbio; |
c1669f41 | 93 | |
0f113f3e MC |
94 | do { |
95 | tbio = BIO_pop(f); | |
96 | BIO_free(f); | |
97 | f = tbio; | |
12a765a5 | 98 | } while (f != NULL && f != upto); |
c1669f41 | 99 | } else { |
0f113f3e | 100 | BIO_free_all(f); |
c1669f41 | 101 | } |
0f113f3e | 102 | } |
852bd350 | 103 | |
8931b30d | 104 | int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) |
0f113f3e MC |
105 | { |
106 | BIO *cont; | |
107 | int r; | |
c1669f41 | 108 | |
0f113f3e | 109 | if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) { |
9311d0c4 | 110 | ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_DATA); |
0f113f3e MC |
111 | return 0; |
112 | } | |
113 | cont = CMS_dataInit(cms, NULL); | |
c1669f41 | 114 | if (cont == NULL) |
0f113f3e MC |
115 | return 0; |
116 | r = cms_copy_content(out, cont, flags); | |
117 | BIO_free_all(cont); | |
118 | return r; | |
119 | } | |
8931b30d | 120 | |
d8652be0 | 121 | CMS_ContentInfo *CMS_data_create_ex(BIO *in, unsigned int flags, |
b4250010 | 122 | OSSL_LIB_CTX *libctx, const char *propq) |
0f113f3e | 123 | { |
53155f1c | 124 | CMS_ContentInfo *cms = ossl_cms_Data_create(libctx, propq); |
c1669f41 SL |
125 | |
126 | if (cms == NULL) | |
0f113f3e | 127 | return NULL; |
8931b30d | 128 | |
0f113f3e MC |
129 | if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) |
130 | return cms; | |
8931b30d | 131 | |
0f113f3e | 132 | CMS_ContentInfo_free(cms); |
0f113f3e MC |
133 | return NULL; |
134 | } | |
8931b30d | 135 | |
c1669f41 SL |
136 | CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) |
137 | { | |
d8652be0 | 138 | return CMS_data_create_ex(in, flags, NULL, NULL); |
c1669f41 SL |
139 | } |
140 | ||
8931b30d | 141 | int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, |
0f113f3e MC |
142 | unsigned int flags) |
143 | { | |
144 | BIO *cont; | |
145 | int r; | |
c1669f41 | 146 | |
0f113f3e | 147 | if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) { |
9311d0c4 | 148 | ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_DIGESTED_DATA); |
0f113f3e MC |
149 | return 0; |
150 | } | |
151 | ||
c1669f41 | 152 | if (dcont == NULL && !check_content(cms)) |
0f113f3e MC |
153 | return 0; |
154 | ||
155 | cont = CMS_dataInit(cms, dcont); | |
c1669f41 | 156 | if (cont == NULL) |
0f113f3e | 157 | return 0; |
c1669f41 | 158 | |
0f113f3e MC |
159 | r = cms_copy_content(out, cont, flags); |
160 | if (r) | |
53155f1c | 161 | r = ossl_cms_DigestedData_do_final(cms, cont, 1); |
0f113f3e MC |
162 | do_free_upto(cont, dcont); |
163 | return r; | |
164 | } | |
8931b30d | 165 | |
d8652be0 | 166 | CMS_ContentInfo *CMS_digest_create_ex(BIO *in, const EVP_MD *md, |
b4250010 | 167 | unsigned int flags, OSSL_LIB_CTX *ctx, |
d8652be0 | 168 | const char *propq) |
0f113f3e MC |
169 | { |
170 | CMS_ContentInfo *cms; | |
c1669f41 SL |
171 | |
172 | if (md == NULL) | |
0f113f3e | 173 | md = EVP_sha1(); |
53155f1c | 174 | cms = ossl_cms_DigestedData_create(md, ctx, propq); |
c1669f41 | 175 | if (cms == NULL) |
0f113f3e | 176 | return NULL; |
8931b30d | 177 | |
0f113f3e MC |
178 | if (!(flags & CMS_DETACHED)) |
179 | CMS_set_detached(cms, 0); | |
8931b30d | 180 | |
0f113f3e MC |
181 | if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) |
182 | return cms; | |
8931b30d | 183 | |
0f113f3e MC |
184 | CMS_ContentInfo_free(cms); |
185 | return NULL; | |
186 | } | |
8931b30d | 187 | |
c1669f41 SL |
188 | CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, |
189 | unsigned int flags) | |
190 | { | |
d8652be0 | 191 | return CMS_digest_create_ex(in, md, flags, NULL, NULL); |
c1669f41 SL |
192 | } |
193 | ||
b820455c | 194 | int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, |
0f113f3e MC |
195 | const unsigned char *key, size_t keylen, |
196 | BIO *dcont, BIO *out, unsigned int flags) | |
197 | { | |
198 | BIO *cont; | |
199 | int r; | |
c1669f41 | 200 | |
0f113f3e | 201 | if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) { |
9311d0c4 | 202 | ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_ENCRYPTED_DATA); |
0f113f3e MC |
203 | return 0; |
204 | } | |
205 | ||
c1669f41 | 206 | if (dcont == NULL && !check_content(cms)) |
0f113f3e MC |
207 | return 0; |
208 | ||
209 | if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) | |
210 | return 0; | |
211 | cont = CMS_dataInit(cms, dcont); | |
c1669f41 | 212 | if (cont == NULL) |
0f113f3e MC |
213 | return 0; |
214 | r = cms_copy_content(out, cont, flags); | |
215 | do_free_upto(cont, dcont); | |
216 | return r; | |
217 | } | |
b820455c | 218 | |
d8652be0 MC |
219 | CMS_ContentInfo *CMS_EncryptedData_encrypt_ex(BIO *in, const EVP_CIPHER *cipher, |
220 | const unsigned char *key, | |
221 | size_t keylen, unsigned int flags, | |
b4250010 | 222 | OSSL_LIB_CTX *libctx, |
d8652be0 | 223 | const char *propq) |
0f113f3e MC |
224 | { |
225 | CMS_ContentInfo *cms; | |
c1669f41 SL |
226 | |
227 | if (cipher == NULL) { | |
9311d0c4 | 228 | ERR_raise(ERR_LIB_CMS, CMS_R_NO_CIPHER); |
0f113f3e MC |
229 | return NULL; |
230 | } | |
d8652be0 | 231 | cms = CMS_ContentInfo_new_ex(libctx, propq); |
90945fa3 | 232 | if (cms == NULL) |
0f113f3e MC |
233 | return NULL; |
234 | if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) | |
235 | return NULL; | |
236 | ||
237 | if (!(flags & CMS_DETACHED)) | |
238 | CMS_set_detached(cms, 0); | |
239 | ||
240 | if ((flags & (CMS_STREAM | CMS_PARTIAL)) | |
241 | || CMS_final(cms, in, NULL, flags)) | |
242 | return cms; | |
243 | ||
244 | CMS_ContentInfo_free(cms); | |
245 | return NULL; | |
246 | } | |
320bfc1b | 247 | |
c1669f41 SL |
248 | CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, |
249 | const unsigned char *key, | |
250 | size_t keylen, unsigned int flags) | |
251 | { | |
d8652be0 MC |
252 | return CMS_EncryptedData_encrypt_ex(in, cipher, key, keylen, flags, NULL, |
253 | NULL); | |
c1669f41 SL |
254 | } |
255 | ||
8931b30d | 256 | static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, |
0f113f3e MC |
257 | X509_STORE *store, |
258 | STACK_OF(X509) *certs, | |
9e3c510b | 259 | STACK_OF(X509_CRL) *crls, |
c1669f41 SL |
260 | STACK_OF(X509) **chain, |
261 | const CMS_CTX *cms_ctx) | |
0f113f3e | 262 | { |
c1669f41 | 263 | X509_STORE_CTX *ctx; |
0f113f3e MC |
264 | X509 *signer; |
265 | int i, j, r = 0; | |
f0e0fd51 | 266 | |
53155f1c SL |
267 | ctx = X509_STORE_CTX_new_ex(ossl_cms_ctx_get0_libctx(cms_ctx), |
268 | ossl_cms_ctx_get0_propq(cms_ctx)); | |
f0e0fd51 | 269 | if (ctx == NULL) { |
9311d0c4 | 270 | ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); |
f0e0fd51 RS |
271 | goto err; |
272 | } | |
0f113f3e | 273 | CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); |
f0e0fd51 | 274 | if (!X509_STORE_CTX_init(ctx, store, signer, certs)) { |
9311d0c4 | 275 | ERR_raise(ERR_LIB_CMS, CMS_R_STORE_INIT_ERROR); |
0f113f3e MC |
276 | goto err; |
277 | } | |
f0e0fd51 | 278 | X509_STORE_CTX_set_default(ctx, "smime_sign"); |
c1669f41 | 279 | if (crls != NULL) |
f0e0fd51 | 280 | X509_STORE_CTX_set0_crls(ctx, crls); |
0f113f3e | 281 | |
f0e0fd51 | 282 | i = X509_verify_cert(ctx); |
0f113f3e | 283 | if (i <= 0) { |
f0e0fd51 | 284 | j = X509_STORE_CTX_get_error(ctx); |
a150f8e1 RL |
285 | ERR_raise_data(ERR_LIB_CMS, CMS_R_CERTIFICATE_VERIFY_ERROR, |
286 | "Verify error: %s", X509_verify_cert_error_string(j)); | |
0f113f3e MC |
287 | goto err; |
288 | } | |
289 | r = 1; | |
9e3c510b F |
290 | |
291 | /* also send back the trust chain when required */ | |
292 | if (chain != NULL) | |
293 | *chain = X509_STORE_CTX_get1_chain(ctx); | |
0f113f3e | 294 | err: |
f0e0fd51 | 295 | X509_STORE_CTX_free(ctx); |
0f113f3e MC |
296 | return r; |
297 | ||
298 | } | |
8931b30d DSH |
299 | |
300 | int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, | |
0f113f3e MC |
301 | X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags) |
302 | { | |
303 | CMS_SignerInfo *si; | |
304 | STACK_OF(CMS_SignerInfo) *sinfos; | |
305 | STACK_OF(X509) *cms_certs = NULL; | |
306 | STACK_OF(X509_CRL) *crls = NULL; | |
9e3c510b | 307 | STACK_OF(X509) **si_chains = NULL; |
0f113f3e MC |
308 | X509 *signer; |
309 | int i, scount = 0, ret = 0; | |
310 | BIO *cmsbio = NULL, *tmpin = NULL, *tmpout = NULL; | |
9e3c510b | 311 | int cadesVerify = (flags & CMS_CADES) != 0; |
53155f1c | 312 | const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms); |
0f113f3e | 313 | |
c1669f41 | 314 | if (dcont == NULL && !check_content(cms)) |
0f113f3e | 315 | return 0; |
c1669f41 | 316 | if (dcont != NULL && !(flags & CMS_BINARY)) { |
0f113f3e | 317 | const ASN1_OBJECT *coid = CMS_get0_eContentType(cms); |
c1669f41 | 318 | |
0f113f3e MC |
319 | if (OBJ_obj2nid(coid) == NID_id_ct_asciiTextWithCRLF) |
320 | flags |= CMS_ASCIICRLF; | |
321 | } | |
322 | ||
323 | /* Attempt to find all signer certificates */ | |
324 | ||
325 | sinfos = CMS_get0_SignerInfos(cms); | |
326 | ||
327 | if (sk_CMS_SignerInfo_num(sinfos) <= 0) { | |
9311d0c4 | 328 | ERR_raise(ERR_LIB_CMS, CMS_R_NO_SIGNERS); |
0f113f3e MC |
329 | goto err; |
330 | } | |
331 | ||
332 | for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { | |
333 | si = sk_CMS_SignerInfo_value(sinfos, i); | |
334 | CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); | |
335 | if (signer) | |
336 | scount++; | |
337 | } | |
338 | ||
339 | if (scount != sk_CMS_SignerInfo_num(sinfos)) | |
340 | scount += CMS_set1_signers_certs(cms, certs, flags); | |
341 | ||
342 | if (scount != sk_CMS_SignerInfo_num(sinfos)) { | |
9311d0c4 | 343 | ERR_raise(ERR_LIB_CMS, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); |
0f113f3e MC |
344 | goto err; |
345 | } | |
346 | ||
347 | /* Attempt to verify all signers certs */ | |
9e3c510b F |
348 | /* at this point scount == sk_CMS_SignerInfo_num(sinfos) */ |
349 | ||
350 | if ((flags & CMS_NO_SIGNER_CERT_VERIFY) == 0 || cadesVerify) { | |
351 | if (cadesVerify) { | |
352 | /* Certificate trust chain is required to check CAdES signature */ | |
353 | si_chains = OPENSSL_zalloc(scount * sizeof(si_chains[0])); | |
354 | if (si_chains == NULL) { | |
9311d0c4 | 355 | ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); |
9e3c510b F |
356 | goto err; |
357 | } | |
358 | } | |
0f113f3e MC |
359 | cms_certs = CMS_get1_certs(cms); |
360 | if (!(flags & CMS_NOCRL)) | |
361 | crls = CMS_get1_crls(cms); | |
9e3c510b | 362 | for (i = 0; i < scount; i++) { |
0f113f3e | 363 | si = sk_CMS_SignerInfo_value(sinfos, i); |
9e3c510b F |
364 | |
365 | if (!cms_signerinfo_verify_cert(si, store, cms_certs, crls, | |
c1669f41 SL |
366 | si_chains ? &si_chains[i] : NULL, |
367 | ctx)) | |
0f113f3e MC |
368 | goto err; |
369 | } | |
370 | } | |
371 | ||
372 | /* Attempt to verify all SignerInfo signed attribute signatures */ | |
373 | ||
9e3c510b F |
374 | if ((flags & CMS_NO_ATTR_VERIFY) == 0 || cadesVerify) { |
375 | for (i = 0; i < scount; i++) { | |
0f113f3e MC |
376 | si = sk_CMS_SignerInfo_value(sinfos, i); |
377 | if (CMS_signed_get_attr_count(si) < 0) | |
378 | continue; | |
379 | if (CMS_SignerInfo_verify(si) <= 0) | |
380 | goto err; | |
9e3c510b F |
381 | if (cadesVerify) { |
382 | STACK_OF(X509) *si_chain = si_chains ? si_chains[i] : NULL; | |
383 | ||
63b64f19 | 384 | if (ossl_cms_check_signing_certs(si, si_chain) <= 0) |
9e3c510b F |
385 | goto err; |
386 | } | |
0f113f3e MC |
387 | } |
388 | } | |
389 | ||
390 | /* | |
391 | * Performance optimization: if the content is a memory BIO then store | |
392 | * its contents in a temporary read only memory BIO. This avoids | |
393 | * potentially large numbers of slow copies of data which will occur when | |
394 | * reading from a read write memory BIO when signatures are calculated. | |
395 | */ | |
396 | ||
c1669f41 | 397 | if (dcont != NULL && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { |
0f113f3e MC |
398 | char *ptr; |
399 | long len; | |
c1669f41 | 400 | |
0f113f3e | 401 | len = BIO_get_mem_data(dcont, &ptr); |
13c5ec56 | 402 | tmpin = (len == 0) ? dcont : BIO_new_mem_buf(ptr, len); |
0f113f3e | 403 | if (tmpin == NULL) { |
9311d0c4 | 404 | ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); |
7fba8407 | 405 | goto err2; |
0f113f3e | 406 | } |
c1669f41 | 407 | } else { |
0f113f3e | 408 | tmpin = dcont; |
c1669f41 | 409 | } |
0f113f3e MC |
410 | /* |
411 | * If not binary mode and detached generate digests by *writing* through | |
412 | * the BIO. That makes it possible to canonicalise the input. | |
413 | */ | |
414 | if (!(flags & SMIME_BINARY) && dcont) { | |
415 | /* | |
416 | * Create output BIO so we can either handle text or to ensure | |
417 | * included content doesn't override detached content. | |
418 | */ | |
419 | tmpout = cms_get_text_bio(out, flags); | |
c1669f41 | 420 | if (tmpout == NULL) { |
9311d0c4 | 421 | ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); |
0f113f3e MC |
422 | goto err; |
423 | } | |
424 | cmsbio = CMS_dataInit(cms, tmpout); | |
c1669f41 | 425 | if (cmsbio == NULL) |
0f113f3e MC |
426 | goto err; |
427 | /* | |
428 | * Don't use SMIME_TEXT for verify: it adds headers and we want to | |
429 | * remove them. | |
430 | */ | |
431 | SMIME_crlf_copy(dcont, cmsbio, flags & ~SMIME_TEXT); | |
432 | ||
433 | if (flags & CMS_TEXT) { | |
434 | if (!SMIME_text(tmpout, out)) { | |
9311d0c4 | 435 | ERR_raise(ERR_LIB_CMS, CMS_R_SMIME_TEXT_ERROR); |
0f113f3e MC |
436 | goto err; |
437 | } | |
438 | } | |
439 | } else { | |
440 | cmsbio = CMS_dataInit(cms, tmpin); | |
c1669f41 | 441 | if (cmsbio == NULL) |
0f113f3e MC |
442 | goto err; |
443 | ||
444 | if (!cms_copy_content(out, cmsbio, flags)) | |
445 | goto err; | |
446 | ||
447 | } | |
448 | if (!(flags & CMS_NO_CONTENT_VERIFY)) { | |
449 | for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { | |
450 | si = sk_CMS_SignerInfo_value(sinfos, i); | |
451 | if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) { | |
9311d0c4 | 452 | ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_VERIFY_ERROR); |
0f113f3e MC |
453 | goto err; |
454 | } | |
455 | } | |
456 | } | |
457 | ||
458 | ret = 1; | |
0f113f3e MC |
459 | err: |
460 | if (!(flags & SMIME_BINARY) && dcont) { | |
461 | do_free_upto(cmsbio, tmpout); | |
462 | if (tmpin != dcont) | |
463 | BIO_free(tmpin); | |
464 | } else { | |
0f113f3e MC |
465 | if (dcont && (tmpin == dcont)) |
466 | do_free_upto(cmsbio, dcont); | |
467 | else | |
468 | BIO_free_all(cmsbio); | |
469 | } | |
470 | ||
ca3a82c3 | 471 | if (out != tmpout) |
0f113f3e MC |
472 | BIO_free_all(tmpout); |
473 | ||
7fba8407 | 474 | err2: |
9e3c510b F |
475 | if (si_chains != NULL) { |
476 | for (i = 0; i < scount; ++i) | |
477 | sk_X509_pop_free(si_chains[i], X509_free); | |
478 | OPENSSL_free(si_chains); | |
479 | } | |
222561fe RS |
480 | sk_X509_pop_free(cms_certs, X509_free); |
481 | sk_X509_CRL_pop_free(crls, X509_CRL_free); | |
0f113f3e MC |
482 | |
483 | return ret; | |
484 | } | |
8931b30d | 485 | |
eb9d8d8c | 486 | int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, |
0f113f3e MC |
487 | STACK_OF(X509) *certs, |
488 | X509_STORE *store, unsigned int flags) | |
489 | { | |
490 | int r; | |
c1669f41 | 491 | |
0f113f3e MC |
492 | flags &= ~(CMS_DETACHED | CMS_TEXT); |
493 | r = CMS_verify(rcms, certs, store, NULL, NULL, flags); | |
494 | if (r <= 0) | |
495 | return r; | |
53155f1c | 496 | return ossl_cms_Receipt_verify(rcms, ocms); |
0f113f3e MC |
497 | } |
498 | ||
d8652be0 MC |
499 | CMS_ContentInfo *CMS_sign_ex(X509 *signcert, EVP_PKEY *pkey, |
500 | STACK_OF(X509) *certs, BIO *data, | |
b4250010 | 501 | unsigned int flags, OSSL_LIB_CTX *libctx, |
d8652be0 | 502 | const char *propq) |
0f113f3e MC |
503 | { |
504 | CMS_ContentInfo *cms; | |
505 | int i; | |
506 | ||
d8652be0 | 507 | cms = CMS_ContentInfo_new_ex(libctx, propq); |
90945fa3 | 508 | if (cms == NULL || !CMS_SignedData_init(cms)) |
0f113f3e MC |
509 | goto merr; |
510 | if (flags & CMS_ASCIICRLF | |
511 | && !CMS_set1_eContentType(cms, | |
512 | OBJ_nid2obj(NID_id_ct_asciiTextWithCRLF))) | |
513 | goto err; | |
514 | ||
c1669f41 | 515 | if (pkey != NULL && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { |
9311d0c4 | 516 | ERR_raise(ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR); |
0f113f3e MC |
517 | goto err; |
518 | } | |
519 | ||
520 | for (i = 0; i < sk_X509_num(certs); i++) { | |
521 | X509 *x = sk_X509_value(certs, i); | |
c1669f41 | 522 | |
0f113f3e MC |
523 | if (!CMS_add1_cert(cms, x)) |
524 | goto merr; | |
525 | } | |
526 | ||
527 | if (!(flags & CMS_DETACHED)) | |
528 | CMS_set_detached(cms, 0); | |
529 | ||
530 | if ((flags & (CMS_STREAM | CMS_PARTIAL)) | |
531 | || CMS_final(cms, data, NULL, flags)) | |
532 | return cms; | |
533 | else | |
534 | goto err; | |
535 | ||
536 | merr: | |
9311d0c4 | 537 | ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); |
0f113f3e MC |
538 | |
539 | err: | |
25aaa98a | 540 | CMS_ContentInfo_free(cms); |
0f113f3e MC |
541 | return NULL; |
542 | } | |
8931b30d | 543 | |
c1669f41 SL |
544 | CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, |
545 | BIO *data, unsigned int flags) | |
546 | { | |
d8652be0 | 547 | return CMS_sign_ex(signcert, pkey, certs, data, flags, NULL, NULL); |
c1669f41 SL |
548 | } |
549 | ||
36309aa2 | 550 | CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, |
0f113f3e MC |
551 | X509 *signcert, EVP_PKEY *pkey, |
552 | STACK_OF(X509) *certs, unsigned int flags) | |
553 | { | |
554 | CMS_SignerInfo *rct_si; | |
555 | CMS_ContentInfo *cms = NULL; | |
556 | ASN1_OCTET_STRING **pos, *os; | |
557 | BIO *rct_cont = NULL; | |
558 | int r = 0; | |
c1669f41 | 559 | const CMS_CTX *ctx = si->cms_ctx; |
0f113f3e MC |
560 | |
561 | flags &= ~(CMS_STREAM | CMS_TEXT); | |
562 | /* Not really detached but avoids content being allocated */ | |
563 | flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED; | |
12a765a5 | 564 | if (pkey == NULL || signcert == NULL) { |
9311d0c4 | 565 | ERR_raise(ERR_LIB_CMS, CMS_R_NO_KEY_OR_CERT); |
0f113f3e MC |
566 | return NULL; |
567 | } | |
568 | ||
569 | /* Initialize signed data */ | |
570 | ||
53155f1c SL |
571 | cms = CMS_sign_ex(NULL, NULL, certs, NULL, flags, |
572 | ossl_cms_ctx_get0_libctx(ctx), | |
573 | ossl_cms_ctx_get0_propq(ctx)); | |
c1669f41 | 574 | if (cms == NULL) |
0f113f3e MC |
575 | goto err; |
576 | ||
577 | /* Set inner content type to signed receipt */ | |
578 | if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt))) | |
579 | goto err; | |
580 | ||
581 | rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); | |
582 | if (!rct_si) { | |
9311d0c4 | 583 | ERR_raise(ERR_LIB_CMS, CMS_R_ADD_SIGNER_ERROR); |
0f113f3e MC |
584 | goto err; |
585 | } | |
586 | ||
53155f1c | 587 | os = ossl_cms_encode_Receipt(si); |
c1669f41 | 588 | if (os == NULL) |
0f113f3e MC |
589 | goto err; |
590 | ||
591 | /* Set content to digest */ | |
592 | rct_cont = BIO_new_mem_buf(os->data, os->length); | |
c1669f41 | 593 | if (rct_cont == NULL) |
0f113f3e MC |
594 | goto err; |
595 | ||
596 | /* Add msgSigDigest attribute */ | |
597 | ||
53155f1c | 598 | if (!ossl_cms_msgSigDigest_add1(rct_si, si)) |
0f113f3e MC |
599 | goto err; |
600 | ||
601 | /* Finalize structure */ | |
602 | if (!CMS_final(cms, rct_cont, NULL, flags)) | |
603 | goto err; | |
604 | ||
605 | /* Set embedded content */ | |
606 | pos = CMS_get0_content(cms); | |
607 | *pos = os; | |
608 | ||
609 | r = 1; | |
610 | ||
611 | err: | |
ca3a82c3 | 612 | BIO_free(rct_cont); |
0f113f3e MC |
613 | if (r) |
614 | return cms; | |
615 | CMS_ContentInfo_free(cms); | |
616 | return NULL; | |
617 | ||
618 | } | |
36309aa2 | 619 | |
d8652be0 MC |
620 | CMS_ContentInfo *CMS_encrypt_ex(STACK_OF(X509) *certs, BIO *data, |
621 | const EVP_CIPHER *cipher, unsigned int flags, | |
b4250010 | 622 | OSSL_LIB_CTX *libctx, const char *propq) |
0f113f3e MC |
623 | { |
624 | CMS_ContentInfo *cms; | |
625 | int i; | |
626 | X509 *recip; | |
c1669f41 | 627 | |
924663c3 JZ |
628 | |
629 | cms = (EVP_CIPHER_flags(cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) | |
d8652be0 MC |
630 | ? CMS_AuthEnvelopedData_create_ex(cipher, libctx, propq) |
631 | : CMS_EnvelopedData_create_ex(cipher, libctx, propq); | |
c1669f41 | 632 | if (cms == NULL) |
0f113f3e MC |
633 | goto merr; |
634 | for (i = 0; i < sk_X509_num(certs); i++) { | |
635 | recip = sk_X509_value(certs, i); | |
636 | if (!CMS_add1_recipient_cert(cms, recip, flags)) { | |
9311d0c4 | 637 | ERR_raise(ERR_LIB_CMS, CMS_R_RECIPIENT_ERROR); |
0f113f3e MC |
638 | goto err; |
639 | } | |
640 | } | |
641 | ||
642 | if (!(flags & CMS_DETACHED)) | |
643 | CMS_set_detached(cms, 0); | |
644 | ||
645 | if ((flags & (CMS_STREAM | CMS_PARTIAL)) | |
646 | || CMS_final(cms, data, NULL, flags)) | |
647 | return cms; | |
648 | else | |
649 | goto err; | |
650 | ||
651 | merr: | |
9311d0c4 | 652 | ERR_raise(ERR_LIB_CMS, ERR_R_MALLOC_FAILURE); |
0f113f3e | 653 | err: |
25aaa98a | 654 | CMS_ContentInfo_free(cms); |
0f113f3e MC |
655 | return NULL; |
656 | } | |
eeb9cdfc | 657 | |
c1669f41 SL |
658 | CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, |
659 | const EVP_CIPHER *cipher, unsigned int flags) | |
660 | { | |
d8652be0 | 661 | return CMS_encrypt_ex(certs, data, cipher, flags, NULL, NULL); |
c1669f41 SL |
662 | } |
663 | ||
664 | static int cms_kari_set1_pkey_and_peer(CMS_ContentInfo *cms, | |
665 | CMS_RecipientInfo *ri, | |
71434aed | 666 | EVP_PKEY *pk, X509 *cert, X509 *peer) |
0f113f3e MC |
667 | { |
668 | int i; | |
669 | STACK_OF(CMS_RecipientEncryptedKey) *reks; | |
670 | CMS_RecipientEncryptedKey *rek; | |
71434aed | 671 | |
0f113f3e | 672 | reks = CMS_RecipientInfo_kari_get0_reks(ri); |
0f113f3e MC |
673 | for (i = 0; i < sk_CMS_RecipientEncryptedKey_num(reks); i++) { |
674 | int rv; | |
c1669f41 | 675 | |
0f113f3e | 676 | rek = sk_CMS_RecipientEncryptedKey_value(reks, i); |
3f1d1704 | 677 | if (cert != NULL && CMS_RecipientEncryptedKey_cert_cmp(rek, cert)) |
0f113f3e | 678 | continue; |
71434aed | 679 | CMS_RecipientInfo_kari_set0_pkey_and_peer(ri, pk, peer); |
0f113f3e MC |
680 | rv = CMS_RecipientInfo_kari_decrypt(cms, ri, rek); |
681 | CMS_RecipientInfo_kari_set0_pkey(ri, NULL); | |
682 | if (rv > 0) | |
683 | return 1; | |
3f1d1704 | 684 | return cert == NULL ? 0 : -1; |
0f113f3e MC |
685 | } |
686 | return 0; | |
687 | } | |
17c2764d | 688 | |
eeb9cdfc | 689 | int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) |
71434aed DB |
690 | { |
691 | return CMS_decrypt_set1_pkey_and_peer(cms, pk, cert, NULL); | |
692 | } | |
693 | ||
c1669f41 SL |
694 | int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk, |
695 | X509 *cert, X509 *peer) | |
0f113f3e MC |
696 | { |
697 | STACK_OF(CMS_RecipientInfo) *ris; | |
698 | CMS_RecipientInfo *ri; | |
71434aed | 699 | int i, r, cms_pkey_ri_type; |
0f113f3e | 700 | int debug = 0, match_ri = 0; |
c1669f41 | 701 | |
0f113f3e | 702 | ris = CMS_get0_RecipientInfos(cms); |
c1669f41 | 703 | if (ris != NULL) |
53155f1c | 704 | debug = ossl_cms_get0_env_enc_content(cms)->debug; |
71434aed | 705 | |
53155f1c | 706 | cms_pkey_ri_type = ossl_cms_pkey_get_ri_type(pk); |
71434aed | 707 | if (cms_pkey_ri_type == CMS_RECIPINFO_NONE) { |
9311d0c4 | 708 | ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); |
71434aed | 709 | return 0; |
0f113f3e MC |
710 | } |
711 | ||
712 | for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { | |
71434aed DB |
713 | int ri_type; |
714 | ||
0f113f3e | 715 | ri = sk_CMS_RecipientInfo_value(ris, i); |
71434aed | 716 | ri_type = CMS_RecipientInfo_type(ri); |
53155f1c | 717 | if (!ossl_cms_pkey_is_ri_type_supported(pk, ri_type)) |
0f113f3e MC |
718 | continue; |
719 | match_ri = 1; | |
720 | if (ri_type == CMS_RECIPINFO_AGREE) { | |
71434aed | 721 | r = cms_kari_set1_pkey_and_peer(cms, ri, pk, cert, peer); |
0f113f3e MC |
722 | if (r > 0) |
723 | return 1; | |
724 | if (r < 0) | |
725 | return 0; | |
726 | } | |
727 | /* | |
728 | * If we have a cert try matching RecipientInfo otherwise try them | |
729 | * all. | |
730 | */ | |
c1669f41 | 731 | else if (cert == NULL|| !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) { |
3d551b20 | 732 | EVP_PKEY_up_ref(pk); |
0f113f3e MC |
733 | CMS_RecipientInfo_set0_pkey(ri, pk); |
734 | r = CMS_RecipientInfo_decrypt(cms, ri); | |
735 | CMS_RecipientInfo_set0_pkey(ri, NULL); | |
c1669f41 | 736 | if (cert != NULL) { |
0f113f3e MC |
737 | /* |
738 | * If not debugging clear any error and return success to | |
739 | * avoid leaking of information useful to MMA | |
740 | */ | |
741 | if (!debug) { | |
742 | ERR_clear_error(); | |
743 | return 1; | |
744 | } | |
745 | if (r > 0) | |
746 | return 1; | |
9311d0c4 | 747 | ERR_raise(ERR_LIB_CMS, CMS_R_DECRYPT_ERROR); |
0f113f3e MC |
748 | return 0; |
749 | } | |
750 | /* | |
751 | * If no cert and not debugging don't leave loop after first | |
752 | * successful decrypt. Always attempt to decrypt all recipients | |
753 | * to avoid leaking timing of a successful decrypt. | |
754 | */ | |
71434aed | 755 | else if (r > 0 && (debug || cms_pkey_ri_type != CMS_RECIPINFO_TRANS)) |
0f113f3e MC |
756 | return 1; |
757 | } | |
758 | } | |
3f1d1704 | 759 | /* If no cert, key transport and not debugging always return success */ |
c1669f41 SL |
760 | if (cert == NULL |
761 | && cms_pkey_ri_type == CMS_RECIPINFO_TRANS | |
762 | && match_ri | |
763 | && !debug) { | |
0f113f3e MC |
764 | ERR_clear_error(); |
765 | return 1; | |
766 | } | |
767 | ||
9311d0c4 | 768 | ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT); |
0f113f3e MC |
769 | return 0; |
770 | ||
771 | } | |
772 | ||
773 | int CMS_decrypt_set1_key(CMS_ContentInfo *cms, | |
774 | unsigned char *key, size_t keylen, | |
c17dd597 | 775 | const unsigned char *id, size_t idlen) |
0f113f3e MC |
776 | { |
777 | STACK_OF(CMS_RecipientInfo) *ris; | |
778 | CMS_RecipientInfo *ri; | |
779 | int i, r; | |
c1669f41 | 780 | |
0f113f3e MC |
781 | ris = CMS_get0_RecipientInfos(cms); |
782 | for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { | |
783 | ri = sk_CMS_RecipientInfo_value(ris, i); | |
784 | if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK) | |
785 | continue; | |
786 | ||
787 | /* | |
788 | * If we have an id try matching RecipientInfo otherwise try them | |
789 | * all. | |
790 | */ | |
c1669f41 | 791 | if (id == NULL || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { |
0f113f3e MC |
792 | CMS_RecipientInfo_set0_key(ri, key, keylen); |
793 | r = CMS_RecipientInfo_decrypt(cms, ri); | |
794 | CMS_RecipientInfo_set0_key(ri, NULL, 0); | |
795 | if (r > 0) | |
796 | return 1; | |
c1669f41 | 797 | if (id != NULL) { |
9311d0c4 | 798 | ERR_raise(ERR_LIB_CMS, CMS_R_DECRYPT_ERROR); |
0f113f3e MC |
799 | return 0; |
800 | } | |
801 | ERR_clear_error(); | |
802 | } | |
803 | } | |
804 | ||
9311d0c4 | 805 | ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT); |
0f113f3e MC |
806 | return 0; |
807 | ||
808 | } | |
809 | ||
810 | int CMS_decrypt_set1_password(CMS_ContentInfo *cms, | |
811 | unsigned char *pass, ossl_ssize_t passlen) | |
812 | { | |
813 | STACK_OF(CMS_RecipientInfo) *ris; | |
814 | CMS_RecipientInfo *ri; | |
815 | int i, r; | |
c1669f41 | 816 | |
0f113f3e MC |
817 | ris = CMS_get0_RecipientInfos(cms); |
818 | for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { | |
819 | ri = sk_CMS_RecipientInfo_value(ris, i); | |
820 | if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS) | |
821 | continue; | |
822 | CMS_RecipientInfo_set0_password(ri, pass, passlen); | |
823 | r = CMS_RecipientInfo_decrypt(cms, ri); | |
824 | CMS_RecipientInfo_set0_password(ri, NULL, 0); | |
825 | if (r > 0) | |
826 | return 1; | |
827 | } | |
828 | ||
9311d0c4 | 829 | ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_RECIPIENT); |
0f113f3e MC |
830 | return 0; |
831 | ||
832 | } | |
833 | ||
4f1aa191 | 834 | int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, |
0f113f3e MC |
835 | BIO *dcont, BIO *out, unsigned int flags) |
836 | { | |
837 | int r; | |
838 | BIO *cont; | |
12a765a5 | 839 | |
924663c3 JZ |
840 | int nid = OBJ_obj2nid(CMS_get0_type(cms)); |
841 | ||
842 | if (nid != NID_pkcs7_enveloped | |
843 | && nid != NID_id_smime_ct_authEnvelopedData) { | |
9311d0c4 | 844 | ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_ENVELOPED_DATA); |
0f113f3e MC |
845 | return 0; |
846 | } | |
c1669f41 | 847 | if (dcont == NULL && !check_content(cms)) |
0f113f3e MC |
848 | return 0; |
849 | if (flags & CMS_DEBUG_DECRYPT) | |
53155f1c | 850 | ossl_cms_get0_env_enc_content(cms)->debug = 1; |
0f113f3e | 851 | else |
53155f1c | 852 | ossl_cms_get0_env_enc_content(cms)->debug = 0; |
c1669f41 | 853 | if (cert == NULL) |
53155f1c | 854 | ossl_cms_get0_env_enc_content(cms)->havenocert = 1; |
5840ed0c | 855 | else |
53155f1c | 856 | ossl_cms_get0_env_enc_content(cms)->havenocert = 0; |
12a765a5 | 857 | if (pk == NULL && cert == NULL && dcont == NULL && out == NULL) |
0f113f3e | 858 | return 1; |
12a765a5 | 859 | if (pk != NULL && !CMS_decrypt_set1_pkey(cms, pk, cert)) |
0f113f3e MC |
860 | return 0; |
861 | cont = CMS_dataInit(cms, dcont); | |
12a765a5 | 862 | if (cont == NULL) |
0f113f3e MC |
863 | return 0; |
864 | r = cms_copy_content(out, cont, flags); | |
865 | do_free_upto(cont, dcont); | |
866 | return r; | |
867 | } | |
8931b30d | 868 | |
e0fbd073 | 869 | int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) |
0f113f3e MC |
870 | { |
871 | BIO *cmsbio; | |
872 | int ret = 0; | |
75ebbd9a RS |
873 | |
874 | if ((cmsbio = CMS_dataInit(cms, dcont)) == NULL) { | |
9311d0c4 | 875 | ERR_raise(ERR_LIB_CMS, CMS_R_CMS_LIB); |
0f113f3e MC |
876 | return 0; |
877 | } | |
8931b30d | 878 | |
c1669f41 | 879 | ret = SMIME_crlf_copy(data, cmsbio, flags); |
8931b30d | 880 | |
0f113f3e | 881 | (void)BIO_flush(cmsbio); |
8931b30d | 882 | |
0f113f3e | 883 | if (!CMS_dataFinal(cms, cmsbio)) { |
9311d0c4 | 884 | ERR_raise(ERR_LIB_CMS, CMS_R_CMS_DATAFINAL_ERROR); |
0f113f3e MC |
885 | goto err; |
886 | } | |
c1669f41 | 887 | err: |
0f113f3e | 888 | do_free_upto(cmsbio, dcont); |
8931b30d | 889 | |
0f113f3e | 890 | return ret; |
8931b30d | 891 | |
0f113f3e | 892 | } |
8931b30d DSH |
893 | |
894 | #ifdef ZLIB | |
895 | ||
a5db50d0 | 896 | int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, |
0f113f3e MC |
897 | unsigned int flags) |
898 | { | |
899 | BIO *cont; | |
900 | int r; | |
c1669f41 | 901 | |
0f113f3e | 902 | if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) { |
9311d0c4 | 903 | ERR_raise(ERR_LIB_CMS, CMS_R_TYPE_NOT_COMPRESSED_DATA); |
0f113f3e MC |
904 | return 0; |
905 | } | |
906 | ||
c1669f41 | 907 | if (dcont == NULL && !check_content(cms)) |
0f113f3e MC |
908 | return 0; |
909 | ||
910 | cont = CMS_dataInit(cms, dcont); | |
c1669f41 | 911 | if (cont == NULL) |
0f113f3e MC |
912 | return 0; |
913 | r = cms_copy_content(out, cont, flags); | |
914 | do_free_upto(cont, dcont); | |
915 | return r; | |
916 | } | |
8931b30d DSH |
917 | |
918 | CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) | |
0f113f3e MC |
919 | { |
920 | CMS_ContentInfo *cms; | |
c1669f41 | 921 | |
0f113f3e MC |
922 | if (comp_nid <= 0) |
923 | comp_nid = NID_zlib_compression; | |
53155f1c | 924 | cms = ossl_cms_CompressedData_create(comp_nid, NULL, NULL); |
c1669f41 | 925 | if (cms == NULL) |
0f113f3e | 926 | return NULL; |
8931b30d | 927 | |
0f113f3e MC |
928 | if (!(flags & CMS_DETACHED)) |
929 | CMS_set_detached(cms, 0); | |
8931b30d | 930 | |
0f113f3e MC |
931 | if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) |
932 | return cms; | |
8931b30d | 933 | |
0f113f3e MC |
934 | CMS_ContentInfo_free(cms); |
935 | return NULL; | |
936 | } | |
8931b30d DSH |
937 | |
938 | #else | |
939 | ||
940 | int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, | |
0f113f3e MC |
941 | unsigned int flags) |
942 | { | |
9311d0c4 | 943 | ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); |
0f113f3e MC |
944 | return 0; |
945 | } | |
8931b30d DSH |
946 | |
947 | CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) | |
0f113f3e | 948 | { |
9311d0c4 | 949 | ERR_raise(ERR_LIB_CMS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); |
0f113f3e MC |
950 | return NULL; |
951 | } | |
8931b30d DSH |
952 | |
953 | #endif |