]> git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/pkcs7/pk7_doit.c
faefa9e95b551bf3fe1266ef9c493c4a03ca8f03
[thirdparty/openssl.git] / crypto / pkcs7 / pk7_doit.c
1 /*
2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
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
8 */
9
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/rand.h>
13 #include <openssl/objects.h>
14 #include <openssl/x509.h>
15 #include <openssl/x509v3.h>
16 #include <openssl/err.h>
17 #include "pk7_local.h"
18
19 DEFINE_STACK_OF(X509_ALGOR)
20 DEFINE_STACK_OF(PKCS7_RECIP_INFO)
21 DEFINE_STACK_OF(PKCS7_SIGNER_INFO)
22
23 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
24 void *value);
25 static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid);
26
27 static int PKCS7_type_is_other(PKCS7 *p7)
28 {
29 int isOther = 1;
30
31 int nid = OBJ_obj2nid(p7->type);
32
33 switch (nid) {
34 case NID_pkcs7_data:
35 case NID_pkcs7_signed:
36 case NID_pkcs7_enveloped:
37 case NID_pkcs7_signedAndEnveloped:
38 case NID_pkcs7_digest:
39 case NID_pkcs7_encrypted:
40 isOther = 0;
41 break;
42 default:
43 isOther = 1;
44 }
45
46 return isOther;
47
48 }
49
50 static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7)
51 {
52 if (PKCS7_type_is_data(p7))
53 return p7->d.data;
54 if (PKCS7_type_is_other(p7) && p7->d.other
55 && (p7->d.other->type == V_ASN1_OCTET_STRING))
56 return p7->d.other->value.octet_string;
57 return NULL;
58 }
59
60 static int pkcs7_bio_add_digest(BIO **pbio, X509_ALGOR *alg,
61 const PKCS7_CTX *ctx)
62 {
63 BIO *btmp;
64 const char *name;
65 EVP_MD *fetched = NULL;
66 const EVP_MD *md;
67
68 if ((btmp = BIO_new(BIO_f_md())) == NULL) {
69 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
70 goto err;
71 }
72
73 name = OBJ_nid2sn(OBJ_obj2nid(alg->algorithm));
74
75 (void)ERR_set_mark();
76 fetched = EVP_MD_fetch(ctx->libctx, name, ctx->propq);
77 if (fetched != NULL)
78 md = fetched;
79 else
80 md = EVP_get_digestbyname(name);
81
82 if (md == NULL) {
83 (void)ERR_clear_last_mark();
84 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE);
85 goto err;
86 }
87 (void)ERR_pop_to_mark();
88
89 BIO_set_md(btmp, md);
90 EVP_MD_free(fetched);
91 if (*pbio == NULL)
92 *pbio = btmp;
93 else if (!BIO_push(*pbio, btmp)) {
94 PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB);
95 goto err;
96 }
97 btmp = NULL;
98
99 return 1;
100
101 err:
102 BIO_free(btmp);
103 return 0;
104 }
105
106 static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
107 unsigned char *key, int keylen)
108 {
109 EVP_PKEY_CTX *pctx = NULL;
110 EVP_PKEY *pkey = NULL;
111 unsigned char *ek = NULL;
112 int ret = 0;
113 size_t eklen;
114 const PKCS7_CTX *ctx = ri->ctx;
115
116 pkey = X509_get0_pubkey(ri->cert);
117 if (pkey == NULL)
118 return 0;
119
120 pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, ctx->propq);
121 if (pctx == NULL)
122 return 0;
123
124 if (EVP_PKEY_encrypt_init(pctx) <= 0)
125 goto err;
126
127 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
128 EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) {
129 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
130 goto err;
131 }
132
133 if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
134 goto err;
135
136 ek = OPENSSL_malloc(eklen);
137
138 if (ek == NULL) {
139 PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
140 goto err;
141 }
142
143 if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
144 goto err;
145
146 ASN1_STRING_set0(ri->enc_key, ek, eklen);
147 ek = NULL;
148
149 ret = 1;
150
151 err:
152 EVP_PKEY_CTX_free(pctx);
153 OPENSSL_free(ek);
154 return ret;
155
156 }
157
158 static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen,
159 PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey,
160 size_t fixlen)
161 {
162 EVP_PKEY_CTX *pctx = NULL;
163 unsigned char *ek = NULL;
164 size_t eklen;
165 int ret = -1;
166 const PKCS7_CTX *ctx = ri->ctx;
167
168 pctx = EVP_PKEY_CTX_new_from_pkey(ctx->libctx, pkey, ctx->propq);
169 if (pctx == NULL)
170 return -1;
171
172 if (EVP_PKEY_decrypt_init(pctx) <= 0)
173 goto err;
174
175 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT,
176 EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) {
177 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR);
178 goto err;
179 }
180
181 if (EVP_PKEY_decrypt(pctx, NULL, &eklen,
182 ri->enc_key->data, ri->enc_key->length) <= 0)
183 goto err;
184
185 ek = OPENSSL_malloc(eklen);
186
187 if (ek == NULL) {
188 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE);
189 goto err;
190 }
191
192 if (EVP_PKEY_decrypt(pctx, ek, &eklen,
193 ri->enc_key->data, ri->enc_key->length) <= 0
194 || eklen == 0
195 || (fixlen != 0 && eklen != fixlen)) {
196 ret = 0;
197 PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB);
198 goto err;
199 }
200
201 ret = 1;
202
203 OPENSSL_clear_free(*pek, *peklen);
204 *pek = ek;
205 *peklen = eklen;
206
207 err:
208 EVP_PKEY_CTX_free(pctx);
209 if (!ret)
210 OPENSSL_free(ek);
211
212 return ret;
213 }
214
215 BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
216 {
217 int i;
218 BIO *out = NULL, *btmp = NULL;
219 X509_ALGOR *xa = NULL;
220 EVP_CIPHER *fetched_cipher = NULL;
221 const EVP_CIPHER *cipher;
222 const EVP_CIPHER *evp_cipher = NULL;
223 STACK_OF(X509_ALGOR) *md_sk = NULL;
224 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
225 X509_ALGOR *xalg = NULL;
226 PKCS7_RECIP_INFO *ri = NULL;
227 ASN1_OCTET_STRING *os = NULL;
228 const PKCS7_CTX *p7_ctx;
229
230 if (p7 == NULL) {
231 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER);
232 return NULL;
233 }
234 p7_ctx = pkcs7_get0_ctx(p7);
235
236 /*
237 * The content field in the PKCS7 ContentInfo is optional, but that really
238 * only applies to inner content (precisely, detached signatures).
239 *
240 * When reading content, missing outer content is therefore treated as an
241 * error.
242 *
243 * When creating content, PKCS7_content_new() must be called before
244 * calling this method, so a NULL p7->d is always an error.
245 */
246 if (p7->d.ptr == NULL) {
247 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT);
248 return NULL;
249 }
250
251 i = OBJ_obj2nid(p7->type);
252 p7->state = PKCS7_S_HEADER;
253
254 switch (i) {
255 case NID_pkcs7_signed:
256 md_sk = p7->d.sign->md_algs;
257 os = PKCS7_get_octet_string(p7->d.sign->contents);
258 break;
259 case NID_pkcs7_signedAndEnveloped:
260 rsk = p7->d.signed_and_enveloped->recipientinfo;
261 md_sk = p7->d.signed_and_enveloped->md_algs;
262 xalg = p7->d.signed_and_enveloped->enc_data->algorithm;
263 evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher;
264 if (evp_cipher == NULL) {
265 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
266 goto err;
267 }
268 break;
269 case NID_pkcs7_enveloped:
270 rsk = p7->d.enveloped->recipientinfo;
271 xalg = p7->d.enveloped->enc_data->algorithm;
272 evp_cipher = p7->d.enveloped->enc_data->cipher;
273 if (evp_cipher == NULL) {
274 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED);
275 goto err;
276 }
277 break;
278 case NID_pkcs7_digest:
279 xa = p7->d.digest->md;
280 os = PKCS7_get_octet_string(p7->d.digest->contents);
281 break;
282 case NID_pkcs7_data:
283 break;
284 default:
285 PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
286 goto err;
287 }
288
289 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++)
290 if (!pkcs7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i), p7_ctx))
291 goto err;
292
293 if (xa && !pkcs7_bio_add_digest(&out, xa, p7_ctx))
294 goto err;
295
296 if (evp_cipher != NULL) {
297 unsigned char key[EVP_MAX_KEY_LENGTH];
298 unsigned char iv[EVP_MAX_IV_LENGTH];
299 int keylen, ivlen;
300 EVP_CIPHER_CTX *ctx;
301
302 if ((btmp = BIO_new(BIO_f_cipher())) == NULL) {
303 PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB);
304 goto err;
305 }
306 BIO_get_cipher_ctx(btmp, &ctx);
307 keylen = EVP_CIPHER_key_length(evp_cipher);
308 ivlen = EVP_CIPHER_iv_length(evp_cipher);
309 xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
310 if (ivlen > 0)
311 if (RAND_bytes_ex(p7_ctx->libctx, iv, ivlen) <= 0)
312 goto err;
313
314 (void)ERR_set_mark();
315 fetched_cipher = EVP_CIPHER_fetch(p7_ctx->libctx,
316 EVP_CIPHER_name(evp_cipher),
317 p7_ctx->propq);
318 (void)ERR_pop_to_mark();
319 if (fetched_cipher != NULL)
320 cipher = fetched_cipher;
321 else
322 cipher = evp_cipher;
323
324 if (EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, 1) <= 0)
325 goto err;
326
327 EVP_CIPHER_free(fetched_cipher);
328 fetched_cipher = NULL;
329
330 if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0)
331 goto err;
332 if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0)
333 goto err;
334
335 if (ivlen > 0) {
336 if (xalg->parameter == NULL) {
337 xalg->parameter = ASN1_TYPE_new();
338 if (xalg->parameter == NULL)
339 goto err;
340 }
341 if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
342 goto err;
343 }
344
345 /* Lets do the pub key stuff :-) */
346 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
347 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
348 if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
349 goto err;
350 }
351 OPENSSL_cleanse(key, keylen);
352
353 if (out == NULL)
354 out = btmp;
355 else
356 BIO_push(out, btmp);
357 btmp = NULL;
358 }
359
360 if (bio == NULL) {
361 if (PKCS7_is_detached(p7)) {
362 bio = BIO_new(BIO_s_null());
363 } else if (os && os->length > 0) {
364 bio = BIO_new_mem_buf(os->data, os->length);
365 } else {
366 bio = BIO_new(BIO_s_mem());
367 if (bio == NULL)
368 goto err;
369 BIO_set_mem_eof_return(bio, 0);
370 }
371 if (bio == NULL)
372 goto err;
373 }
374 if (out)
375 BIO_push(out, bio);
376 else
377 out = bio;
378 return out;
379
380 err:
381 EVP_CIPHER_free(fetched_cipher);
382 BIO_free_all(out);
383 BIO_free_all(btmp);
384 return NULL;
385 }
386
387 static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert)
388 {
389 int ret;
390 ret = X509_NAME_cmp(ri->issuer_and_serial->issuer,
391 X509_get_issuer_name(pcert));
392 if (ret)
393 return ret;
394 return ASN1_INTEGER_cmp(X509_get0_serialNumber(pcert),
395 ri->issuer_and_serial->serial);
396 }
397
398 /* int */
399 BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
400 {
401 int i, len;
402 BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL;
403 X509_ALGOR *xa;
404 ASN1_OCTET_STRING *data_body = NULL;
405 EVP_MD *evp_md = NULL;
406 const EVP_MD *md;
407 EVP_CIPHER *evp_cipher = NULL;
408 const EVP_CIPHER *cipher = NULL;
409 EVP_CIPHER_CTX *evp_ctx = NULL;
410 X509_ALGOR *enc_alg = NULL;
411 STACK_OF(X509_ALGOR) *md_sk = NULL;
412 STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL;
413 PKCS7_RECIP_INFO *ri = NULL;
414 unsigned char *ek = NULL, *tkey = NULL;
415 int eklen = 0, tkeylen = 0;
416 const char *name;
417 const PKCS7_CTX *p7_ctx;
418
419 if (p7 == NULL) {
420 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER);
421 return NULL;
422 }
423
424 p7_ctx = pkcs7_get0_ctx(p7);
425
426 if (p7->d.ptr == NULL) {
427 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
428 return NULL;
429 }
430
431 i = OBJ_obj2nid(p7->type);
432 p7->state = PKCS7_S_HEADER;
433
434 switch (i) {
435 case NID_pkcs7_signed:
436 /*
437 * p7->d.sign->contents is a PKCS7 structure consisting of a contentType
438 * field and optional content.
439 * data_body is NULL if that structure has no (=detached) content
440 * or if the contentType is wrong (i.e., not "data").
441 */
442 data_body = PKCS7_get_octet_string(p7->d.sign->contents);
443 if (!PKCS7_is_detached(p7) && data_body == NULL) {
444 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
445 PKCS7_R_INVALID_SIGNED_DATA_TYPE);
446 goto err;
447 }
448 md_sk = p7->d.sign->md_algs;
449 break;
450 case NID_pkcs7_signedAndEnveloped:
451 rsk = p7->d.signed_and_enveloped->recipientinfo;
452 md_sk = p7->d.signed_and_enveloped->md_algs;
453 /* data_body is NULL if the optional EncryptedContent is missing. */
454 data_body = p7->d.signed_and_enveloped->enc_data->enc_data;
455 enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm;
456
457 name = OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm));
458
459 (void)ERR_set_mark();
460 evp_cipher = EVP_CIPHER_fetch(p7_ctx->libctx, name, p7_ctx->propq);
461 if (evp_cipher != NULL)
462 cipher = evp_cipher;
463 else
464 cipher = EVP_get_cipherbyname(name);
465
466 if (cipher == NULL) {
467 (void)ERR_clear_last_mark();
468 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
469 PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
470 goto err;
471 }
472 (void)ERR_pop_to_mark();
473 break;
474 case NID_pkcs7_enveloped:
475 rsk = p7->d.enveloped->recipientinfo;
476 enc_alg = p7->d.enveloped->enc_data->algorithm;
477 /* data_body is NULL if the optional EncryptedContent is missing. */
478 data_body = p7->d.enveloped->enc_data->enc_data;
479 name = OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm));
480
481 (void)ERR_set_mark();
482 evp_cipher = EVP_CIPHER_fetch(p7_ctx->libctx, name, p7_ctx->propq);
483 if (evp_cipher != NULL)
484 cipher = evp_cipher;
485 else
486 cipher = EVP_get_cipherbyname(name);
487
488 if (cipher == NULL) {
489 (void)ERR_clear_last_mark();
490 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
491 PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
492 goto err;
493 }
494 (void)ERR_pop_to_mark();
495 break;
496 default:
497 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
498 goto err;
499 }
500
501 /* Detached content must be supplied via in_bio instead. */
502 if (data_body == NULL && in_bio == NULL) {
503 PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT);
504 goto err;
505 }
506
507 /* We will be checking the signature */
508 if (md_sk != NULL) {
509 for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) {
510 xa = sk_X509_ALGOR_value(md_sk, i);
511 if ((btmp = BIO_new(BIO_f_md())) == NULL) {
512 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
513 goto err;
514 }
515
516 name = OBJ_nid2sn(OBJ_obj2nid(xa->algorithm));
517
518 (void)ERR_set_mark();
519 evp_md = EVP_MD_fetch(p7_ctx->libctx, name, p7_ctx->propq);
520 if (evp_md != NULL)
521 md = evp_md;
522 else
523 md = EVP_get_digestbyname(name);
524
525 if (md == NULL) {
526 (void)ERR_clear_last_mark();
527 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
528 PKCS7_R_UNKNOWN_DIGEST_TYPE);
529 goto err;
530 }
531 (void)ERR_pop_to_mark();
532
533 BIO_set_md(btmp, md);
534 EVP_MD_free(evp_md);
535 if (out == NULL)
536 out = btmp;
537 else
538 BIO_push(out, btmp);
539 btmp = NULL;
540 }
541 }
542
543 if (cipher != NULL) {
544 if ((etmp = BIO_new(BIO_f_cipher())) == NULL) {
545 PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB);
546 goto err;
547 }
548
549 /*
550 * It was encrypted, we need to decrypt the secret key with the
551 * private key
552 */
553
554 /*
555 * Find the recipientInfo which matches the passed certificate (if
556 * any)
557 */
558
559 if (pcert) {
560 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
561 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
562 if (!pkcs7_cmp_ri(ri, pcert))
563 break;
564 ri = NULL;
565 }
566 if (ri == NULL) {
567 PKCS7err(PKCS7_F_PKCS7_DATADECODE,
568 PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
569 goto err;
570 }
571 }
572
573 /* If we haven't got a certificate try each ri in turn */
574 if (pcert == NULL) {
575 /*
576 * Always attempt to decrypt all rinfo even after success as a
577 * defence against MMA timing attacks.
578 */
579 for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) {
580 ri = sk_PKCS7_RECIP_INFO_value(rsk, i);
581 ri->ctx = p7_ctx;
582 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey,
583 EVP_CIPHER_key_length(cipher)) < 0)
584 goto err;
585 ERR_clear_error();
586 }
587 } else {
588 ri->ctx = p7_ctx;
589 /* Only exit on fatal errors, not decrypt failure */
590 if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey, 0) < 0)
591 goto err;
592 ERR_clear_error();
593 }
594
595 evp_ctx = NULL;
596 BIO_get_cipher_ctx(etmp, &evp_ctx);
597 if (EVP_CipherInit_ex(evp_ctx, cipher, NULL, NULL, NULL, 0) <= 0)
598 goto err;
599 if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0)
600 goto err;
601 /* Generate random key as MMA defence */
602 len = EVP_CIPHER_CTX_key_length(evp_ctx);
603 if (len <= 0)
604 goto err;
605 tkeylen = (size_t)len;
606 tkey = OPENSSL_malloc(tkeylen);
607 if (tkey == NULL)
608 goto err;
609 if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0)
610 goto err;
611 if (ek == NULL) {
612 ek = tkey;
613 eklen = tkeylen;
614 tkey = NULL;
615 }
616
617 if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) {
618 /*
619 * Some S/MIME clients don't use the same key and effective key
620 * length. The key length is determined by the size of the
621 * decrypted RSA key.
622 */
623 if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) {
624 /* Use random key as MMA defence */
625 OPENSSL_clear_free(ek, eklen);
626 ek = tkey;
627 eklen = tkeylen;
628 tkey = NULL;
629 }
630 }
631 /* Clear errors so we don't leak information useful in MMA */
632 ERR_clear_error();
633 if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0)
634 goto err;
635
636 OPENSSL_clear_free(ek, eklen);
637 ek = NULL;
638 OPENSSL_clear_free(tkey, tkeylen);
639 tkey = NULL;
640
641 if (out == NULL)
642 out = etmp;
643 else
644 BIO_push(out, etmp);
645 etmp = NULL;
646 }
647 if (in_bio != NULL) {
648 bio = in_bio;
649 } else {
650 if (data_body->length > 0)
651 bio = BIO_new_mem_buf(data_body->data, data_body->length);
652 else {
653 bio = BIO_new(BIO_s_mem());
654 if (bio == NULL)
655 goto err;
656 BIO_set_mem_eof_return(bio, 0);
657 }
658 if (bio == NULL)
659 goto err;
660 }
661 BIO_push(out, bio);
662 bio = NULL;
663 EVP_CIPHER_free(evp_cipher);
664 return out;
665
666 err:
667 EVP_CIPHER_free(evp_cipher);
668 OPENSSL_clear_free(ek, eklen);
669 OPENSSL_clear_free(tkey, tkeylen);
670 BIO_free_all(out);
671 BIO_free_all(btmp);
672 BIO_free_all(etmp);
673 BIO_free_all(bio);
674 return NULL;
675 }
676
677 static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid)
678 {
679 for (;;) {
680 bio = BIO_find_type(bio, BIO_TYPE_MD);
681 if (bio == NULL) {
682 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST,
683 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
684 return NULL;
685 }
686 BIO_get_md_ctx(bio, pmd);
687 if (*pmd == NULL) {
688 PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR);
689 return NULL;
690 }
691 if (EVP_MD_CTX_type(*pmd) == nid)
692 return bio;
693 bio = BIO_next(bio);
694 }
695 return NULL;
696 }
697
698 static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
699 {
700 unsigned char md_data[EVP_MAX_MD_SIZE];
701 unsigned int md_len;
702
703 /* Add signing time if not already present */
704 if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
705 if (!PKCS7_add0_attrib_signing_time(si, NULL)) {
706 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
707 return 0;
708 }
709 }
710
711 /* Add digest */
712 if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) {
713 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
714 return 0;
715 }
716 if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) {
717 PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
718 return 0;
719 }
720
721 /* Now sign the attributes */
722 if (!PKCS7_SIGNER_INFO_sign(si))
723 return 0;
724
725 return 1;
726 }
727
728 int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
729 {
730 int ret = 0;
731 int i, j;
732 BIO *btmp;
733 PKCS7_SIGNER_INFO *si;
734 EVP_MD_CTX *mdc, *ctx_tmp;
735 STACK_OF(X509_ATTRIBUTE) *sk;
736 STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL;
737 ASN1_OCTET_STRING *os = NULL;
738 const PKCS7_CTX *p7_ctx;
739
740 if (p7 == NULL) {
741 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER);
742 return 0;
743 }
744
745 p7_ctx = pkcs7_get0_ctx(p7);
746
747 if (p7->d.ptr == NULL) {
748 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT);
749 return 0;
750 }
751
752 ctx_tmp = EVP_MD_CTX_new();
753 if (ctx_tmp == NULL) {
754 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
755 return 0;
756 }
757
758 i = OBJ_obj2nid(p7->type);
759 p7->state = PKCS7_S_HEADER;
760
761 switch (i) {
762 case NID_pkcs7_data:
763 os = p7->d.data;
764 break;
765 case NID_pkcs7_signedAndEnveloped:
766 /* XXXXXXXXXXXXXXXX */
767 si_sk = p7->d.signed_and_enveloped->signer_info;
768 os = p7->d.signed_and_enveloped->enc_data->enc_data;
769 if (os == NULL) {
770 os = ASN1_OCTET_STRING_new();
771 if (os == NULL) {
772 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
773 goto err;
774 }
775 p7->d.signed_and_enveloped->enc_data->enc_data = os;
776 }
777 break;
778 case NID_pkcs7_enveloped:
779 /* XXXXXXXXXXXXXXXX */
780 os = p7->d.enveloped->enc_data->enc_data;
781 if (os == NULL) {
782 os = ASN1_OCTET_STRING_new();
783 if (os == NULL) {
784 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE);
785 goto err;
786 }
787 p7->d.enveloped->enc_data->enc_data = os;
788 }
789 break;
790 case NID_pkcs7_signed:
791 si_sk = p7->d.sign->signer_info;
792 os = PKCS7_get_octet_string(p7->d.sign->contents);
793 /* If detached data then the content is excluded */
794 if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
795 ASN1_OCTET_STRING_free(os);
796 os = NULL;
797 p7->d.sign->contents->d.data = NULL;
798 }
799 break;
800
801 case NID_pkcs7_digest:
802 os = PKCS7_get_octet_string(p7->d.digest->contents);
803 /* If detached data then the content is excluded */
804 if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) {
805 ASN1_OCTET_STRING_free(os);
806 os = NULL;
807 p7->d.digest->contents->d.data = NULL;
808 }
809 break;
810
811 default:
812 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
813 goto err;
814 }
815
816 if (si_sk != NULL) {
817 for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) {
818 si = sk_PKCS7_SIGNER_INFO_value(si_sk, i);
819 if (si->pkey == NULL)
820 continue;
821
822 j = OBJ_obj2nid(si->digest_alg->algorithm);
823
824 btmp = bio;
825
826 btmp = PKCS7_find_digest(&mdc, btmp, j);
827
828 if (btmp == NULL)
829 goto err;
830
831 /*
832 * We now have the EVP_MD_CTX, lets do the signing.
833 */
834 if (!EVP_MD_CTX_copy_ex(ctx_tmp, mdc))
835 goto err;
836
837 sk = si->auth_attr;
838
839 /*
840 * If there are attributes, we add the digest attribute and only
841 * sign the attributes
842 */
843 if (sk_X509_ATTRIBUTE_num(sk) > 0) {
844 if (!do_pkcs7_signed_attrib(si, ctx_tmp))
845 goto err;
846 } else {
847 unsigned char *abuf = NULL;
848 unsigned int abuflen;
849 abuflen = EVP_PKEY_size(si->pkey);
850 abuf = OPENSSL_malloc(abuflen);
851 if (abuf == NULL)
852 goto err;
853
854 if (!EVP_SignFinal_with_libctx(ctx_tmp, abuf, &abuflen, si->pkey,
855 p7_ctx->libctx, p7_ctx->propq)) {
856 OPENSSL_free(abuf);
857 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB);
858 goto err;
859 }
860 ASN1_STRING_set0(si->enc_digest, abuf, abuflen);
861 }
862 }
863 } else if (i == NID_pkcs7_digest) {
864 unsigned char md_data[EVP_MAX_MD_SIZE];
865 unsigned int md_len;
866 if (!PKCS7_find_digest(&mdc, bio,
867 OBJ_obj2nid(p7->d.digest->md->algorithm)))
868 goto err;
869 if (!EVP_DigestFinal_ex(mdc, md_data, &md_len))
870 goto err;
871 if (!ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len))
872 goto err;
873 }
874
875 if (!PKCS7_is_detached(p7)) {
876 /*
877 * NOTE(emilia): I think we only reach os == NULL here because detached
878 * digested data support is broken.
879 */
880 if (os == NULL)
881 goto err;
882 if (!(os->flags & ASN1_STRING_FLAG_NDEF)) {
883 char *cont;
884 long contlen;
885 btmp = BIO_find_type(bio, BIO_TYPE_MEM);
886 if (btmp == NULL) {
887 PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
888 goto err;
889 }
890 contlen = BIO_get_mem_data(btmp, &cont);
891 /*
892 * Mark the BIO read only then we can use its copy of the data
893 * instead of making an extra copy.
894 */
895 BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
896 BIO_set_mem_eof_return(btmp, 0);
897 ASN1_STRING_set0(os, (unsigned char *)cont, contlen);
898 }
899 }
900 ret = 1;
901 err:
902 EVP_MD_CTX_free(ctx_tmp);
903 return ret;
904 }
905
906 int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si)
907 {
908 EVP_MD_CTX *mctx;
909 EVP_PKEY_CTX *pctx = NULL;
910 unsigned char *abuf = NULL;
911 int alen;
912 size_t siglen;
913 const EVP_MD *md = NULL;
914 const PKCS7_CTX *ctx = si->ctx;
915
916 md = EVP_get_digestbyobj(si->digest_alg->algorithm);
917 if (md == NULL)
918 return 0;
919
920 mctx = EVP_MD_CTX_new();
921 if (mctx == NULL) {
922 PKCS7err(0, ERR_R_MALLOC_FAILURE);
923 goto err;
924 }
925
926 if (EVP_DigestSignInit_with_libctx(mctx, &pctx,
927 EVP_MD_name(md), ctx->libctx, ctx->propq,
928 si->pkey) <= 0)
929 goto err;
930
931 /*
932 * TODO(3.0): This causes problems when providers are in use, so disabled
933 * for now. Can we get rid of this completely? AFAICT this ctrl has never
934 * been used since it was first put in. All internal implementations just
935 * return 1 and ignore this ctrl and have always done so by the looks of
936 * things. To fix this we could convert this ctrl into a param, which would
937 * require us to send all the signer info data as a set of params...but that
938 * is non-trivial and since this isn't used by anything it may be better
939 * just to remove it. The original commit that added it had this
940 * justification in CHANGES:
941 *
942 * "During PKCS7 signing pass the PKCS7 SignerInfo structure to the
943 * EVP_PKEY_METHOD before and after signing via the
944 * EVP_PKEY_CTRL_PKCS7_SIGN ctrl. It can then customise the structure
945 * before and/or after signing if necessary."
946 */
947 #if 0
948 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
949 EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) {
950 PKCS7err(0, PKCS7_R_CTRL_ERROR);
951 goto err;
952 }
953 #endif
954
955 alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf,
956 ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
957 if (!abuf)
958 goto err;
959 if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
960 goto err;
961 OPENSSL_free(abuf);
962 abuf = NULL;
963 if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
964 goto err;
965 abuf = OPENSSL_malloc(siglen);
966 if (abuf == NULL)
967 goto err;
968 if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
969 goto err;
970
971 /*
972 * TODO(3.0): This causes problems when providers are in use, so disabled
973 * for now. Can we get rid of this completely? AFAICT this ctrl has never
974 * been used since it was first put in. All internal implementations just
975 * return 1 and ignore this ctrl and have always done so by the looks of
976 * things. To fix this we could convert this ctrl into a param, which would
977 * require us to send all the signer info data as a set of params...but that
978 * is non-trivial and since this isn't used by anything it may be better
979 * just to remove it. The original commit that added it had this
980 * justification in CHANGES:
981 *
982 * "During PKCS7 signing pass the PKCS7 SignerInfo structure to the
983 * EVP_PKEY_METHOD before and after signing via the
984 * EVP_PKEY_CTRL_PKCS7_SIGN ctrl. It can then customise the structure
985 * before and/or after signing if necessary."
986 */
987 #if 0
988 if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
989 EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) {
990 PKCS7err(0, PKCS7_R_CTRL_ERROR);
991 goto err;
992 }
993 #endif
994
995 EVP_MD_CTX_free(mctx);
996
997 ASN1_STRING_set0(si->enc_digest, abuf, siglen);
998
999 return 1;
1000
1001 err:
1002 OPENSSL_free(abuf);
1003 EVP_MD_CTX_free(mctx);
1004 return 0;
1005 }
1006
1007 int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio,
1008 PKCS7 *p7, PKCS7_SIGNER_INFO *si)
1009 {
1010 PKCS7_ISSUER_AND_SERIAL *ias;
1011 int ret = 0, i;
1012 STACK_OF(X509) *cert;
1013 X509 *x509;
1014
1015 if (p7 == NULL) {
1016 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER);
1017 return 0;
1018 }
1019
1020 if (p7->d.ptr == NULL) {
1021 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT);
1022 return 0;
1023 }
1024
1025 if (PKCS7_type_is_signed(p7)) {
1026 cert = p7->d.sign->cert;
1027 } else if (PKCS7_type_is_signedAndEnveloped(p7)) {
1028 cert = p7->d.signed_and_enveloped->cert;
1029 } else {
1030 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
1031 goto err;
1032 }
1033 /* XXXXXXXXXXXXXXXXXXXXXXX */
1034 ias = si->issuer_and_serial;
1035
1036 x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial);
1037
1038 /* were we able to find the cert in passed to us */
1039 if (x509 == NULL) {
1040 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY,
1041 PKCS7_R_UNABLE_TO_FIND_CERTIFICATE);
1042 goto err;
1043 }
1044
1045 /* Lets verify */
1046 if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) {
1047 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
1048 goto err;
1049 }
1050 X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN);
1051 i = X509_verify_cert(ctx);
1052 if (i <= 0) {
1053 PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB);
1054 X509_STORE_CTX_cleanup(ctx);
1055 goto err;
1056 }
1057 X509_STORE_CTX_cleanup(ctx);
1058
1059 return PKCS7_signatureVerify(bio, p7, si, x509);
1060 err:
1061 return ret;
1062 }
1063
1064 int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
1065 X509 *x509)
1066 {
1067 ASN1_OCTET_STRING *os;
1068 EVP_MD_CTX *mdc_tmp, *mdc;
1069 const EVP_MD *md;
1070 EVP_MD *fetched_md = NULL;
1071 int ret = 0, i;
1072 int md_type;
1073 STACK_OF(X509_ATTRIBUTE) *sk;
1074 BIO *btmp;
1075 EVP_PKEY *pkey;
1076 const PKCS7_CTX *ctx = pkcs7_get0_ctx(p7);
1077
1078 mdc_tmp = EVP_MD_CTX_new();
1079 if (mdc_tmp == NULL) {
1080 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_MALLOC_FAILURE);
1081 goto err;
1082 }
1083
1084 if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) {
1085 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE);
1086 goto err;
1087 }
1088
1089 md_type = OBJ_obj2nid(si->digest_alg->algorithm);
1090
1091 btmp = bio;
1092 for (;;) {
1093 if ((btmp == NULL) ||
1094 ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) {
1095 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
1096 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
1097 goto err;
1098 }
1099 BIO_get_md_ctx(btmp, &mdc);
1100 if (mdc == NULL) {
1101 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR);
1102 goto err;
1103 }
1104 if (EVP_MD_CTX_type(mdc) == md_type)
1105 break;
1106 /*
1107 * Workaround for some broken clients that put the signature OID
1108 * instead of the digest OID in digest_alg->algorithm
1109 */
1110 if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type)
1111 break;
1112 btmp = BIO_next(btmp);
1113 }
1114
1115 /*
1116 * mdc is the digest ctx that we want, unless there are attributes, in
1117 * which case the digest is the signed attributes
1118 */
1119 if (!EVP_MD_CTX_copy_ex(mdc_tmp, mdc))
1120 goto err;
1121
1122 sk = si->auth_attr;
1123 if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) {
1124 unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL;
1125 unsigned int md_len;
1126 int alen;
1127 ASN1_OCTET_STRING *message_digest;
1128
1129 if (!EVP_DigestFinal_ex(mdc_tmp, md_dat, &md_len))
1130 goto err;
1131 message_digest = PKCS7_digest_from_attributes(sk);
1132 if (!message_digest) {
1133 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY,
1134 PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
1135 goto err;
1136 }
1137 if ((message_digest->length != (int)md_len) ||
1138 (memcmp(message_digest->data, md_dat, md_len))) {
1139 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE);
1140 ret = -1;
1141 goto err;
1142 }
1143
1144 (void)ERR_set_mark();
1145 fetched_md = EVP_MD_fetch(ctx->libctx, OBJ_nid2sn(md_type), ctx->propq);
1146
1147 if (fetched_md != NULL)
1148 md = fetched_md;
1149 else
1150 md = EVP_get_digestbynid(md_type);
1151
1152 if (md == NULL || !EVP_VerifyInit_ex(mdc_tmp, md, NULL)) {
1153 (void)ERR_clear_last_mark();
1154 goto err;
1155 }
1156 (void)ERR_pop_to_mark();
1157
1158 alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
1159 ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY));
1160 if (alen <= 0) {
1161 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB);
1162 ret = -1;
1163 goto err;
1164 }
1165 if (!EVP_VerifyUpdate(mdc_tmp, abuf, alen))
1166 goto err;
1167
1168 OPENSSL_free(abuf);
1169 }
1170
1171 os = si->enc_digest;
1172 pkey = X509_get0_pubkey(x509);
1173 if (pkey == NULL) {
1174 ret = -1;
1175 goto err;
1176 }
1177
1178 i = EVP_VerifyFinal_with_libctx(mdc_tmp, os->data, os->length, pkey,
1179 ctx->libctx, ctx->propq);
1180 if (i <= 0) {
1181 PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
1182 ret = -1;
1183 goto err;
1184 }
1185 ret = 1;
1186 err:
1187 EVP_MD_CTX_free(mdc_tmp);
1188 EVP_MD_free(fetched_md);
1189 return ret;
1190 }
1191
1192 PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx)
1193 {
1194 STACK_OF(PKCS7_RECIP_INFO) *rsk;
1195 PKCS7_RECIP_INFO *ri;
1196 int i;
1197
1198 i = OBJ_obj2nid(p7->type);
1199 if (i != NID_pkcs7_signedAndEnveloped)
1200 return NULL;
1201 if (p7->d.signed_and_enveloped == NULL)
1202 return NULL;
1203 rsk = p7->d.signed_and_enveloped->recipientinfo;
1204 if (rsk == NULL)
1205 return NULL;
1206 if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx)
1207 return NULL;
1208 ri = sk_PKCS7_RECIP_INFO_value(rsk, idx);
1209 return ri->issuer_and_serial;
1210 }
1211
1212 ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid)
1213 {
1214 return get_attribute(si->auth_attr, nid);
1215 }
1216
1217 ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid)
1218 {
1219 return get_attribute(si->unauth_attr, nid);
1220 }
1221
1222 static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid)
1223 {
1224 int idx;
1225 X509_ATTRIBUTE *xa;
1226 idx = X509at_get_attr_by_NID(sk, nid, -1);
1227 xa = X509at_get_attr(sk, idx);
1228 return X509_ATTRIBUTE_get0_type(xa, 0);
1229 }
1230
1231 ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk)
1232 {
1233 ASN1_TYPE *astype;
1234 if ((astype = get_attribute(sk, NID_pkcs9_messageDigest)) == NULL)
1235 return NULL;
1236 return astype->value.octet_string;
1237 }
1238
1239 int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si,
1240 STACK_OF(X509_ATTRIBUTE) *sk)
1241 {
1242 int i;
1243
1244 sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free);
1245 p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk);
1246 if (p7si->auth_attr == NULL)
1247 return 0;
1248 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1249 if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i,
1250 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
1251 (sk, i))))
1252 == NULL)
1253 return 0;
1254 }
1255 return 1;
1256 }
1257
1258 int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si,
1259 STACK_OF(X509_ATTRIBUTE) *sk)
1260 {
1261 int i;
1262
1263 sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free);
1264 p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk);
1265 if (p7si->unauth_attr == NULL)
1266 return 0;
1267 for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
1268 if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i,
1269 X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value
1270 (sk, i))))
1271 == NULL)
1272 return 0;
1273 }
1274 return 1;
1275 }
1276
1277 int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
1278 void *value)
1279 {
1280 return add_attribute(&(p7si->auth_attr), nid, atrtype, value);
1281 }
1282
1283 int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype,
1284 void *value)
1285 {
1286 return add_attribute(&(p7si->unauth_attr), nid, atrtype, value);
1287 }
1288
1289 static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype,
1290 void *value)
1291 {
1292 X509_ATTRIBUTE *attr = NULL;
1293
1294 if (*sk == NULL) {
1295 if ((*sk = sk_X509_ATTRIBUTE_new_null()) == NULL)
1296 return 0;
1297 new_attrib:
1298 if ((attr = X509_ATTRIBUTE_create(nid, atrtype, value)) == NULL)
1299 return 0;
1300 if (!sk_X509_ATTRIBUTE_push(*sk, attr)) {
1301 X509_ATTRIBUTE_free(attr);
1302 return 0;
1303 }
1304 } else {
1305 int i;
1306
1307 for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) {
1308 attr = sk_X509_ATTRIBUTE_value(*sk, i);
1309 if (OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attr)) == nid) {
1310 X509_ATTRIBUTE_free(attr);
1311 attr = X509_ATTRIBUTE_create(nid, atrtype, value);
1312 if (attr == NULL)
1313 return 0;
1314 if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) {
1315 X509_ATTRIBUTE_free(attr);
1316 return 0;
1317 }
1318 goto end;
1319 }
1320 }
1321 goto new_attrib;
1322 }
1323 end:
1324 return 1;
1325 }