xref: /dragonfly/crypto/libressl/crypto/cms/cms_sd.c (revision 961e30ea7dc61d1112b778ea4981eac68129fb86)
1 /* $OpenBSD: cms_sd.c,v 1.24 2022/08/28 18:27:47 tb Exp $ */
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 <string.h>
56 
57 #include "cryptlib.h"
58 #include <openssl/asn1t.h>
59 #include <openssl/pem.h>
60 #include <openssl/x509.h>
61 #include <openssl/x509v3.h>
62 #include <openssl/err.h>
63 #include <openssl/cms.h>
64 #include "cms_lcl.h"
65 #include "asn1/asn1_locl.h"
66 #include "evp/evp_locl.h"
67 
68 /* CMS SignedData Utilities */
69 
70 static CMS_SignedData *
cms_get0_signed(CMS_ContentInfo * cms)71 cms_get0_signed(CMS_ContentInfo *cms)
72 {
73           if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) {
74                     CMSerror(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
75                     return NULL;
76           }
77           return cms->d.signedData;
78 }
79 
80 static CMS_SignedData *
cms_signed_data_init(CMS_ContentInfo * cms)81 cms_signed_data_init(CMS_ContentInfo *cms)
82 {
83           if (cms->d.other == NULL) {
84                     cms->d.signedData = (CMS_SignedData *)ASN1_item_new(&CMS_SignedData_it);
85                     if (!cms->d.signedData) {
86                               CMSerror(ERR_R_MALLOC_FAILURE);
87                               return NULL;
88                     }
89                     cms->d.signedData->version = 1;
90                     cms->d.signedData->encapContentInfo->eContentType =
91                         OBJ_nid2obj(NID_pkcs7_data);
92                     cms->d.signedData->encapContentInfo->partial = 1;
93                     ASN1_OBJECT_free(cms->contentType);
94                     cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
95                     return cms->d.signedData;
96           }
97           return cms_get0_signed(cms);
98 }
99 
100 /* Just initialise SignedData e.g. for certs only structure */
101 
102 int
CMS_SignedData_init(CMS_ContentInfo * cms)103 CMS_SignedData_init(CMS_ContentInfo *cms)
104 {
105           if (cms_signed_data_init(cms))
106                     return 1;
107           else
108                     return 0;
109 }
110 
111 /* Check structures and fixup version numbers (if necessary) */
112 
113 static void
cms_sd_set_version(CMS_SignedData * sd)114 cms_sd_set_version(CMS_SignedData *sd)
115 {
116           int i;
117           CMS_CertificateChoices *cch;
118           CMS_RevocationInfoChoice *rch;
119           CMS_SignerInfo *si;
120 
121           for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) {
122                     cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
123                     if (cch->type == CMS_CERTCHOICE_OTHER) {
124                               if (sd->version < 5)
125                                   sd->version = 5;
126                     } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
127                               if (sd->version < 4)
128                                   sd->version = 4;
129                     } else if (cch->type == CMS_CERTCHOICE_V1ACERT) {
130                               if (sd->version < 3)
131                                   sd->version = 3;
132                     }
133           }
134 
135           for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) {
136                     rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
137                     if (rch->type == CMS_REVCHOICE_OTHER) {
138                               if (sd->version < 5)
139                                   sd->version = 5;
140                     }
141           }
142 
143           if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
144                     && (sd->version < 3))
145                     sd->version = 3;
146 
147           for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
148                     si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
149                     if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
150                               if (si->version < 3)
151                                   si->version = 3;
152                               if (sd->version < 3)
153                                   sd->version = 3;
154                     } else if (si->version < 1)
155                               si->version = 1;
156           }
157 
158           if (sd->version < 1)
159                     sd->version = 1;
160 }
161 
162 /* Copy an existing messageDigest value */
163 
164 static int
cms_copy_messageDigest(CMS_ContentInfo * cms,CMS_SignerInfo * si)165 cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
166 {
167           STACK_OF(CMS_SignerInfo) *sinfos;
168           CMS_SignerInfo *sitmp;
169           int i;
170 
171           sinfos = CMS_get0_SignerInfos(cms);
172           for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
173                     ASN1_OCTET_STRING *messageDigest;
174                     sitmp = sk_CMS_SignerInfo_value(sinfos, i);
175                     if (sitmp == si)
176                               continue;
177                     if (CMS_signed_get_attr_count(sitmp) < 0)
178                               continue;
179                     if (OBJ_cmp(si->digestAlgorithm->algorithm,
180                         sitmp->digestAlgorithm->algorithm))
181                               continue;
182                     messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
183                         OBJ_nid2obj(NID_pkcs9_messageDigest), -3, V_ASN1_OCTET_STRING);
184                     if (!messageDigest) {
185                               CMSerror(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
186                               return 0;
187                     }
188 
189                     if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
190                         V_ASN1_OCTET_STRING, messageDigest, -1))
191                               return 1;
192                     else
193                               return 0;
194           }
195 
196           CMSerror(CMS_R_NO_MATCHING_DIGEST);
197 
198           return 0;
199 }
200 
201 int
cms_set1_SignerIdentifier(CMS_SignerIdentifier * sid,X509 * cert,int type)202 cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)
203 {
204           switch (type) {
205           case CMS_SIGNERINFO_ISSUER_SERIAL:
206                     if (!cms_set1_ias(&sid->d.issuerAndSerialNumber, cert))
207                               return 0;
208                     break;
209 
210           case CMS_SIGNERINFO_KEYIDENTIFIER:
211                     if (!cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert))
212                               return 0;
213                     break;
214 
215           default:
216                     CMSerror(CMS_R_UNKNOWN_ID);
217                     return 0;
218           }
219 
220           sid->type = type;
221 
222           return 1;
223 }
224 
225 int
cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier * sid,ASN1_OCTET_STRING ** keyid,X509_NAME ** issuer,ASN1_INTEGER ** sno)226 cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
227     ASN1_OCTET_STRING **keyid, X509_NAME **issuer, ASN1_INTEGER **sno)
228 {
229           if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
230                     if (issuer)
231                               *issuer = sid->d.issuerAndSerialNumber->issuer;
232                     if (sno)
233                               *sno = sid->d.issuerAndSerialNumber->serialNumber;
234           } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
235                     if (keyid)
236                               *keyid = sid->d.subjectKeyIdentifier;
237           } else
238                     return 0;
239 
240           return 1;
241 }
242 
243 int
cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier * sid,X509 * cert)244 cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
245 {
246           if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
247                     return cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert);
248           else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
249                     return cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert);
250           else
251                     return -1;
252 }
253 
254 static int
cms_sd_asn1_ctrl(CMS_SignerInfo * si,int cmd)255 cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
256 {
257           EVP_PKEY *pkey = si->pkey;
258           int i;
259 
260           if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
261                     return 1;
262           i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
263           if (i == -2) {
264                     CMSerror(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
265                     return 0;
266           }
267           if (i <= 0) {
268                     CMSerror(CMS_R_CTRL_FAILURE);
269                     return 0;
270           }
271 
272           return 1;
273 }
274 
275 CMS_SignerInfo *
CMS_add1_signer(CMS_ContentInfo * cms,X509 * signer,EVP_PKEY * pk,const EVP_MD * md,unsigned int flags)276 CMS_add1_signer(CMS_ContentInfo *cms, X509 *signer, EVP_PKEY *pk,
277     const EVP_MD *md, unsigned int flags)
278 {
279           CMS_SignedData *sd;
280           CMS_SignerInfo *si = NULL;
281           X509_ALGOR *alg;
282           int i, type;
283 
284           if (!X509_check_private_key(signer, pk)) {
285                     CMSerror(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 = (CMS_SignerInfo *)ASN1_item_new(&CMS_SignerInfo_it);
292           if (!si)
293                     goto merr;
294           /* Call for side-effect of computing hash and caching extensions */
295           X509_check_purpose(signer, -1, -1);
296 
297           X509_up_ref(signer);
298           EVP_PKEY_up_ref(pk);
299 
300           si->pkey = pk;
301           si->signer = signer;
302           si->mctx = EVP_MD_CTX_new();
303           si->pctx = NULL;
304 
305           if (si->mctx == NULL) {
306                     CMSerror(ERR_R_MALLOC_FAILURE);
307                     goto err;
308           }
309 
310           if (flags & CMS_USE_KEYID) {
311                     si->version = 3;
312                     if (sd->version < 3)
313                               sd->version = 3;
314                     type = CMS_SIGNERINFO_KEYIDENTIFIER;
315           } else {
316                     type = CMS_SIGNERINFO_ISSUER_SERIAL;
317                     si->version = 1;
318           }
319 
320           if (!cms_set1_SignerIdentifier(si->sid, signer, type))
321                     goto err;
322 
323           if (md == NULL) {
324                     int def_nid;
325                     if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0)
326                               goto err;
327                     md = EVP_get_digestbynid(def_nid);
328                     if (md == NULL) {
329                               CMSerror(CMS_R_NO_DEFAULT_DIGEST);
330                               goto err;
331                     }
332           }
333 
334           if (!md) {
335                     CMSerror(CMS_R_NO_DIGEST_SET);
336                     goto err;
337           }
338 
339           X509_ALGOR_set_md(si->digestAlgorithm, md);
340 
341           /* See if digest is present in digestAlgorithms */
342           for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
343                     const ASN1_OBJECT *aoid;
344                     alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
345                     X509_ALGOR_get0(&aoid, NULL, NULL, alg);
346                     if (OBJ_obj2nid(aoid) == EVP_MD_type(md))
347                               break;
348           }
349 
350           if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
351                     alg = X509_ALGOR_new();
352                     if (alg == NULL)
353                               goto merr;
354                     X509_ALGOR_set_md(alg, md);
355                     if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) {
356                               X509_ALGOR_free(alg);
357                               goto merr;
358                     }
359           }
360 
361           if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0))
362                     goto err;
363           if (!(flags & CMS_NOATTR)) {
364                     /*
365                      * Initialize signed attributes structure so other attributes
366                      * such as signing time etc are added later even if we add none here.
367                      */
368                     if (!si->signedAttrs) {
369                               si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
370                               if (!si->signedAttrs)
371                                         goto merr;
372                     }
373 
374                     if (!(flags & CMS_NOSMIMECAP)) {
375                               STACK_OF(X509_ALGOR) *smcap = NULL;
376 
377                               i = CMS_add_standard_smimecap(&smcap);
378                               if (i)
379                                   i = CMS_add_smimecap(si, smcap);
380                               sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
381                               if (!i)
382                                         goto merr;
383                     }
384                     if (flags & CMS_REUSE_DIGEST) {
385                               if (!cms_copy_messageDigest(cms, si))
386                                         goto err;
387                               if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
388                                   !CMS_SignerInfo_sign(si))
389                                         goto err;
390                     }
391           }
392 
393           if (!(flags & CMS_NOCERTS)) {
394                     /* NB ignore -1 return for duplicate cert */
395                     if (!CMS_add1_cert(cms, signer))
396                               goto merr;
397           }
398 
399           if (flags & CMS_KEY_PARAM) {
400                     if (flags & CMS_NOATTR) {
401                               si->pctx = EVP_PKEY_CTX_new(si->pkey, NULL);
402                               if (si->pctx == NULL)
403                                         goto err;
404                               if (EVP_PKEY_sign_init(si->pctx) <= 0)
405                                         goto err;
406                               if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
407                                         goto err;
408                     } else if (EVP_DigestSignInit(si->mctx, &si->pctx, md,
409                         NULL, pk) <= 0)
410                               goto err;
411           }
412 
413           if (!sd->signerInfos)
414                     sd->signerInfos = sk_CMS_SignerInfo_new_null();
415           if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si))
416                     goto merr;
417 
418           return si;
419 
420  merr:
421           CMSerror(ERR_R_MALLOC_FAILURE);
422  err:
423           ASN1_item_free((ASN1_VALUE *)si, &CMS_SignerInfo_it);
424 
425           return NULL;
426 }
427 
428 static int
cms_add1_signingTime(CMS_SignerInfo * si,ASN1_TIME * t)429 cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
430 {
431           ASN1_TIME *tt;
432           int r = 0;
433 
434           if (t)
435                     tt = t;
436           else
437                     tt = X509_gmtime_adj(NULL, 0);
438 
439           if (!tt)
440                     goto merr;
441 
442           if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
443                                                       tt->type, tt, -1) <= 0)
444                     goto merr;
445 
446           r = 1;
447 
448  merr:
449           if (!t)
450                     ASN1_TIME_free(tt);
451           if (!r)
452                     CMSerror(ERR_R_MALLOC_FAILURE);
453 
454           return r;
455 }
456 
457 EVP_PKEY_CTX *
CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo * si)458 CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si)
459 {
460           return si->pctx;
461 }
462 
463 EVP_MD_CTX *
CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo * si)464 CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
465 {
466           return si->mctx;
467 }
468 
STACK_OF(CMS_SignerInfo)469 STACK_OF(CMS_SignerInfo) *
470 CMS_get0_SignerInfos(CMS_ContentInfo *cms)
471 {
472           CMS_SignedData *sd;
473 
474           sd = cms_get0_signed(cms);
475           if (!sd)
476                     return NULL;
477 
478           return sd->signerInfos;
479 }
480 
STACK_OF(X509)481 STACK_OF(X509) *
482 CMS_get0_signers(CMS_ContentInfo *cms)
483 {
484           STACK_OF(X509) *signers = NULL;
485           STACK_OF(CMS_SignerInfo) *sinfos;
486           CMS_SignerInfo *si;
487           int i;
488 
489           sinfos = CMS_get0_SignerInfos(cms);
490           for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
491                     si = sk_CMS_SignerInfo_value(sinfos, i);
492                     if (si->signer) {
493                               if (!signers) {
494                                         signers = sk_X509_new_null();
495                                         if (!signers)
496                                                   return NULL;
497                               }
498                               if (!sk_X509_push(signers, si->signer)) {
499                                         sk_X509_free(signers);
500                                         return NULL;
501                               }
502                     }
503           }
504 
505           return signers;
506 }
507 
508 void
CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo * si,X509 * signer)509 CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
510 {
511           if (signer) {
512                     X509_up_ref(signer);
513                     EVP_PKEY_free(si->pkey);
514                     si->pkey = X509_get_pubkey(signer);
515           }
516           X509_free(si->signer);
517           si->signer = signer;
518 }
519 
520 int
CMS_SignerInfo_get0_signer_id(CMS_SignerInfo * si,ASN1_OCTET_STRING ** keyid,X509_NAME ** issuer,ASN1_INTEGER ** sno)521 CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, ASN1_OCTET_STRING **keyid,
522     X509_NAME **issuer, ASN1_INTEGER **sno)
523 {
524           return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
525 }
526 
527 int
CMS_SignerInfo_cert_cmp(CMS_SignerInfo * si,X509 * cert)528 CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
529 {
530           return cms_SignerIdentifier_cert_cmp(si->sid, cert);
531 }
532 
533 int
CMS_set1_signers_certs(CMS_ContentInfo * cms,STACK_OF (X509)* scerts,unsigned int flags)534 CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
535     unsigned int flags)
536 {
537           CMS_SignedData *sd;
538           CMS_SignerInfo *si;
539           CMS_CertificateChoices *cch;
540           STACK_OF(CMS_CertificateChoices) *certs;
541           X509 *x;
542           int i, j;
543           int ret = 0;
544 
545           sd = cms_get0_signed(cms);
546           if (!sd)
547                     return -1;
548           certs = sd->certificates;
549           for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
550                     si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
551                     if (si->signer)
552                               continue;
553 
554                     for (j = 0; j < sk_X509_num(scerts); j++) {
555                               x = sk_X509_value(scerts, j);
556                               if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
557                                         CMS_SignerInfo_set1_signer_cert(si, x);
558                                         ret++;
559                                         break;
560                               }
561                     }
562 
563                     if (si->signer || (flags & CMS_NOINTERN))
564                               continue;
565 
566                     for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
567                               cch = sk_CMS_CertificateChoices_value(certs, j);
568                               if (cch->type != 0)
569                                         continue;
570                               x = cch->d.certificate;
571                               if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
572                                         CMS_SignerInfo_set1_signer_cert(si, x);
573                                         ret++;
574                                         break;
575                               }
576                     }
577           }
578           return ret;
579 }
580 
581 void
CMS_SignerInfo_get0_algs(CMS_SignerInfo * si,EVP_PKEY ** pk,X509 ** signer,X509_ALGOR ** pdig,X509_ALGOR ** psig)582 CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, X509 **signer,
583 X509_ALGOR **pdig, X509_ALGOR **psig)
584 {
585           if (pk)
586                     *pk = si->pkey;
587           if (signer)
588                     *signer = si->signer;
589           if (pdig)
590                     *pdig = si->digestAlgorithm;
591           if (psig)
592                     *psig = si->signatureAlgorithm;
593 }
594 
595 ASN1_OCTET_STRING *
CMS_SignerInfo_get0_signature(CMS_SignerInfo * si)596 CMS_SignerInfo_get0_signature(CMS_SignerInfo *si)
597 {
598           return si->signature;
599 }
600 
601 static int
cms_SignerInfo_content_sign(CMS_ContentInfo * cms,CMS_SignerInfo * si,BIO * chain)602 cms_SignerInfo_content_sign(CMS_ContentInfo *cms, CMS_SignerInfo *si, BIO *chain)
603 {
604           EVP_MD_CTX *mctx = EVP_MD_CTX_new();
605           int r = 0;
606           EVP_PKEY_CTX *pctx = NULL;
607 
608           if (mctx == NULL) {
609                     CMSerror(ERR_R_MALLOC_FAILURE);
610                     return 0;
611           }
612 
613           if (!si->pkey) {
614                     CMSerror(CMS_R_NO_PRIVATE_KEY);
615                     goto err;
616           }
617 
618           if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
619                     goto err;
620           /* Set SignerInfo algorithm details if we used custom parameter */
621           if (si->pctx && !cms_sd_asn1_ctrl(si, 0))
622                     goto err;
623 
624           /*
625            * If any signed attributes calculate and add messageDigest attribute
626            */
627 
628           if (CMS_signed_get_attr_count(si) >= 0) {
629                     ASN1_OBJECT *ctype =
630                         cms->d.signedData->encapContentInfo->eContentType;
631                     unsigned char md[EVP_MAX_MD_SIZE];
632                     unsigned int mdlen;
633 
634                     if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
635                               goto err;
636                     if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
637                         V_ASN1_OCTET_STRING, md, mdlen))
638                               goto err;
639                     /* Copy content type across */
640                     if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
641                         V_ASN1_OBJECT, ctype, -1) <= 0)
642                               goto err;
643                     if (!CMS_SignerInfo_sign(si))
644                               goto err;
645           } else if (si->pctx) {
646                     unsigned char *sig;
647                     size_t siglen;
648                     unsigned char md[EVP_MAX_MD_SIZE];
649                     unsigned int mdlen;
650 
651                     pctx = si->pctx;
652                     if (!EVP_DigestFinal_ex(mctx, md, &mdlen))
653                               goto err;
654                     siglen = EVP_PKEY_size(si->pkey);
655                     sig = malloc(siglen);
656                     if (sig == NULL) {
657                               CMSerror(ERR_R_MALLOC_FAILURE);
658                               goto err;
659                     }
660                     if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) {
661                               free(sig);
662                               goto err;
663                     }
664                     ASN1_STRING_set0(si->signature, sig, siglen);
665           } else {
666                     unsigned char *sig;
667                     unsigned int siglen;
668 
669                     sig = malloc(EVP_PKEY_size(si->pkey));
670                     if (sig == NULL) {
671                               CMSerror(ERR_R_MALLOC_FAILURE);
672                               goto err;
673                     }
674                     if (!EVP_SignFinal(mctx, sig, &siglen, si->pkey)) {
675                               CMSerror(CMS_R_SIGNFINAL_ERROR);
676                               free(sig);
677                               goto err;
678                     }
679                     ASN1_STRING_set0(si->signature, sig, siglen);
680           }
681 
682           r = 1;
683 
684  err:
685           EVP_MD_CTX_free(mctx);
686           EVP_PKEY_CTX_free(pctx);
687 
688           return r;
689 }
690 
691 int
cms_SignedData_final(CMS_ContentInfo * cms,BIO * chain)692 cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain)
693 {
694           STACK_OF(CMS_SignerInfo) *sinfos;
695           CMS_SignerInfo *si;
696           int i;
697 
698           sinfos = CMS_get0_SignerInfos(cms);
699           for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
700                     si = sk_CMS_SignerInfo_value(sinfos, i);
701                     if (!cms_SignerInfo_content_sign(cms, si, chain))
702                               return 0;
703           }
704           cms->d.signedData->encapContentInfo->partial = 0;
705 
706           return 1;
707 }
708 
709 int
CMS_SignerInfo_sign(CMS_SignerInfo * si)710 CMS_SignerInfo_sign(CMS_SignerInfo *si)
711 {
712           EVP_MD_CTX *mctx = si->mctx;
713           EVP_PKEY_CTX *pctx = NULL;
714           unsigned char *abuf = NULL;
715           int alen;
716           size_t siglen;
717           const EVP_MD *md = NULL;
718 
719           md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
720           if (md == NULL)
721                     return 0;
722 
723           if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
724                     if (!cms_add1_signingTime(si, NULL))
725                               goto err;
726           }
727 
728           if (si->pctx)
729                     pctx = si->pctx;
730           else {
731                     EVP_MD_CTX_reset(mctx);
732                     if (EVP_DigestSignInit(mctx, &pctx, md, NULL, si->pkey) <= 0)
733                               goto err;
734                     si->pctx = pctx;
735           }
736 
737           if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
738               EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) {
739                     CMSerror(CMS_R_CTRL_ERROR);
740                     goto err;
741           }
742 
743           alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
744               &CMS_Attributes_Sign_it);
745           if (!abuf)
746                     goto err;
747           if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
748                     goto err;
749           if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
750                     goto err;
751           free(abuf);
752           abuf = malloc(siglen);
753           if (abuf == NULL)
754                     goto err;
755           if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
756                     goto err;
757 
758           if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN,
759               EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) {
760                     CMSerror(CMS_R_CTRL_ERROR);
761                     goto err;
762           }
763 
764           EVP_MD_CTX_reset(mctx);
765 
766           ASN1_STRING_set0(si->signature, abuf, siglen);
767 
768           return 1;
769 
770  err:
771           free(abuf);
772           EVP_MD_CTX_reset(mctx);
773 
774           return 0;
775 }
776 
777 int
CMS_SignerInfo_verify(CMS_SignerInfo * si)778 CMS_SignerInfo_verify(CMS_SignerInfo *si)
779 {
780           EVP_MD_CTX *mctx = NULL;
781           unsigned char *abuf = NULL;
782           int alen, r = -1;
783           const EVP_MD *md = NULL;
784 
785           if (!si->pkey) {
786                     CMSerror(CMS_R_NO_PUBLIC_KEY);
787                     return -1;
788           }
789 
790           md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
791           if (md == NULL)
792                     return -1;
793           if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) {
794                     CMSerror(ERR_R_MALLOC_FAILURE);
795                     return -1;
796           }
797           mctx = si->mctx;
798           if (EVP_DigestVerifyInit(mctx, &si->pctx, md, NULL, si->pkey) <= 0)
799                     goto err;
800 
801           if (!cms_sd_asn1_ctrl(si, 1))
802                     goto err;
803 
804           alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
805               &CMS_Attributes_Verify_it);
806           if (!abuf)
807                     goto err;
808           r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
809           free(abuf);
810           if (r <= 0) {
811                     r = -1;
812                     goto err;
813           }
814 
815           r = EVP_DigestVerifyFinal(mctx, si->signature->data,
816               si->signature->length);
817           if (r <= 0)
818                     CMSerror(CMS_R_VERIFICATION_FAILURE);
819 
820  err:
821           EVP_MD_CTX_reset(mctx);
822 
823           return r;
824 }
825 
826 /* Create a chain of digest BIOs from a CMS ContentInfo */
827 
828 BIO *
cms_SignedData_init_bio(CMS_ContentInfo * cms)829 cms_SignedData_init_bio(CMS_ContentInfo *cms)
830 {
831           int i;
832           CMS_SignedData *sd;
833           BIO *chain = NULL;
834 
835           sd = cms_get0_signed(cms);
836           if (!sd)
837                     return NULL;
838           if (cms->d.signedData->encapContentInfo->partial)
839                     cms_sd_set_version(sd);
840           for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
841                     X509_ALGOR *digestAlgorithm;
842                     BIO *mdbio;
843                     digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
844                     mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm);
845                     if (!mdbio)
846                               goto err;
847                     if (chain)
848                               BIO_push(chain, mdbio);
849                     else
850                               chain = mdbio;
851           }
852 
853           return chain;
854 
855  err:
856           BIO_free_all(chain);
857 
858           return NULL;
859 }
860 
861 int
CMS_SignerInfo_verify_content(CMS_SignerInfo * si,BIO * chain)862 CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
863 {
864           ASN1_OCTET_STRING *os = NULL;
865           EVP_MD_CTX *mctx = EVP_MD_CTX_new();
866           EVP_PKEY_CTX *pkctx = NULL;
867           int r = -1;
868           unsigned char mval[EVP_MAX_MD_SIZE];
869           unsigned int mlen;
870 
871           if (mctx == NULL) {
872                     CMSerror(ERR_R_MALLOC_FAILURE);
873                     goto err;
874           }
875           /* If we have any signed attributes look for messageDigest value */
876           if (CMS_signed_get_attr_count(si) >= 0) {
877                     os = CMS_signed_get0_data_by_OBJ(si,
878                         OBJ_nid2obj(NID_pkcs9_messageDigest), -3,
879                         V_ASN1_OCTET_STRING);
880                     if (!os) {
881                               CMSerror(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
882                               goto err;
883                     }
884           }
885 
886           if (!cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
887                     goto err;
888 
889           if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) {
890                     CMSerror(CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
891                     goto err;
892           }
893 
894           /* If messageDigest found compare it */
895 
896           if (os) {
897                     if (mlen != (unsigned int)os->length) {
898                               CMSerror(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
899                               goto err;
900                     }
901 
902                     if (memcmp(mval, os->data, mlen)) {
903                               CMSerror(CMS_R_VERIFICATION_FAILURE);
904                               r = 0;
905                     } else
906                               r = 1;
907           } else {
908                     const EVP_MD *md = EVP_MD_CTX_md(mctx);
909 
910                     pkctx = EVP_PKEY_CTX_new(si->pkey, NULL);
911                     if (pkctx == NULL)
912                               goto err;
913                     if (EVP_PKEY_verify_init(pkctx) <= 0)
914                               goto err;
915                     if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
916                               goto err;
917                     si->pctx = pkctx;
918                     if (!cms_sd_asn1_ctrl(si, 1))
919                               goto err;
920                     r = EVP_PKEY_verify(pkctx, si->signature->data,
921                                               si->signature->length, mval, mlen);
922                     if (r <= 0) {
923                               CMSerror(CMS_R_VERIFICATION_FAILURE);
924                               r = 0;
925                     }
926           }
927 
928  err:
929           EVP_PKEY_CTX_free(pkctx);
930           EVP_MD_CTX_free(mctx);
931 
932           return r;
933 }
934 
935 int
CMS_add_smimecap(CMS_SignerInfo * si,STACK_OF (X509_ALGOR)* algs)936 CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
937 {
938           unsigned char *smder = NULL;
939           int smderlen, r;
940 
941           smderlen = i2d_X509_ALGORS(algs, &smder);
942           if (smderlen <= 0)
943                     return 0;
944           r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
945               V_ASN1_SEQUENCE, smder, smderlen);
946           free(smder);
947 
948           return r;
949 }
950 
951 int
CMS_add_simple_smimecap(STACK_OF (X509_ALGOR)** algs,int algnid,int keysize)952 CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, int algnid, int keysize)
953 {
954           X509_ALGOR *alg;
955           ASN1_INTEGER *key = NULL;
956 
957           if (keysize > 0) {
958                     if ((key = ASN1_INTEGER_new()) == NULL)
959                               return 0;
960                     if (!ASN1_INTEGER_set(key, keysize)) {
961                               ASN1_INTEGER_free(key);
962                               return 0;
963                     }
964           }
965           alg = X509_ALGOR_new();
966           if (alg == NULL) {
967                     ASN1_INTEGER_free(key);
968                     return 0;
969           }
970 
971           X509_ALGOR_set0(alg, OBJ_nid2obj(algnid),
972               key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
973           if (*algs == NULL)
974                     *algs = sk_X509_ALGOR_new_null();
975           if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) {
976                     X509_ALGOR_free(alg);
977                     return 0;
978           }
979 
980           return 1;
981 }
982 
983 /* Check to see if a cipher exists and if so add S/MIME capabilities */
984 
985 static int
cms_add_cipher_smcap(STACK_OF (X509_ALGOR)** sk,int nid,int arg)986 cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
987 {
988           if (EVP_get_cipherbynid(nid))
989                     return CMS_add_simple_smimecap(sk, nid, arg);
990           return 1;
991 }
992 
993 static int
cms_add_digest_smcap(STACK_OF (X509_ALGOR)** sk,int nid,int arg)994 cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
995 {
996           if (EVP_get_digestbynid(nid))
997                     return CMS_add_simple_smimecap(sk, nid, arg);
998           return 1;
999 }
1000 
1001 int
CMS_add_standard_smimecap(STACK_OF (X509_ALGOR)** smcap)1002 CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
1003 {
1004           if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) ||
1005               !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) ||
1006               !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) ||
1007               !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) ||
1008               !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) ||
1009               !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) ||
1010               !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) ||
1011               !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) ||
1012               !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) ||
1013               !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
1014                     return 0;
1015 
1016           return 1;
1017 }
1018