]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/pkcs7/pk7_doit.c
Update to SHA256 for TSA signing digest.
[thirdparty/openssl.git] / crypto / pkcs7 / pk7_doit.c
CommitLineData
d02b48c6 1/* crypto/pkcs7/pk7_doit.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
0f113f3e 8 *
d02b48c6
RE
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
0f113f3e 15 *
d02b48c6
RE
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
0f113f3e 22 *
d02b48c6
RE
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
0f113f3e 37 * 4. If you include any Windows specific code (or a derivative thereof) from
d02b48c6
RE
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
0f113f3e 40 *
d02b48c6
RE
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
0f113f3e 52 *
d02b48c6
RE
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
58
59#include <stdio.h>
b39fc560 60#include "internal/cryptlib.h"
ec577822
BM
61#include <openssl/rand.h>
62#include <openssl/objects.h>
63#include <openssl/x509.h>
5a9a4b29 64#include <openssl/x509v3.h>
8f2e4fdf 65#include <openssl/err.h>
d02b48c6 66
b6436ff2 67static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
0f113f3e 68 void *value);
b6436ff2 69static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
dfeab068 70
0f113f3e
MC
71static int PKCS7_type_is_other(PKCS7 *p7)
72{
73 int isOther = 1;
74
75 int nid = OBJ_obj2nid(p7->type);
76
77 switch (nid) {
78 case NID_pkcs7_data:
79 case NID_pkcs7_signed:
80 case NID_pkcs7_enveloped:
81 case NID_pkcs7_signedAndEnveloped:
82 case NID_pkcs7_digest:
83 case NID_pkcs7_encrypted:
84 isOther = 0;
85 break;
86 default:
87 isOther = 1;
88 }
89
90 return isOther;
91
92}
67fec850 93
caf044cb 94static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
0f113f3e
MC
95{
96 if (PKCS7_type_is_data(p7))
97 return p7->d.data;
98 if (PKCS7_type_is_other(p7) && p7->d.other
99 && (p7->d.other->type == V_ASN1_OCTET_STRING))
100 return p7->d.other->value.octet_string;
101 return NULL;
102}
67fec850 103
c5a55463 104static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
0f113f3e
MC
105{
106 BIO *btmp;
107 const EVP_MD *md;
108 if ((btmp = BIO_new(BIO_f_md())) == NULL) {
109 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
110 goto err;
111 }
112
113 md = EVP_get_digestbyobj(alg->algorithm);
114 if (md == NULL) {
115 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE);
116 goto err;
117 }
118
119 BIO_set_md(btmp, md);
120 if (*pbio == NULL)
121 *pbio = btmp;
122 else if (!BIO_push(*pbio, btmp)) {
123 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
124 goto err;
125 }
126 btmp = NULL;
127
128 return 1;
129
130 err:
ca3a82c3 131 BIO_free(btmp);
0f113f3e 132 return 0;
c5a55463 133
0f113f3e 134}
399a6f0b 135
0f113f3e
MC
136static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
137 unsigned char *key, int keylen)
138{
139 EVP_PKEY_CTX *pctx = NULL;
140 EVP_PKEY *pkey = NULL;
141 unsigned char *ek = NULL;
142 int ret = 0;
143 size_t eklen;
399a6f0b 144
0f113f3e 145 pkey = X509_get_pubkey(ri->cert);
399a6f0b 146
0f113f3e
MC
147 if (!pkey)
148 return 0;
399a6f0b 149
0f113f3e
MC
150 pctx = EVP_PKEY_CTX_new(pkey, NULL);
151 if (!pctx)
152 return 0;
399a6f0b 153
0f113f3e
MC
154 if (EVP_PKEY_encrypt_init(pctx) <= 0)
155 goto err;
399a6f0b 156
0f113f3e
MC
157 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
158 EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) {
159 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
160 goto err;
161 }
399a6f0b 162
0f113f3e
MC
163 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
164 goto err;
399a6f0b 165
0f113f3e 166 ek = OPENSSL_malloc(eklen);
399a6f0b 167
0f113f3e
MC
168 if (ek == NULL) {
169 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
170 goto err;
171 }
399a6f0b 172
0f113f3e
MC
173 if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
174 goto err;
399a6f0b 175
0f113f3e
MC
176 ASN1_STRING_set0(ri->enc_key, ek, eklen);
177 ek = NULL;
399a6f0b 178
0f113f3e 179 ret = 1;
399a6f0b 180
0f113f3e 181 err:
c5ba2d99
RS
182 EVP_PKEY_free(pkey);
183 EVP_PKEY_CTX_free(pctx);
b548a1f1 184 OPENSSL_free(ek);
0f113f3e 185 return ret;
399a6f0b 186
0f113f3e 187}
399a6f0b 188
777c47ac 189static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
0f113f3e
MC
190 PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey)
191{
192 EVP_PKEY_CTX *pctx = NULL;
193 unsigned char *ek = NULL;
194 size_t eklen;
195
196 int ret = -1;
197
198 pctx = EVP_PKEY_CTX_new(pkey, NULL);
199 if (!pctx)
200 return -1;
201
202 if (EVP_PKEY_decrypt_init(pctx) <= 0)
203 goto err;
204
205 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
206 EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) {
207 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
208 goto err;
209 }
210
211 if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
212 ri->enc_key->data, ri->enc_key->length) <= 0)
213 goto err;
214
215 ek = OPENSSL_malloc(eklen);
216
217 if (ek == NULL) {
218 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
219 goto err;
220 }
221
222 if (EVP_PKEY_decrypt(pctx, ek, &eklen,
223 ri->enc_key->data, ri->enc_key->length) <= 0) {
224 ret = 0;
225 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
226 goto err;
227 }
228
229 ret = 1;
230
4b45c6e5 231 OPENSSL_clear_free(*pek, *peklen);
0f113f3e
MC
232 *pek = ek;
233 *peklen = eklen;
234
235 err:
c5ba2d99 236 EVP_PKEY_CTX_free(pctx);
b548a1f1 237 if (!ret)
0f113f3e
MC
238 OPENSSL_free(ek);
239
240 return ret;
241}
399a6f0b 242
6b691a5c 243BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
0f113f3e
MC
244{
245 int i;
246 BIO *out = NULL, *btmp = NULL;
247 X509_ALGOR *xa = NULL;
248 const EVP_CIPHER *evp_cipher = NULL;
249 STACK_OF(X509_ALGOR) *md_sk = NULL;
250 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
251 X509_ALGOR *xalg = NULL;
252 PKCS7_RECIP_INFO *ri = NULL;
253 ASN1_OCTET_STRING *os = NULL;
254
c225c3cf
EK
255 if (p7 == NULL) {
256 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
257 return NULL;
258 }
259 /*
260 * The content field in the PKCS7 ContentInfo is optional, but that really
261 * only applies to inner content (precisely, detached signatures).
262 *
263 * When reading content, missing outer content is therefore treated as an
264 * error.
265 *
266 * When creating content, PKCS7_content_new() must be called before
267 * calling this method, so a NULL p7->d is always an error.
268 */
269 if (p7->d.ptr == NULL) {
270 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
271 return NULL;
272 }
273
0f113f3e
MC
274 i = OBJ_obj2nid(p7->type);
275 p7->state = PKCS7_S_HEADER;
276
277 switch (i) {
278 case NID_pkcs7_signed:
279 md_sk = p7->d.sign->md_algs;
280 os = PKCS7_get_octet_string(p7->d.sign->contents);
281 break;
282 case NID_pkcs7_signedAndEnveloped:
283 rsk = p7->d.signed_and_enveloped->recipientinfo;
284 md_sk = p7->d.signed_and_enveloped->md_algs;
285 xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
286 evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
287 if (evp_cipher == NULL) {
288 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
289 goto err;
290 }
291 break;
292 case NID_pkcs7_enveloped:
293 rsk = p7->d.enveloped->recipientinfo;
294 xalg = p7->d.enveloped->enc_data->algorithm;
295 evp_cipher = p7->d.enveloped->enc_data->cipher;
296 if (evp_cipher == NULL) {
297 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
298 goto err;
299 }
300 break;
301 case NID_pkcs7_digest:
302 xa = p7->d.digest->md;
303 os = PKCS7_get_octet_string(p7->d.digest->contents);
304 break;
305 case NID_pkcs7_data:
306 break;
307 default:
308 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
309 goto err;
310 }
311
312 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
313 if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i)))
314 goto err;
315
316 if (xa && !PKCS7_bio_add_digest(&out, xa))
317 goto err;
318
319 if (evp_cipher != NULL) {
320 unsigned char key[EVP_MAX_KEY_LENGTH];
321 unsigned char iv[EVP_MAX_IV_LENGTH];
322 int keylen, ivlen;
323 EVP_CIPHER_CTX *ctx;
324
325 if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
326 PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
327 goto err;
328 }
329 BIO_get_cipher_ctx(btmp, &ctx);
330 keylen = EVP_CIPHER_key_length(evp_cipher);
331 ivlen = EVP_CIPHER_iv_length(evp_cipher);
332 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
333 if (ivlen > 0)
266483d2 334 if (RAND_bytes(iv, ivlen) <= 0)
0f113f3e
MC
335 goto err;
336 if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0)
337 goto err;
338 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
339 goto err;
340 if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
341 goto err;
342
343 if (ivlen > 0) {
344 if (xalg->parameter == NULL) {
345 xalg->parameter = ASN1_TYPE_new();
346 if (xalg->parameter == NULL)
347 goto err;
348 }
349 if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
350 goto err;
351 }
352
353 /* Lets do the pub key stuff :-) */
354 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
355 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
356 if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
357 goto err;
358 }
359 OPENSSL_cleanse(key, keylen);
360
361 if (out == NULL)
362 out = btmp;
363 else
364 BIO_push(out, btmp);
365 btmp = NULL;
366 }
367
368 if (bio == NULL) {
369 if (PKCS7_is_detached(p7))
370 bio = BIO_new(BIO_s_null());
371 else if (os && os->length > 0)
372 bio = BIO_new_mem_buf(os->data, os->length);
373 if (bio == NULL) {
374 bio = BIO_new(BIO_s_mem());
375 if (bio == NULL)
376 goto err;
377 BIO_set_mem_eof_return(bio, 0);
378 }
379 }
380 if (out)
381 BIO_push(out, bio);
382 else
383 out = bio;
ca3a82c3
RS
384 return out;
385
0f113f3e 386 err:
ca3a82c3
RS
387 BIO_free_all(out);
388 BIO_free_all(btmp);
389 return NULL;
0f113f3e 390}
dfeab068 391
8f2e4fdf 392static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
0f113f3e
MC
393{
394 int ret;
395 ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
a8d8e06b 396 X509_get_issuer_name(pcert));
0f113f3e
MC
397 if (ret)
398 return ret;
a8d8e06b
DSH
399 return ASN1_INTEGER_cmp(X509_get_serialNumber(pcert),
400 ri->issuer_and_serial->serial);
0f113f3e 401}
8f2e4fdf 402
dfeab068 403/* int */
84fa704c 404BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
0f113f3e
MC
405{
406 int i, j;
407 BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
408 X509_ALGOR *xa;
409 ASN1_OCTET_STRING *data_body = NULL;
410 const EVP_MD *evp_md;
411 const EVP_CIPHER *evp_cipher = NULL;
412 EVP_CIPHER_CTX *evp_ctx = NULL;
413 X509_ALGOR *enc_alg = NULL;
414 STACK_OF(X509_ALGOR) *md_sk = NULL;
415 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
416 PKCS7_RECIP_INFO *ri = NULL;
417 unsigned char *ek = NULL, *tkey = NULL;
418 int eklen = 0, tkeylen = 0;
419
c225c3cf
EK
420 if (p7 == NULL) {
421 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER);
422 return NULL;
423 }
424
425 if (p7->d.ptr == NULL) {
426 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
427 return NULL;
428 }
429
0f113f3e
MC
430 i = OBJ_obj2nid(p7->type);
431 p7->state = PKCS7_S_HEADER;
432
433 switch (i) {
434 case NID_pkcs7_signed:
59302b60
EK
435 /*
436 * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
437 * field and optional content.
438 * data_body is NULL if that structure has no (=detached) content
439 * or if the contentType is wrong (i.e., not "data").
440 */
0f113f3e
MC
441 data_body = PKCS7_get_octet_string(p7->d.sign->contents);
442 if (!PKCS7_is_detached(p7) && data_body == NULL) {
443 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
444 PKCS7_R_INVALID_SIGNED_DATA_TYPE);
445 goto err;
446 }
447 md_sk = p7->d.sign->md_algs;
448 break;
449 case NID_pkcs7_signedAndEnveloped:
450 rsk = p7->d.signed_and_enveloped->recipientinfo;
451 md_sk = p7->d.signed_and_enveloped->md_algs;
59302b60 452 /* data_body is NULL if the optional EncryptedContent is missing. */
0f113f3e
MC
453 data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
454 enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
455 evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
456 if (evp_cipher == NULL) {
457 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
458 PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
459 goto err;
460 }
461 break;
462 case NID_pkcs7_enveloped:
463 rsk = p7->d.enveloped->recipientinfo;
464 enc_alg = p7->d.enveloped->enc_data->algorithm;
59302b60 465 /* data_body is NULL if the optional EncryptedContent is missing. */
0f113f3e
MC
466 data_body = p7->d.enveloped->enc_data->enc_data;
467 evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm);
468 if (evp_cipher == NULL) {
469 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
470 PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
471 goto err;
472 }
473 break;
474 default:
475 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
476 goto err;
477 }
478
59302b60
EK
479 /* Detached content must be supplied via in_bio instead. */
480 if (data_body == NULL && in_bio == NULL) {
481 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
482 goto err;
483 }
484
0f113f3e
MC
485 /* We will be checking the signature */
486 if (md_sk != NULL) {
487 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
488 xa = sk_X509_ALGOR_value(md_sk, i);
489 if ((btmp = BIO_new(BIO_f_md())) == NULL) {
490 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
491 goto err;
492 }
493
494 j = OBJ_obj2nid(xa->algorithm);
495 evp_md = EVP_get_digestbynid(j);
496 if (evp_md == NULL) {
497 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
498 PKCS7_R_UNKNOWN_DIGEST_TYPE);
499 goto err;
500 }
501
502 BIO_set_md(btmp, evp_md);
503 if (out == NULL)
504 out = btmp;
505 else
506 BIO_push(out, btmp);
507 btmp = NULL;
508 }
509 }
510
511 if (evp_cipher != NULL) {
0f113f3e
MC
512 if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
513 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
514 goto err;
515 }
516
517 /*
518 * It was encrypted, we need to decrypt the secret key with the
519 * private key
520 */
521
522 /*
523 * Find the recipientInfo which matches the passed certificate (if
524 * any)
525 */
526
527 if (pcert) {
528 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
529 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
530 if (!pkcs7_cmp_ri(ri, pcert))
531 break;
532 ri = NULL;
533 }
534 if (ri == NULL) {
535 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
536 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
537 goto err;
538 }
539 }
540
541 /* If we haven't got a certificate try each ri in turn */
542 if (pcert == NULL) {
543 /*
544 * Always attempt to decrypt all rinfo even after success as a
545 * defence against MMA timing attacks.
546 */
547 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
548 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
549
550 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
551 goto err;
552 ERR_clear_error();
553 }
554 } else {
555 /* Only exit on fatal errors, not decrypt failure */
556 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0)
557 goto err;
558 ERR_clear_error();
559 }
560
561 evp_ctx = NULL;
562 BIO_get_cipher_ctx(etmp, &evp_ctx);
563 if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0)
564 goto err;
565 if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
566 goto err;
567 /* Generate random key as MMA defence */
568 tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx);
569 tkey = OPENSSL_malloc(tkeylen);
90945fa3 570 if (tkey == NULL)
0f113f3e
MC
571 goto err;
572 if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
573 goto err;
574 if (ek == NULL) {
575 ek = tkey;
576 eklen = tkeylen;
577 tkey = NULL;
578 }
579
580 if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
581 /*
582 * Some S/MIME clients don't use the same key and effective key
583 * length. The key length is determined by the size of the
584 * decrypted RSA key.
585 */
586 if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) {
587 /* Use random key as MMA defence */
4b45c6e5 588 OPENSSL_clear_free(ek, eklen);
0f113f3e
MC
589 ek = tkey;
590 eklen = tkeylen;
591 tkey = NULL;
592 }
593 }
594 /* Clear errors so we don't leak information useful in MMA */
595 ERR_clear_error();
596 if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0)
597 goto err;
598
4b45c6e5
RS
599 OPENSSL_clear_free(ek, eklen);
600 ek = NULL;
601 OPENSSL_clear_free(tkey, tkeylen);
602 tkey = NULL;
0f113f3e
MC
603
604 if (out == NULL)
605 out = etmp;
606 else
607 BIO_push(out, etmp);
608 etmp = NULL;
609 }
59302b60 610 if (in_bio != NULL) {
0f113f3e
MC
611 bio = in_bio;
612 } else {
0f113f3e
MC
613 if (data_body->length > 0)
614 bio = BIO_new_mem_buf(data_body->data, data_body->length);
615 else {
616 bio = BIO_new(BIO_s_mem());
90945fa3
MC
617 if (bio == NULL)
618 goto err;
0f113f3e
MC
619 BIO_set_mem_eof_return(bio, 0);
620 }
621 if (bio == NULL)
622 goto err;
0f113f3e
MC
623 }
624 BIO_push(out, bio);
625 bio = NULL;
4b45c6e5
RS
626 return out;
627
0f113f3e 628 err:
4b45c6e5
RS
629 OPENSSL_clear_free(ek, eklen);
630 OPENSSL_clear_free(tkey, tkeylen);
631 BIO_free_all(out);
632 BIO_free_all(btmp);
633 BIO_free_all(etmp);
634 BIO_free_all(bio);
635 return NULL;
0f113f3e 636}
d02b48c6 637
c5a55463 638static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
0f113f3e
MC
639{
640 for (;;) {
641 bio = BIO_find_type(bio, BIO_TYPE_MD);
642 if (bio == NULL) {
643 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,
644 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
645 return NULL;
646 }
647 BIO_get_md_ctx(bio, pmd);
648 if (*pmd == NULL) {
649 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR);
650 return NULL;
651 }
652 if (EVP_MD_CTX_type(*pmd) == nid)
653 return bio;
654 bio = BIO_next(bio);
655 }
656 return NULL;
657}
c5a55463 658
76fa8f18 659static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
0f113f3e
MC
660{
661 unsigned char md_data[EVP_MAX_MD_SIZE];
662 unsigned int md_len;
663
664 /* Add signing time if not already present */
665 if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
666 if (!PKCS7_add0_attrib_signing_time(si, NULL)) {
667 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
668 return 0;
669 }
670 }
671
672 /* Add digest */
673 if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) {
674 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
675 return 0;
676 }
677 if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) {
678 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
679 return 0;
680 }
681
682 /* Now sign the attributes */
683 if (!PKCS7_SIGNER_INFO_sign(si))
684 return 0;
685
686 return 1;
687}
688
6b691a5c 689int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
0f113f3e
MC
690{
691 int ret = 0;
692 int i, j;
693 BIO *btmp;
694 PKCS7_SIGNER_INFO *si;
6e59a892 695 EVP_MD_CTX *mdc, *ctx_tmp;
0f113f3e
MC
696 STACK_OF(X509_ATTRIBUTE) *sk;
697 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
698 ASN1_OCTET_STRING *os = NULL;
699
c225c3cf
EK
700 if (p7 == NULL) {
701 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
702 return 0;
703 }
704
705 if (p7->d.ptr == NULL) {
706 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
707 return 0;
708 }
709
bfb0641f 710 ctx_tmp = EVP_MD_CTX_new();
6e59a892
RL
711 if (ctx_tmp == NULL) {
712 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
713 return 0;
714 }
715
0f113f3e
MC
716 i = OBJ_obj2nid(p7->type);
717 p7->state = PKCS7_S_HEADER;
718
719 switch (i) {
720 case NID_pkcs7_data:
721 os = p7->d.data;
722 break;
723 case NID_pkcs7_signedAndEnveloped:
724 /* XXXXXXXXXXXXXXXX */
725 si_sk = p7->d.signed_and_enveloped->signer_info;
726 os = p7->d.signed_and_enveloped->enc_data->enc_data;
90945fa3 727 if (os == NULL) {
f422a514 728 os = ASN1_OCTET_STRING_new();
90945fa3 729 if (os == NULL) {
0f113f3e
MC
730 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
731 goto err;
732 }
733 p7->d.signed_and_enveloped->enc_data->enc_data = os;
734 }
735 break;
736 case NID_pkcs7_enveloped:
737 /* XXXXXXXXXXXXXXXX */
738 os = p7->d.enveloped->enc_data->enc_data;
90945fa3 739 if (os == NULL) {
f422a514 740 os = ASN1_OCTET_STRING_new();
90945fa3 741 if (os == NULL) {
0f113f3e
MC
742 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
743 goto err;
744 }
745 p7->d.enveloped->enc_data->enc_data = os;
746 }
747 break;
748 case NID_pkcs7_signed:
749 si_sk = p7->d.sign->signer_info;
750 os = PKCS7_get_octet_string(p7->d.sign->contents);
751 /* If detached data then the content is excluded */
752 if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
f422a514 753 ASN1_OCTET_STRING_free(os);
c225c3cf 754 os = NULL;
0f113f3e
MC
755 p7->d.sign->contents->d.data = NULL;
756 }
757 break;
758
759 case NID_pkcs7_digest:
760 os = PKCS7_get_octet_string(p7->d.digest->contents);
761 /* If detached data then the content is excluded */
762 if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
f422a514 763 ASN1_OCTET_STRING_free(os);
c225c3cf 764 os = NULL;
0f113f3e
MC
765 p7->d.digest->contents->d.data = NULL;
766 }
767 break;
768
769 default:
770 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
771 goto err;
772 }
773
774 if (si_sk != NULL) {
775 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
776 si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
777 if (si->pkey == NULL)
778 continue;
779
780 j = OBJ_obj2nid(si->digest_alg->algorithm);
781
782 btmp = bio;
783
784 btmp = PKCS7_find_digest(&mdc, btmp, j);
785
786 if (btmp == NULL)
787 goto err;
788
789 /*
790 * We now have the EVP_MD_CTX, lets do the signing.
791 */
6e59a892 792 if (!EVP_MD_CTX_copy_ex(ctx_tmp, mdc))
0f113f3e
MC
793 goto err;
794
795 sk = si->auth_attr;
796
797 /*
798 * If there are attributes, we add the digest attribute and only
799 * sign the attributes
800 */
801 if (sk_X509_ATTRIBUTE_num(sk) > 0) {
6e59a892 802 if (!do_pkcs7_signed_attrib(si, ctx_tmp))
0f113f3e
MC
803 goto err;
804 } else {
805 unsigned char *abuf = NULL;
806 unsigned int abuflen;
807 abuflen = EVP_PKEY_size(si->pkey);
808 abuf = OPENSSL_malloc(abuflen);
90945fa3 809 if (abuf == NULL)
0f113f3e
MC
810 goto err;
811
6e59a892 812 if (!EVP_SignFinal(ctx_tmp, abuf, &abuflen, si->pkey)) {
0f113f3e
MC
813 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
814 goto err;
815 }
816 ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
817 }
818 }
819 } else if (i == NID_pkcs7_digest) {
820 unsigned char md_data[EVP_MAX_MD_SIZE];
821 unsigned int md_len;
822 if (!PKCS7_find_digest(&mdc, bio,
823 OBJ_obj2nid(p7->d.digest->md->algorithm)))
824 goto err;
825 if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
826 goto err;
f422a514 827 ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
0f113f3e
MC
828 }
829
c225c3cf 830 if (!PKCS7_is_detached(p7)) {
0f113f3e 831 /*
c225c3cf
EK
832 * NOTE(emilia): I think we only reach os == NULL here because detached
833 * digested data support is broken.
0f113f3e 834 */
c225c3cf
EK
835 if (os == NULL)
836 goto err;
837 if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
838 char *cont;
839 long contlen;
840 btmp = BIO_find_type(bio, BIO_TYPE_MEM);
841 if (btmp == NULL) {
842 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
843 goto err;
844 }
845 contlen = BIO_get_mem_data(btmp, &cont);
846 /*
847 * Mark the BIO read only then we can use its copy of the data
848 * instead of making an extra copy.
849 */
850 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
851 BIO_set_mem_eof_return(btmp, 0);
852 ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
853 }
0f113f3e
MC
854 }
855 ret = 1;
856 err:
bfb0641f 857 EVP_MD_CTX_free(ctx_tmp);
0f113f3e
MC
858 return (ret);
859}
d02b48c6 860
76fa8f18 861int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
0f113f3e 862{
6e59a892 863 EVP_MD_CTX *mctx;
0f113f3e
MC
864 EVP_PKEY_CTX *pctx;
865 unsigned char *abuf = NULL;
866 int alen;
867 size_t siglen;
868 const EVP_MD *md = NULL;
869
870 md = EVP_get_digestbyobj(si->digest_alg->algorithm);
871 if (md == NULL)
872 return 0;
873
bfb0641f 874 mctx = EVP_MD_CTX_new();
6e59a892
RL
875 if (mctx == NULL) {
876 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, ERR_R_MALLOC_FAILURE);
877 goto err;
878 }
879
880 if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
0f113f3e
MC
881 goto err;
882
883 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
884 EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) {
885 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
886 goto err;
887 }
888
889 alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf,
890 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
891 if (!abuf)
892 goto err;
6e59a892 893 if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
0f113f3e
MC
894 goto err;
895 OPENSSL_free(abuf);
896 abuf = NULL;
6e59a892 897 if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
0f113f3e
MC
898 goto err;
899 abuf = OPENSSL_malloc(siglen);
90945fa3 900 if (abuf == NULL)
0f113f3e 901 goto err;
6e59a892 902 if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
0f113f3e
MC
903 goto err;
904
905 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
906 EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) {
907 PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR);
908 goto err;
909 }
910
bfb0641f 911 EVP_MD_CTX_free(mctx);
0f113f3e
MC
912
913 ASN1_STRING_set0(si->enc_digest, abuf, siglen);
914
915 return 1;
916
917 err:
b548a1f1 918 OPENSSL_free(abuf);
bfb0641f 919 EVP_MD_CTX_free(mctx);
0f113f3e
MC
920 return 0;
921
922}
76fa8f18 923
6b691a5c 924int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
0f113f3e
MC
925 PKCS7 *p7, PKCS7_SIGNER_INFO *si)
926{
927 PKCS7_ISSUER_AND_SERIAL *ias;
928 int ret = 0, i;
929 STACK_OF(X509) *cert;
930 X509 *x509;
931
c225c3cf
EK
932 if (p7 == NULL) {
933 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER);
934 return 0;
935 }
936
937 if (p7->d.ptr == NULL) {
938 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
939 return 0;
940 }
941
0f113f3e
MC
942 if (PKCS7_type_is_signed(p7)) {
943 cert = p7->d.sign->cert;
944 } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
945 cert = p7->d.signed_and_enveloped->cert;
946 } else {
947 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
948 goto err;
949 }
950 /* XXXXXXXXXXXXXXXXXXXXXXX */
951 ias = si->issuer_and_serial;
952
953 x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial);
954
955 /* were we able to find the cert in passed to us */
956 if (x509 == NULL) {
957 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
958 PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
959 goto err;
960 }
961
962 /* Lets verify */
963 if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) {
964 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
965 goto err;
966 }
967 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
968 i = X509_verify_cert(ctx);
969 if (i <= 0) {
970 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
971 X509_STORE_CTX_cleanup(ctx);
972 goto err;
973 }
974 X509_STORE_CTX_cleanup(ctx);
975
976 return PKCS7_signatureVerify(bio, p7, si, x509);
977 err:
978 return ret;
979}
170afce5
DSH
980
981int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
0f113f3e 982 X509 *x509)
dfeab068 983{
0f113f3e 984 ASN1_OCTET_STRING *os;
6e59a892 985 EVP_MD_CTX *mdc_tmp, *mdc;
0f113f3e
MC
986 int ret = 0, i;
987 int md_type;
988 STACK_OF(X509_ATTRIBUTE) *sk;
989 BIO *btmp;
990 EVP_PKEY *pkey;
991
bfb0641f 992 mdc_tmp = EVP_MD_CTX_new();
6e59a892
RL
993 if (mdc_tmp == NULL) {
994 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_MALLOC_FAILURE);
995 goto err;
996 }
0f113f3e
MC
997
998 if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) {
999 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
1000 goto err;
1001 }
1002
1003 md_type = OBJ_obj2nid(si->digest_alg->algorithm);
1004
1005 btmp = bio;
1006 for (;;) {
1007 if ((btmp == NULL) ||
1008 ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
1009 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
1010 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
1011 goto err;
1012 }
1013 BIO_get_md_ctx(btmp, &mdc);
1014 if (mdc == NULL) {
1015 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR);
1016 goto err;
1017 }
1018 if (EVP_MD_CTX_type(mdc) == md_type)
1019 break;
1020 /*
1021 * Workaround for some broken clients that put the signature OID
1022 * instead of the digest OID in digest_alg->algorithm
1023 */
1024 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
1025 break;
1026 btmp = BIO_next(btmp);
1027 }
1028
1029 /*
1030 * mdc is the digest ctx that we want, unless there are attributes, in
1031 * which case the digest is the signed attributes
1032 */
6e59a892 1033 if (!EVP_MD_CTX_copy_ex(mdc_tmp, mdc))
0f113f3e
MC
1034 goto err;
1035
1036 sk = si->auth_attr;
1037 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
1038 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
1039 unsigned int md_len;
1040 int alen;
1041 ASN1_OCTET_STRING *message_digest;
1042
6e59a892 1043 if (!EVP_DigestFinal_ex(mdc_tmp, md_dat, &md_len))
0f113f3e
MC
1044 goto err;
1045 message_digest = PKCS7_digest_from_attributes(sk);
1046 if (!message_digest) {
1047 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
1048 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
1049 goto err;
1050 }
1051 if ((message_digest->length != (int)md_len) ||
1052 (memcmp(message_digest->data, md_dat, md_len))) {
0f113f3e
MC
1053 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE);
1054 ret = -1;
1055 goto err;
1056 }
1057
6e59a892 1058 if (!EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL))
0f113f3e
MC
1059 goto err;
1060
1061 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
1062 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
1063 if (alen <= 0) {
1064 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB);
1065 ret = -1;
1066 goto err;
1067 }
6e59a892 1068 if (!EVP_VerifyUpdate(mdc_tmp, abuf, alen))
0f113f3e
MC
1069 goto err;
1070
1071 OPENSSL_free(abuf);
1072 }
1073
1074 os = si->enc_digest;
1075 pkey = X509_get_pubkey(x509);
1076 if (!pkey) {
1077 ret = -1;
1078 goto err;
1079 }
1080
6e59a892 1081 i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey);
0f113f3e
MC
1082 EVP_PKEY_free(pkey);
1083 if (i <= 0) {
1084 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
1085 ret = -1;
1086 goto err;
c5ba2d99
RS
1087 }
1088 ret = 1;
0f113f3e 1089 err:
bfb0641f 1090 EVP_MD_CTX_free(mdc_tmp);
0f113f3e
MC
1091 return (ret);
1092}
d02b48c6 1093
6b691a5c 1094PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
0f113f3e
MC
1095{
1096 STACK_OF(PKCS7_RECIP_INFO) *rsk;
1097 PKCS7_RECIP_INFO *ri;
1098 int i;
1099
1100 i = OBJ_obj2nid(p7->type);
1101 if (i != NID_pkcs7_signedAndEnveloped)
1102 return NULL;
1103 if (p7->d.signed_and_enveloped == NULL)
1104 return NULL;
1105 rsk = p7->d.signed_and_enveloped->recipientinfo;
1106 if (rsk == NULL)
1107 return NULL;
0f113f3e
MC
1108 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
1109 return (NULL);
1110 ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
1111 return (ri->issuer_and_serial);
1112}
dfeab068 1113
6b691a5c 1114ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
0f113f3e
MC
1115{
1116 return (get_attribute(si->auth_attr, nid));
1117}
dfeab068 1118
6b691a5c 1119ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
0f113f3e
MC
1120{
1121 return (get_attribute(si->unauth_attr, nid));
1122}
dfeab068 1123
b6436ff2 1124static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
0f113f3e 1125{
9b0a4531 1126 int idx;
0f113f3e 1127 X509_ATTRIBUTE *xa;
9b0a4531
DSH
1128 idx = X509at_get_attr_by_NID(sk, nid, -1);
1129 xa = X509at_get_attr(sk, idx);
1130 return X509_ATTRIBUTE_get0_type(xa, 0);
0f113f3e 1131}
dfeab068 1132
b6436ff2 1133ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
10243d97 1134{
0f113f3e 1135 ASN1_TYPE *astype;
75ebbd9a 1136 if ((astype = get_attribute(sk, NID_pkcs9_messageDigest)) == NULL)
0f113f3e
MC
1137 return NULL;
1138 return astype->value.octet_string;
10243d97 1139}
dfeab068 1140
b6436ff2 1141int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
0f113f3e
MC
1142 STACK_OF(X509_ATTRIBUTE) *sk)
1143{
1144 int i;
1145
222561fe 1146 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free);
0f113f3e
MC
1147 p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk);
1148 if (p7si->auth_attr == NULL)
1149 return 0;
1150 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1151 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i,
1152 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
1153 (sk, i))))
1154 == NULL)
1155 return (0);
1156 }
1157 return (1);
1158}
1159
1160int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
1161 STACK_OF(X509_ATTRIBUTE) *sk)
1162{
1163 int i;
1164
222561fe 1165 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free);
0f113f3e
MC
1166 p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk);
1167 if (p7si->unauth_attr == NULL)
1168 return 0;
1169 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1170 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i,
1171 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
1172 (sk, i))))
1173 == NULL)
1174 return (0);
1175 }
1176 return (1);
1177}
dfeab068 1178
6b691a5c 1179int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
0f113f3e
MC
1180 void *value)
1181{
1182 return (add_attribute(&(p7si->auth_attr), nid, atrtype, value));
1183}
dfeab068 1184
6b691a5c 1185int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
0f113f3e
MC
1186 void *value)
1187{
1188 return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value));
1189}
dfeab068 1190
b6436ff2 1191static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
0f113f3e
MC
1192 void *value)
1193{
1194 X509_ATTRIBUTE *attr = NULL;
1195
1196 if (*sk == NULL) {
75ebbd9a 1197 if ((*sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
0f113f3e
MC
1198 return 0;
1199 new_attrib:
75ebbd9a 1200 if ((attr = X509_ATTRIBUTE_create(nid, atrtype, value)) == NULL)
0f113f3e
MC
1201 return 0;
1202 if (!sk_X509_ATTRIBUTE_push(*sk, attr)) {
1203 X509_ATTRIBUTE_free(attr);
1204 return 0;
1205 }
1206 } else {
1207 int i;
1208
1209 for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) {
1210 attr = sk_X509_ATTRIBUTE_value(*sk, i);
9b0a4531 1211 if (OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr)) == nid) {
0f113f3e
MC
1212 X509_ATTRIBUTE_free(attr);
1213 attr = X509_ATTRIBUTE_create(nid, atrtype, value);
1214 if (attr == NULL)
1215 return 0;
1216 if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) {
1217 X509_ATTRIBUTE_free(attr);
1218 return 0;
1219 }
1220 goto end;
1221 }
1222 }
1223 goto new_attrib;
1224 }
1225 end:
1226 return (1);
1227}