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