Merge branch 'vendor/OPENSSL'
[dragonfly.git] / crypto / openssl / crypto / cms / cms_sd.c
1 /* crypto/cms/cms_sd.c */
2 /*
3  * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
4  * project.
5  */
6 /* ====================================================================
7  * Copyright (c) 2008 The OpenSSL Project.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  *
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  *
21  * 3. All advertising materials mentioning features or use of this
22  *    software must display the following acknowledgment:
23  *    "This product includes software developed by the OpenSSL Project
24  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25  *
26  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
27  *    endorse or promote products derived from this software without
28  *    prior written permission. For written permission, please contact
29  *    licensing@OpenSSL.org.
30  *
31  * 5. Products derived from this software may not be called "OpenSSL"
32  *    nor may "OpenSSL" appear in their names without prior written
33  *    permission of the OpenSSL Project.
34  *
35  * 6. Redistributions of any form whatsoever must retain the following
36  *    acknowledgment:
37  *    "This product includes software developed by the OpenSSL Project
38  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
41  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
43  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
46  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
47  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
49  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
50  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
51  * OF THE POSSIBILITY OF SUCH DAMAGE.
52  * ====================================================================
53  */
54
55 #include "cryptlib.h"
56 #include <openssl/asn1t.h>
57 #include <openssl/pem.h>
58 #include <openssl/x509v3.h>
59 #include <openssl/err.h>
60 #include <openssl/cms.h>
61 #include "cms_lcl.h"
62 #include "asn1_locl.h"
63
64 /* CMS SignedData Utilities */
65
66 DECLARE_ASN1_ITEM(CMS_SignedData)
67
68 static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
69 {
70     if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) {
71         CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
72         return NULL;
73     }
74     return cms->d.signedData;
75 }
76
77 static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
78 {
79     if (cms->d.other == NULL) {
80         cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
81         if (!cms->d.signedData) {
82             CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);
83             return NULL;
84         }
85         cms->d.signedData->version = 1;
86         cms->d.signedData->encapContentInfo->eContentType =
87             OBJ_nid2obj(NID_pkcs7_data);
88         cms->d.signedData->encapContentInfo->partial = 1;
89         ASN1_OBJECT_free(cms->contentType);
90         cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
91         return cms->d.signedData;
92     }
93     return cms_get0_signed(cms);
94 }
95
96 /* Just initialize SignedData e.g. for certs only structure */
97
98 int CMS_SignedData_init(CMS_ContentInfo *cms)
99 {
100     if (cms_signed_data_init(cms))
101         return 1;
102     else
103         return 0;
104 }
105
106 /* Check structures and fixup version numbers (if necessary) */
107
108 static void cms_sd_set_version(CMS_SignedData *sd)
109 {
110     int i;
111     CMS_CertificateChoices *cch;
112     CMS_RevocationInfoChoice *rch;
113     CMS_SignerInfo *si;
114
115     for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) {
116         cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
117         if (cch->type == CMS_CERTCHOICE_OTHER) {
118             if (sd->version < 5)
119                 sd->version = 5;
120         } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
121             if (sd->version < 4)
122                 sd->version = 4;
123         } else if (cch->type == CMS_CERTCHOICE_V1ACERT) {
124             if (sd->version < 3)
125                 sd->version = 3;
126         }
127     }
128
129     for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) {
130         rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
131         if (rch->type == CMS_REVCHOICE_OTHER) {
132             if (sd->version < 5)
133                 sd->version = 5;
134         }
135     }
136
137     if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
138         && (sd->version < 3))
139         sd->version = 3;
140
141     for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
142         si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
143         if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
144             if (si->version < 3)
145                 si->version = 3;
146             if (sd->version < 3)
147                 sd->version = 3;
148         } else if (si->version < 1)
149             si->version = 1;
150     }
151
152     if (sd->version < 1)
153         sd->version = 1;
154
155 }
156
157 /* Copy an existing messageDigest value */
158
159 static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
160 {
161     STACK_OF(CMS_SignerInfo) *sinfos;
162     CMS_SignerInfo *sitmp;
163     int i;
164     sinfos = CMS_get0_SignerInfos(cms);
165     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
166         ASN1_OCTET_STRING *messageDigest;
167         sitmp = sk_CMS_SignerInfo_value(sinfos, i);
168         if (sitmp == si)
169             continue;
170         if (CMS_signed_get_attr_count(sitmp) < 0)
171             continue;
172         if (OBJ_cmp(si->digestAlgorithm->algorithm,
173                     sitmp->digestAlgorithm->algorithm))
174             continue;
175         messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
176                                                     OBJ_nid2obj
177                                                     (NID_pkcs9_messageDigest),
178                                                     -3, V_ASN1_OCTET_STRING);
179         if (!messageDigest) {
180             CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,
181                    CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
182             return 0;
183         }
184
185         if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
186                                         V_ASN1_OCTET_STRING,
187                                         messageDigest, -1))
188             return 1;
189         else
190             return 0;
191     }
192     CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);
193     return 0;
194 }
195
196 int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
197 {
198     switch (type) {
199     case CMS_SIGNERINFO_ISSUER_SERIAL:
200         sid->d.issuerAndSerialNumber =
201             M_ASN1_new_of(CMS_IssuerAndSerialNumber);
202         if (!sid->d.issuerAndSerialNumber)
203             goto merr;
204         if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer,
205                            X509_get_issuer_name(cert)))
206             goto merr;
207         if (!ASN1_STRING_copy(sid->d.issuerAndSerialNumber->serialNumber,
208                               X509_get_serialNumber(cert)))
209             goto merr;
210         break;
211
212     case CMS_SIGNERINFO_KEYIDENTIFIER:
213         if (!cert->skid) {
214             CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER,
215                    CMS_R_CERTIFICATE_HAS_NO_KEYID);
216             return 0;
217         }
218         sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid);
219         if (!sid->d.subjectKeyIdentifier)
220             goto merr;
221         break;
222
223     default:
224         CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);
225         return 0;
226     }
227
228     sid->type = type;
229
230     return 1;
231
232  merr:
233     CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE);
234     return 0;
235
236 }
237
238 int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
239                                         ASN1_OCTET_STRING **keyid,
240                                         X509_NAME **issuer,
241                                         ASN1_INTEGER **sno)
242 {
243     if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
244         if (issuer)
245             *issuer = sid->d.issuerAndSerialNumber->issuer;
246         if (sno)
247             *sno = sid->d.issuerAndSerialNumber->serialNumber;
248     } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
249         if (keyid)
250             *keyid = sid->d.subjectKeyIdentifier;
251     } else
252         return 0;
253     return 1;
254 }
255
256 int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
257 {
258     int ret;
259     if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
260         ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer,
261                             X509_get_issuer_name(cert));
262         if (ret)
263             return ret;
264         return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber,
265                                 X509_get_serialNumber(cert));
266     } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
267         X509_check_purpose(cert, -1, -1);
268         if (!cert->skid)
269             return -1;
270         return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier, cert->skid);
271     } else
272         return -1;
273 }
274
275 CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
276                                 X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
277                                 unsigned int flags)
278 {
279     CMS_SignedData *sd;
280     CMS_SignerInfo *si = NULL;
281     X509_ALGOR *alg;
282     int i, type;
283     if (!X509_check_private_key(signer, pk)) {
284         CMSerr(CMS_F_CMS_ADD1_SIGNER,
285                CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
286         return NULL;
287     }
288     sd = cms_signed_data_init(cms);
289     if (!sd)
290         goto err;
291     si = M_ASN1_new_of(CMS_SignerInfo);
292     if (!si)
293         goto merr;
294     X509_check_purpose(signer, -1, -1);
295
296     CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);
297     CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
298
299     si->pkey = pk;
300     si->signer = signer;
301
302     if (flags & CMS_USE_KEYID) {
303         si->version = 3;
304         if (sd->version < 3)
305             sd->version = 3;
306         type = CMS_SIGNERINFO_KEYIDENTIFIER;
307     } else {
308         type = CMS_SIGNERINFO_ISSUER_SERIAL;
309         si->version = 1;
310     }
311
312     if (!cms_set1_SignerIdentifier(si->sid, signer, type))
313         goto err;
314
315     if (md == NULL) {
316         int def_nid;
317         if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
318             goto err;
319         md = EVP_get_digestbynid(def_nid);
320         if (md == NULL) {
321             CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST);
322             goto err;
323         }
324     }
325
326     if (!md) {
327         CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET);
328         goto err;
329     }
330
331     cms_DigestAlgorithm_set(si->digestAlgorithm, md);
332
333     /* See if digest is present in digestAlgorithms */
334     for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
335         ASN1_OBJECT *aoid;
336         alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
337         X509_ALGOR_get0(&aoid, NULL, NULL, alg);
338         if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
339             break;
340     }
341
342     if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
343         alg = X509_ALGOR_new();
344         if (!alg)
345             goto merr;
346         cms_DigestAlgorithm_set(alg, md);
347         if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) {
348             X509_ALGOR_free(alg);
349             goto merr;
350         }
351     }
352
353     if (pk->ameth && pk->ameth->pkey_ctrl) {
354         i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN, 0, si);
355         if (i == -2) {
356             CMSerr(CMS_F_CMS_ADD1_SIGNER,
357                    CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
358             goto err;
359         }
360         if (i <= 0) {
361             CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE);
362             goto err;
363         }
364     }
365
366     if (!(flags & CMS_NOATTR)) {
367         /*
368          * Initialialize signed attributes strutucture so other attributes
369          * such as signing time etc are added later even if we add none here.
370          */
371         if (!si->signedAttrs) {
372             si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
373             if (!si->signedAttrs)
374                 goto merr;
375         }
376
377         if (!(flags & CMS_NOSMIMECAP)) {
378             STACK_OF(X509_ALGOR) *smcap = NULL;
379             i = CMS_add_standard_smimecap(&smcap);
380             if (i)
381                 i = CMS_add_smimecap(si, smcap);
382             sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
383             if (!i)
384                 goto merr;
385         }
386         if (flags & CMS_REUSE_DIGEST) {
387             if (!cms_copy_messageDigest(cms, si))
388                 goto err;
389             if (!(flags & CMS_PARTIAL) && !CMS_SignerInfo_sign(si))
390                 goto err;
391         }
392     }
393
394     if (!(flags & CMS_NOCERTS)) {
395         /* NB ignore -1 return for duplicate cert */
396         if (!CMS_add1_cert(cms, signer))
397             goto merr;
398     }
399
400     if (!sd->signerInfos)
401         sd->signerInfos = sk_CMS_SignerInfo_new_null();
402     if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si))
403         goto merr;
404
405     return si;
406
407  merr:
408     CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);
409  err:
410     if (si)
411         M_ASN1_free_of(si, CMS_SignerInfo);
412     return NULL;
413
414 }
415
416 static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
417 {
418     ASN1_TIME *tt;
419     int r = 0;
420     if (t)
421         tt = t;
422     else
423         tt = X509_gmtime_adj(NULL, 0);
424
425     if (!tt)
426         goto merr;
427
428     if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
429                                     tt->type, tt, -1) <= 0)
430         goto merr;
431
432     r = 1;
433
434  merr:
435
436     if (!t)
437         ASN1_TIME_free(tt);
438
439     if (!r)
440         CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);
441
442     return r;
443
444 }
445
446 STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
447 {
448     CMS_SignedData *sd;
449     sd = cms_get0_signed(cms);
450     if (!sd)
451         return NULL;
452     return sd->signerInfos;
453 }
454
455 STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
456 {
457     STACK_OF(X509) *signers = NULL;
458     STACK_OF(CMS_SignerInfo) *sinfos;
459     CMS_SignerInfo *si;
460     int i;
461     sinfos = CMS_get0_SignerInfos(cms);
462     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
463         si = sk_CMS_SignerInfo_value(sinfos, i);
464         if (si->signer) {
465             if (!signers) {
466                 signers = sk_X509_new_null();
467                 if (!signers)
468                     return NULL;
469             }
470             if (!sk_X509_push(signers, si->signer)) {
471                 sk_X509_free(signers);
472                 return NULL;
473             }
474         }
475     }
476     return signers;
477 }
478
479 void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
480 {
481     if (signer) {
482         CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);
483         if (si->pkey)
484             EVP_PKEY_free(si->pkey);
485         si->pkey = X509_get_pubkey(signer);
486     }
487     if (si->signer)
488         X509_free(si->signer);
489     si->signer = signer;
490 }
491
492 int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
493                                   ASN1_OCTET_STRING **keyid,
494                                   X509_NAME **issuer, ASN1_INTEGER **sno)
495 {
496     return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
497 }
498
499 int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
500 {
501     return cms_SignerIdentifier_cert_cmp(si->sid, cert);
502 }
503
504 int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
505                            unsigned int flags)
506 {
507     CMS_SignedData *sd;
508     CMS_SignerInfo *si;
509     CMS_CertificateChoices *cch;
510     STACK_OF(CMS_CertificateChoices) *certs;
511     X509 *x;
512     int i, j;
513     int ret = 0;
514     sd = cms_get0_signed(cms);
515     if (!sd)
516         return -1;
517     certs = sd->certificates;
518     for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
519         si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
520         if (si->signer)
521             continue;
522
523         for (j = 0; j < sk_X509_num(scerts); j++) {
524             x = sk_X509_value(scerts, j);
525             if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
526                 CMS_SignerInfo_set1_signer_cert(si, x);
527                 ret++;
528                 break;
529             }
530         }
531
532         if (si->signer || (flags & CMS_NOINTERN))
533             continue;
534
535         for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
536             cch = sk_CMS_CertificateChoices_value(certs, j);
537             if (cch->type != 0)
538                 continue;
539             x = cch->d.certificate;
540             if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
541                 CMS_SignerInfo_set1_signer_cert(si, x);
542                 ret++;
543                 break;
544             }
545         }
546     }
547     return ret;
548 }
549
550 void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
551                               X509 **signer, X509_ALGOR **pdig,
552                               X509_ALGOR **psig)
553 {
554     if (pk)
555         *pk = si->pkey;
556     if (signer)
557         *signer = si->signer;
558     if (pdig)
559         *pdig = si->digestAlgorithm;
560     if (psig)
561         *psig = si->signatureAlgorithm;
562 }
563
564 static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
565                                        CMS_SignerInfo *si, BIO *chain)
566 {
567     EVP_MD_CTX mctx;
568     int r = 0;
569     EVP_MD_CTX_init(&mctx);
570
571     if (!si->pkey) {
572         CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY);
573         return 0;
574     }
575
576     if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
577         goto err;
578
579     /*
580      * If any signed attributes calculate and add messageDigest attribute
581      */
582
583     if (CMS_signed_get_attr_count(si) >= 0) {
584         ASN1_OBJECT *ctype =
585             cms->d.signedData->encapContentInfo->eContentType;
586         unsigned char md[EVP_MAX_MD_SIZE];
587         unsigned int mdlen;
588         if (!EVP_DigestFinal_ex(&mctx, md, &mdlen))
589             goto err;
590         if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
591                                          V_ASN1_OCTET_STRING, md, mdlen))
592             goto err;
593         /* Copy content type across */
594         if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
595                                         V_ASN1_OBJECT, ctype, -1) <= 0)
596             goto err;
597         if (!CMS_SignerInfo_sign(si))
598             goto err;
599     } else {
600         unsigned char *sig;
601         unsigned int siglen;
602         sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey));
603         if (!sig) {
604             CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE);
605             goto err;
606         }
607         if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) {
608             CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR);
609             OPENSSL_free(sig);
610             goto err;
611         }
612         ASN1_STRING_set0(si->signature, sig, siglen);
613     }
614
615     r = 1;
616
617  err:
618     EVP_MD_CTX_cleanup(&mctx);
619     return r;
620
621 }
622
623 int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
624 {
625     STACK_OF(CMS_SignerInfo) *sinfos;
626     CMS_SignerInfo *si;
627     int i;
628     sinfos = CMS_get0_SignerInfos(cms);
629     for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
630         si = sk_CMS_SignerInfo_value(sinfos, i);
631         if (!cms_SignerInfo_content_sign(cms, si, chain))
632             return 0;
633     }
634     cms->d.signedData->encapContentInfo->partial = 0;
635     return 1;
636 }
637
638 int CMS_SignerInfo_sign(CMS_SignerInfo *si)
639 {
640     EVP_MD_CTX mctx;
641     EVP_PKEY_CTX *pctx;
642     unsigned char *abuf = NULL;
643     int alen;
644     size_t siglen;
645     const EVP_MD *md = NULL;
646
647     md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
648     if (md == NULL)
649         return 0;
650
651     EVP_MD_CTX_init(&mctx);
652
653     if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
654         if (!cms_add1_signingTime(si, NULL))
655             goto err;
656     }
657
658     if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
659         goto err;
660
661     if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
662                           EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) {
663         CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
664         goto err;
665     }
666
667     alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
668                          ASN1_ITEM_rptr(CMS_Attributes_Sign));
669     if (!abuf)
670         goto err;
671     if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0)
672         goto err;
673     if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0)
674         goto err;
675     OPENSSL_free(abuf);
676     abuf = OPENSSL_malloc(siglen);
677     if (!abuf)
678         goto err;
679     if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0)
680         goto err;
681
682     if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
683                           EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) {
684         CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR);
685         goto err;
686     }
687
688     EVP_MD_CTX_cleanup(&mctx);
689
690     ASN1_STRING_set0(si->signature, abuf, siglen);
691
692     return 1;
693
694  err:
695     if (abuf)
696         OPENSSL_free(abuf);
697     EVP_MD_CTX_cleanup(&mctx);
698     return 0;
699
700 }
701
702 int CMS_SignerInfo_verify(CMS_SignerInfo *si)
703 {
704     EVP_MD_CTX mctx;
705     EVP_PKEY_CTX *pctx;
706     unsigned char *abuf = NULL;
707     int alen, r = -1;
708     const EVP_MD *md = NULL;
709
710     if (!si->pkey) {
711         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY);
712         return -1;
713     }
714
715     md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
716     if (md == NULL)
717         return -1;
718     EVP_MD_CTX_init(&mctx);
719     if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0)
720         goto err;
721
722     alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
723                          ASN1_ITEM_rptr(CMS_Attributes_Verify));
724     if (!abuf)
725         goto err;
726     r = EVP_DigestVerifyUpdate(&mctx, abuf, alen);
727     OPENSSL_free(abuf);
728     if (r <= 0) {
729         r = -1;
730         goto err;
731     }
732     r = EVP_DigestVerifyFinal(&mctx,
733                               si->signature->data, si->signature->length);
734     if (r <= 0)
735         CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE);
736  err:
737     EVP_MD_CTX_cleanup(&mctx);
738     return r;
739 }
740
741 /* Create a chain of digest BIOs from a CMS ContentInfo */
742
743 BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms)
744 {
745     int i;
746     CMS_SignedData *sd;
747     BIO *chain = NULL;
748     sd = cms_get0_signed(cms);
749     if (!sd)
750         return NULL;
751     if (cms->d.signedData->encapContentInfo->partial)
752         cms_sd_set_version(sd);
753     for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
754         X509_ALGOR *digestAlgorithm;
755         BIO *mdbio;
756         digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
757         mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
758         if (!mdbio)
759             goto err;
760         if (chain)
761             BIO_push(chain, mdbio);
762         else
763             chain = mdbio;
764     }
765     return chain;
766  err:
767     if (chain)
768         BIO_free_all(chain);
769     return NULL;
770 }
771
772 int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
773 {
774     ASN1_OCTET_STRING *os = NULL;
775     EVP_MD_CTX mctx;
776     int r = -1;
777     EVP_MD_CTX_init(&mctx);
778     /* If we have any signed attributes look for messageDigest value */
779     if (CMS_signed_get_attr_count(si) >= 0) {
780         os = CMS_signed_get0_data_by_OBJ(si,
781                                          OBJ_nid2obj(NID_pkcs9_messageDigest),
782                                          -3, V_ASN1_OCTET_STRING);
783         if (!os) {
784             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
785                    CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
786             goto err;
787         }
788     }
789
790     if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm))
791         goto err;
792
793     /* If messageDigest found compare it */
794
795     if (os) {
796         unsigned char mval[EVP_MAX_MD_SIZE];
797         unsigned int mlen;
798         if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) {
799             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
800                    CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
801             goto err;
802         }
803         if (mlen != (unsigned int)os->length) {
804             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
805                    CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
806             goto err;
807         }
808
809         if (memcmp(mval, os->data, mlen)) {
810             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
811                    CMS_R_VERIFICATION_FAILURE);
812             r = 0;
813         } else
814             r = 1;
815     } else {
816         r = EVP_VerifyFinal(&mctx, si->signature->data,
817                             si->signature->length, si->pkey);
818         if (r <= 0) {
819             CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT,
820                    CMS_R_VERIFICATION_FAILURE);
821             r = 0;
822         }
823     }
824
825  err:
826     EVP_MD_CTX_cleanup(&mctx);
827     return r;
828
829 }
830
831 int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
832 {
833     unsigned char *smder = NULL;
834     int smderlen, r;
835     smderlen = i2d_X509_ALGORS(algs, &smder);
836     if (smderlen <= 0)
837         return 0;
838     r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
839                                     V_ASN1_SEQUENCE, smder, smderlen);
840     OPENSSL_free(smder);
841     return r;
842 }
843
844 int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
845                             int algnid, int keysize)
846 {
847     X509_ALGOR *alg;
848     ASN1_INTEGER *key = NULL;
849     if (keysize > 0) {
850         key = ASN1_INTEGER_new();
851         if (!key || !ASN1_INTEGER_set(key, keysize))
852             return 0;
853     }
854     alg = X509_ALGOR_new();
855     if (!alg) {
856         if (key)
857             ASN1_INTEGER_free(key);
858         return 0;
859     }
860
861     X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
862                     key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
863     if (!*algs)
864         *algs = sk_X509_ALGOR_new_null();
865     if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) {
866         X509_ALGOR_free(alg);
867         return 0;
868     }
869     return 1;
870 }
871
872 /* Check to see if a cipher exists and if so add S/MIME capabilities */
873
874 static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
875 {
876     if (EVP_get_cipherbynid(nid))
877         return CMS_add_simple_smimecap(sk, nid, arg);
878     return 1;
879 }
880
881 static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
882 {
883     if (EVP_get_digestbynid(nid))
884         return CMS_add_simple_smimecap(sk, nid, arg);
885     return 1;
886 }
887
888 int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
889 {
890     if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
891         || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
892         || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
893         || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
894         || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
895         || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
896         || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
897         || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
898         || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
899         || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
900         return 0;
901     return 1;
902 }