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