1 /*
2 * Copyright 2008-2025 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include "internal/cryptlib.h"
11 #include <openssl/asn1t.h>
12 #include <openssl/pem.h>
13 #include <openssl/x509.h>
14 #include <openssl/x509v3.h>
15 #include <openssl/err.h>
16 #include <openssl/cms.h>
17 #include <openssl/ess.h>
18 #include "internal/sizes.h"
19 #include "crypto/asn1.h"
20 #include "crypto/evp.h"
21 #include "crypto/ess.h"
22 #include "crypto/x509.h" /* for ossl_x509_add_cert_new() */
23 #include "cms_local.h"
24
25 /* CMS SignedData Utilities */
26
cms_get0_signed(CMS_ContentInfo * cms)27 static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)
28 {
29 if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) {
30 ERR_raise(ERR_LIB_CMS, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);
31 return NULL;
32 }
33 return cms->d.signedData;
34 }
35
cms_signed_data_init(CMS_ContentInfo * cms)36 static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)
37 {
38 if (cms->d.other == NULL) {
39 cms->d.signedData = M_ASN1_new_of(CMS_SignedData);
40 if (!cms->d.signedData) {
41 ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
42 return NULL;
43 }
44 cms->d.signedData->version = 1;
45 cms->d.signedData->encapContentInfo->eContentType =
46 OBJ_nid2obj(NID_pkcs7_data);
47 cms->d.signedData->encapContentInfo->partial = 1;
48 ASN1_OBJECT_free(cms->contentType);
49 cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
50 return cms->d.signedData;
51 }
52 return cms_get0_signed(cms);
53 }
54
55 /* Just initialise SignedData e.g. for certs only structure */
CMS_SignedData_init(CMS_ContentInfo * cms)56 int CMS_SignedData_init(CMS_ContentInfo *cms)
57 {
58 if (cms_signed_data_init(cms))
59 return 1;
60 else
61 return 0;
62 }
63
64 /* Check structures and fixup version numbers (if necessary) */
cms_sd_set_version(CMS_SignedData * sd)65 static void cms_sd_set_version(CMS_SignedData *sd)
66 {
67 int i;
68 CMS_CertificateChoices *cch;
69 CMS_RevocationInfoChoice *rch;
70 CMS_SignerInfo *si;
71
72 for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) {
73 cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
74 if (cch->type == CMS_CERTCHOICE_OTHER) {
75 if (sd->version < 5)
76 sd->version = 5;
77 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
78 if (sd->version < 4)
79 sd->version = 4;
80 } else if (cch->type == CMS_CERTCHOICE_V1ACERT) {
81 if (sd->version < 3)
82 sd->version = 3;
83 }
84 }
85
86 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) {
87 rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
88 if (rch->type == CMS_REVCHOICE_OTHER) {
89 if (sd->version < 5)
90 sd->version = 5;
91 }
92 }
93
94 if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
95 && (sd->version < 3))
96 sd->version = 3;
97
98 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
99 si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
100 if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
101 if (si->version < 3)
102 si->version = 3;
103 if (sd->version < 3)
104 sd->version = 3;
105 } else if (si->version < 1) {
106 si->version = 1;
107 }
108 }
109
110 if (sd->version < 1)
111 sd->version = 1;
112
113 }
114
115 /*
116 * RFC 5652 Section 11.1 Content Type
117 * The content-type attribute within signed-data MUST
118 * 1) be present if there are signed attributes
119 * 2) match the content type in the signed-data,
120 * 3) be a signed attribute.
121 * 4) not have more than one copy of the attribute.
122 *
123 * Note that since the CMS_SignerInfo_sign() always adds the "signing time"
124 * attribute, the content type attribute MUST be added also.
125 * Assumptions: This assumes that the attribute does not already exist.
126 */
cms_set_si_contentType_attr(CMS_ContentInfo * cms,CMS_SignerInfo * si)127 static int cms_set_si_contentType_attr(CMS_ContentInfo *cms, CMS_SignerInfo *si)
128 {
129 ASN1_OBJECT *ctype = cms->d.signedData->encapContentInfo->eContentType;
130
131 /* Add the contentType attribute */
132 return CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
133 V_ASN1_OBJECT, ctype, -1) > 0;
134 }
135
136 /* Copy an existing messageDigest value */
cms_copy_messageDigest(CMS_ContentInfo * cms,CMS_SignerInfo * si)137 static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
138 {
139 STACK_OF(CMS_SignerInfo) *sinfos;
140 CMS_SignerInfo *sitmp;
141 int i;
142
143 sinfos = CMS_get0_SignerInfos(cms);
144 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
145 ASN1_OCTET_STRING *messageDigest;
146
147 sitmp = sk_CMS_SignerInfo_value(sinfos, i);
148 if (sitmp == si)
149 continue;
150 if (CMS_signed_get_attr_count(sitmp) < 0)
151 continue;
152 if (OBJ_cmp(si->digestAlgorithm->algorithm,
153 sitmp->digestAlgorithm->algorithm))
154 continue;
155 messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
156 OBJ_nid2obj
157 (NID_pkcs9_messageDigest),
158 -3, V_ASN1_OCTET_STRING);
159 if (!messageDigest) {
160 ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
161 return 0;
162 }
163
164 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
165 V_ASN1_OCTET_STRING,
166 messageDigest, -1))
167 return 1;
168 else
169 return 0;
170 }
171 ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_DIGEST);
172 return 0;
173 }
174
ossl_cms_set1_SignerIdentifier(CMS_SignerIdentifier * sid,X509 * cert,int type,const CMS_CTX * ctx)175 int ossl_cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert,
176 int type, const CMS_CTX *ctx)
177 {
178 switch (type) {
179 case CMS_SIGNERINFO_ISSUER_SERIAL:
180 if (!ossl_cms_set1_ias(&sid->d.issuerAndSerialNumber, cert))
181 return 0;
182 break;
183
184 case CMS_SIGNERINFO_KEYIDENTIFIER:
185 if (!ossl_cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert))
186 return 0;
187 break;
188
189 default:
190 ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_ID);
191 return 0;
192 }
193
194 sid->type = type;
195
196 return 1;
197 }
198
ossl_cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier * sid,ASN1_OCTET_STRING ** keyid,X509_NAME ** issuer,ASN1_INTEGER ** sno)199 int ossl_cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
200 ASN1_OCTET_STRING **keyid,
201 X509_NAME **issuer,
202 ASN1_INTEGER **sno)
203 {
204 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
205 if (issuer)
206 *issuer = sid->d.issuerAndSerialNumber->issuer;
207 if (sno)
208 *sno = sid->d.issuerAndSerialNumber->serialNumber;
209 } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
210 if (keyid)
211 *keyid = sid->d.subjectKeyIdentifier;
212 } else {
213 return 0;
214 }
215 return 1;
216 }
217
ossl_cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier * sid,X509 * cert)218 int ossl_cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
219 {
220 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
221 return ossl_cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert);
222 else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
223 return ossl_cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert);
224 else
225 return -1;
226 }
227
cms_signature_nomd(EVP_PKEY * pkey)228 static int cms_signature_nomd(EVP_PKEY *pkey)
229 {
230 char def_md[80];
231
232 return EVP_PKEY_get_default_digest_name(pkey, def_md, sizeof(def_md)) == 2
233 && strcmp(def_md, "UNDEF") == 0 ? 1 : 0;
234 }
235
236 /* Method to map any, incl. provider-implemented PKEY types to OIDs */
237 /* (EC)DSA and all provider-delivered signatures implementation is the same */
cms_generic_sign(CMS_SignerInfo * si,int verify)238 static int cms_generic_sign(CMS_SignerInfo *si, int verify)
239 {
240 if (!ossl_assert(verify == 0 || verify == 1))
241 return -1;
242
243 if (!verify) {
244 EVP_PKEY *pkey = si->pkey;
245 int snid, hnid, pknid = EVP_PKEY_get_id(pkey);
246 X509_ALGOR *alg1, *alg2;
247
248 CMS_SignerInfo_get0_algs(si, NULL, NULL, &alg1, &alg2);
249 if (alg1 == NULL || alg1->algorithm == NULL)
250 return -1;
251 hnid = OBJ_obj2nid(alg1->algorithm);
252 if (hnid == NID_undef)
253 return -1;
254 if (pknid <= 0) { /* check whether a provider registered a NID */
255 const char *typename = EVP_PKEY_get0_type_name(pkey);
256
257 if (typename != NULL)
258 pknid = OBJ_txt2nid(typename);
259 }
260 if (pknid > 0 && cms_signature_nomd(pkey))
261 snid = pknid;
262 else if (!OBJ_find_sigid_by_algs(&snid, hnid, pknid))
263 return -1;
264 return X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, NULL);
265 }
266 return 1;
267 }
268
cms_sd_asn1_ctrl(CMS_SignerInfo * si,int cmd)269 static int cms_sd_asn1_ctrl(CMS_SignerInfo *si, int cmd)
270 {
271 EVP_PKEY *pkey = si->pkey;
272 int i;
273
274 if (EVP_PKEY_is_a(pkey, "DSA") || EVP_PKEY_is_a(pkey, "EC"))
275 return cms_generic_sign(si, cmd) > 0;
276 else if (EVP_PKEY_is_a(pkey, "RSA") || EVP_PKEY_is_a(pkey, "RSA-PSS"))
277 return ossl_cms_rsa_sign(si, cmd) > 0;
278
279 /* Now give engines, providers, etc a chance to handle this */
280 if (pkey->ameth == NULL || pkey->ameth->pkey_ctrl == NULL)
281 return cms_generic_sign(si, cmd) > 0;
282 i = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_CMS_SIGN, cmd, si);
283 if (i == -2) {
284 ERR_raise(ERR_LIB_CMS, CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
285 return 0;
286 }
287 if (i <= 0) {
288 ERR_raise(ERR_LIB_CMS, CMS_R_CTRL_FAILURE);
289 return 0;
290 }
291 return 1;
292 }
293
294 /* Add SigningCertificate signed attribute to the signer info. */
ossl_cms_add1_signing_cert(CMS_SignerInfo * si,const ESS_SIGNING_CERT * sc)295 static int ossl_cms_add1_signing_cert(CMS_SignerInfo *si,
296 const ESS_SIGNING_CERT *sc)
297 {
298 ASN1_STRING *seq = NULL;
299 unsigned char *p, *pp = NULL;
300 int ret, len = i2d_ESS_SIGNING_CERT(sc, NULL);
301
302 if (len <= 0 || (pp = OPENSSL_malloc(len)) == NULL)
303 return 0;
304
305 p = pp;
306 i2d_ESS_SIGNING_CERT(sc, &p);
307 if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) {
308 ASN1_STRING_free(seq);
309 OPENSSL_free(pp);
310 return 0;
311 }
312 OPENSSL_free(pp);
313 ret = CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_signingCertificate,
314 V_ASN1_SEQUENCE, seq, -1);
315 ASN1_STRING_free(seq);
316 return ret;
317 }
318
319 /* Add SigningCertificateV2 signed attribute to the signer info. */
ossl_cms_add1_signing_cert_v2(CMS_SignerInfo * si,const ESS_SIGNING_CERT_V2 * sc)320 static int ossl_cms_add1_signing_cert_v2(CMS_SignerInfo *si,
321 const ESS_SIGNING_CERT_V2 *sc)
322 {
323 ASN1_STRING *seq = NULL;
324 unsigned char *p, *pp = NULL;
325 int ret, len = i2d_ESS_SIGNING_CERT_V2(sc, NULL);
326
327 if (len <= 0 || (pp = OPENSSL_malloc(len)) == NULL)
328 return 0;
329
330 p = pp;
331 i2d_ESS_SIGNING_CERT_V2(sc, &p);
332 if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) {
333 ASN1_STRING_free(seq);
334 OPENSSL_free(pp);
335 return 0;
336 }
337 OPENSSL_free(pp);
338 ret = CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_signingCertificateV2,
339 V_ASN1_SEQUENCE, seq, -1);
340 ASN1_STRING_free(seq);
341 return ret;
342 }
343
CMS_add1_signer(CMS_ContentInfo * cms,X509 * signer,EVP_PKEY * pk,const EVP_MD * md,unsigned int flags)344 CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
345 X509 *signer, EVP_PKEY *pk, const EVP_MD *md,
346 unsigned int flags)
347 {
348 CMS_SignedData *sd;
349 CMS_SignerInfo *si = NULL;
350 X509_ALGOR *alg;
351 int i, type;
352 const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms);
353
354 if (!X509_check_private_key(signer, pk)) {
355 ERR_raise(ERR_LIB_CMS, CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);
356 return NULL;
357 }
358 sd = cms_signed_data_init(cms);
359 if (!sd)
360 goto err;
361 si = M_ASN1_new_of(CMS_SignerInfo);
362 if (!si) {
363 ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
364 goto err;
365 }
366 /* Call for side-effect of computing hash and caching extensions */
367 X509_check_purpose(signer, -1, -1);
368
369 if (!X509_up_ref(signer))
370 goto err;
371 if (!EVP_PKEY_up_ref(pk)) {
372 X509_free(signer);
373 goto err;
374 }
375
376 si->cms_ctx = ctx;
377 si->pkey = pk;
378 si->signer = signer;
379 si->mctx = EVP_MD_CTX_new();
380 si->pctx = NULL;
381 si->omit_signing_time = 0;
382
383 if (si->mctx == NULL) {
384 ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
385 goto err;
386 }
387
388 if (flags & CMS_USE_KEYID) {
389 si->version = 3;
390 if (sd->version < 3)
391 sd->version = 3;
392 type = CMS_SIGNERINFO_KEYIDENTIFIER;
393 } else {
394 type = CMS_SIGNERINFO_ISSUER_SERIAL;
395 si->version = 1;
396 }
397
398 if (!ossl_cms_set1_SignerIdentifier(si->sid, signer, type, ctx))
399 goto err;
400
401 if (md == NULL) {
402 int def_nid;
403
404 if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) {
405 ERR_raise_data(ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST,
406 "pkey nid=%d", EVP_PKEY_get_id(pk));
407 goto err;
408 }
409 md = EVP_get_digestbynid(def_nid);
410 if (md == NULL) {
411 ERR_raise_data(ERR_LIB_CMS, CMS_R_NO_DEFAULT_DIGEST,
412 "default md nid=%d", def_nid);
413 goto err;
414 }
415 }
416
417 X509_ALGOR_set_md(si->digestAlgorithm, md);
418
419 /* See if digest is present in digestAlgorithms */
420 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
421 const ASN1_OBJECT *aoid;
422 char name[OSSL_MAX_NAME_SIZE];
423
424 alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
425 X509_ALGOR_get0(&aoid, NULL, NULL, alg);
426 OBJ_obj2txt(name, sizeof(name), aoid, 0);
427 if (EVP_MD_is_a(md, name))
428 break;
429 }
430
431 if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) {
432 if ((alg = X509_ALGOR_new()) == NULL) {
433 ERR_raise(ERR_LIB_CMS, ERR_R_ASN1_LIB);
434 goto err;
435 }
436 X509_ALGOR_set_md(alg, md);
437 if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) {
438 X509_ALGOR_free(alg);
439 ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB);
440 goto err;
441 }
442 }
443
444 if (!(flags & CMS_KEY_PARAM) && !cms_sd_asn1_ctrl(si, 0)) {
445 ERR_raise_data(ERR_LIB_CMS, CMS_R_UNSUPPORTED_SIGNATURE_ALGORITHM,
446 "pkey nid=%d", EVP_PKEY_get_id(pk));
447 goto err;
448 }
449 if (!(flags & CMS_NOATTR)) {
450 /*
451 * Initialize signed attributes structure so other attributes
452 * such as signing time etc are added later even if we add none here.
453 */
454 if (!si->signedAttrs) {
455 si->signedAttrs = sk_X509_ATTRIBUTE_new_null();
456 if (!si->signedAttrs) {
457 ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB);
458 goto err;
459 }
460 }
461
462 if (!(flags & CMS_NOSMIMECAP)) {
463 STACK_OF(X509_ALGOR) *smcap = NULL;
464
465 i = CMS_add_standard_smimecap(&smcap);
466 if (i)
467 i = CMS_add_smimecap(si, smcap);
468 sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);
469 if (!i) {
470 ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
471 goto err;
472 }
473 }
474 if ((flags & CMS_NO_SIGNING_TIME) != 0) {
475 /*
476 * The signing-time signed attribute (NID_pkcs9_signingTime)
477 * would normally be added later, in CMS_SignerInfo_sign(),
478 * unless we set this flag here
479 */
480 si->omit_signing_time = 1;
481 }
482 if (flags & CMS_CADES) {
483 ESS_SIGNING_CERT *sc = NULL;
484 ESS_SIGNING_CERT_V2 *sc2 = NULL;
485 int add_sc;
486
487 if (md == NULL || EVP_MD_is_a(md, SN_sha1)) {
488 if ((sc = OSSL_ESS_signing_cert_new_init(signer,
489 NULL, 1)) == NULL)
490 goto err;
491 add_sc = ossl_cms_add1_signing_cert(si, sc);
492 ESS_SIGNING_CERT_free(sc);
493 } else {
494 if ((sc2 = OSSL_ESS_signing_cert_v2_new_init(md, signer,
495 NULL, 1)) == NULL)
496 goto err;
497 add_sc = ossl_cms_add1_signing_cert_v2(si, sc2);
498 ESS_SIGNING_CERT_V2_free(sc2);
499 }
500 if (!add_sc)
501 goto err;
502 }
503 if (flags & CMS_REUSE_DIGEST) {
504 if (!cms_copy_messageDigest(cms, si))
505 goto err;
506 if (!cms_set_si_contentType_attr(cms, si))
507 goto err;
508 if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) &&
509 !CMS_SignerInfo_sign(si))
510 goto err;
511 }
512 }
513
514 if (!(flags & CMS_NOCERTS)) {
515 /* NB ignore -1 return for duplicate cert */
516 if (!CMS_add1_cert(cms, signer)) {
517 ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
518 goto err;
519 }
520 }
521
522 if (flags & CMS_KEY_PARAM) {
523 if (flags & CMS_NOATTR) {
524 si->pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx),
525 si->pkey,
526 ossl_cms_ctx_get0_propq(ctx));
527 if (si->pctx == NULL)
528 goto err;
529 if (EVP_PKEY_sign_init(si->pctx) <= 0)
530 goto err;
531 if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
532 goto err;
533 } else if (EVP_DigestSignInit_ex(si->mctx, &si->pctx,
534 EVP_MD_get0_name(md),
535 ossl_cms_ctx_get0_libctx(ctx),
536 ossl_cms_ctx_get0_propq(ctx),
537 pk, NULL) <= 0) {
538 si->pctx = NULL;
539 goto err;
540 }
541 else {
542 EVP_MD_CTX_set_flags(si->mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
543 }
544 }
545
546 if (sd->signerInfos == NULL)
547 sd->signerInfos = sk_CMS_SignerInfo_new_null();
548 if (sd->signerInfos == NULL || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) {
549 ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB);
550 goto err;
551 }
552
553 return si;
554
555 err:
556 M_ASN1_free_of(si, CMS_SignerInfo);
557 return NULL;
558
559 }
560
ossl_cms_SignerInfos_set_cmsctx(CMS_ContentInfo * cms)561 void ossl_cms_SignerInfos_set_cmsctx(CMS_ContentInfo *cms)
562 {
563 int i;
564 CMS_SignerInfo *si;
565 STACK_OF(CMS_SignerInfo) *sinfos;
566 const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms);
567
568 ERR_set_mark();
569 sinfos = CMS_get0_SignerInfos(cms);
570 ERR_pop_to_mark(); /* removes error in case sinfos == NULL */
571
572 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
573 si = sk_CMS_SignerInfo_value(sinfos, i);
574 if (si != NULL)
575 si->cms_ctx = ctx;
576 }
577 }
578
cms_add1_signingTime(CMS_SignerInfo * si,ASN1_TIME * t)579 static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)
580 {
581 ASN1_TIME *tt;
582 int r = 0;
583
584 if (t != NULL)
585 tt = t;
586 else
587 tt = X509_gmtime_adj(NULL, 0);
588
589 if (tt == NULL) {
590 ERR_raise(ERR_LIB_CMS, ERR_R_X509_LIB);
591 goto err;
592 }
593
594 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,
595 tt->type, tt, -1) <= 0) {
596 ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
597 goto err;
598 }
599
600 r = 1;
601 err:
602 if (t == NULL)
603 ASN1_TIME_free(tt);
604
605 return r;
606
607 }
608
CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo * si)609 EVP_PKEY_CTX *CMS_SignerInfo_get0_pkey_ctx(CMS_SignerInfo *si)
610 {
611 return si->pctx;
612 }
613
CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo * si)614 EVP_MD_CTX *CMS_SignerInfo_get0_md_ctx(CMS_SignerInfo *si)
615 {
616 return si->mctx;
617 }
618
STACK_OF(CMS_SignerInfo)619 STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)
620 {
621 CMS_SignedData *sd = cms_get0_signed(cms);
622
623 return sd != NULL ? sd->signerInfos : NULL;
624 }
625
STACK_OF(X509)626 STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
627 {
628 STACK_OF(X509) *signers = NULL;
629 STACK_OF(CMS_SignerInfo) *sinfos;
630 CMS_SignerInfo *si;
631 int i;
632
633 sinfos = CMS_get0_SignerInfos(cms);
634 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
635 si = sk_CMS_SignerInfo_value(sinfos, i);
636 if (si->signer != NULL) {
637 if (!ossl_x509_add_cert_new(&signers, si->signer,
638 X509_ADD_FLAG_DEFAULT)) {
639 sk_X509_free(signers);
640 return NULL;
641 }
642 }
643 }
644 return signers;
645 }
646
CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo * si,X509 * signer)647 void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
648 {
649 if (signer != NULL) {
650 if (!X509_up_ref(signer))
651 return;
652 EVP_PKEY_free(si->pkey);
653 si->pkey = X509_get_pubkey(signer);
654 }
655 X509_free(si->signer);
656 si->signer = signer;
657 }
658
CMS_SignerInfo_get0_signer_id(CMS_SignerInfo * si,ASN1_OCTET_STRING ** keyid,X509_NAME ** issuer,ASN1_INTEGER ** sno)659 int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si,
660 ASN1_OCTET_STRING **keyid,
661 X509_NAME **issuer, ASN1_INTEGER **sno)
662 {
663 return ossl_cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno);
664 }
665
CMS_SignerInfo_cert_cmp(CMS_SignerInfo * si,X509 * cert)666 int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert)
667 {
668 return ossl_cms_SignerIdentifier_cert_cmp(si->sid, cert);
669 }
670
CMS_set1_signers_certs(CMS_ContentInfo * cms,STACK_OF (X509)* scerts,unsigned int flags)671 int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts,
672 unsigned int flags)
673 {
674 CMS_SignedData *sd;
675 CMS_SignerInfo *si;
676 CMS_CertificateChoices *cch;
677 STACK_OF(CMS_CertificateChoices) *certs;
678 X509 *x;
679 int i, j;
680 int ret = 0;
681
682 sd = cms_get0_signed(cms);
683 if (sd == NULL)
684 return -1;
685 certs = sd->certificates;
686 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
687 si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
688 if (si->signer != NULL)
689 continue;
690
691 for (j = 0; j < sk_X509_num(scerts); j++) {
692 x = sk_X509_value(scerts, j);
693 if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
694 CMS_SignerInfo_set1_signer_cert(si, x);
695 ret++;
696 break;
697 }
698 }
699
700 if (si->signer != NULL || (flags & CMS_NOINTERN))
701 continue;
702
703 for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) {
704 cch = sk_CMS_CertificateChoices_value(certs, j);
705 if (cch->type != CMS_CERTCHOICE_CERT)
706 continue;
707 x = cch->d.certificate;
708 if (CMS_SignerInfo_cert_cmp(si, x) == 0) {
709 CMS_SignerInfo_set1_signer_cert(si, x);
710 ret++;
711 break;
712 }
713 }
714 }
715 return ret;
716 }
717
CMS_SignerInfo_get0_algs(CMS_SignerInfo * si,EVP_PKEY ** pk,X509 ** signer,X509_ALGOR ** pdig,X509_ALGOR ** psig)718 void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk,
719 X509 **signer, X509_ALGOR **pdig,
720 X509_ALGOR **psig)
721 {
722 if (pk != NULL)
723 *pk = si->pkey;
724 if (signer != NULL)
725 *signer = si->signer;
726 if (pdig != NULL)
727 *pdig = si->digestAlgorithm;
728 if (psig != NULL)
729 *psig = si->signatureAlgorithm;
730 }
731
CMS_SignerInfo_get0_signature(CMS_SignerInfo * si)732 ASN1_OCTET_STRING *CMS_SignerInfo_get0_signature(CMS_SignerInfo *si)
733 {
734 return si->signature;
735 }
736
cms_SignerInfo_content_sign(CMS_ContentInfo * cms,CMS_SignerInfo * si,BIO * chain,const unsigned char * md,unsigned int mdlen)737 static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms,
738 CMS_SignerInfo *si, BIO *chain,
739 const unsigned char *md,
740 unsigned int mdlen)
741 {
742 EVP_MD_CTX *mctx = EVP_MD_CTX_new();
743 int r = 0;
744 EVP_PKEY_CTX *pctx = NULL;
745 const CMS_CTX *ctx = ossl_cms_get0_cmsctx(cms);
746
747 if (mctx == NULL) {
748 ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
749 return 0;
750 }
751
752 if (si->pkey == NULL) {
753 ERR_raise(ERR_LIB_CMS, CMS_R_NO_PRIVATE_KEY);
754 goto err;
755 }
756
757 if (!ossl_cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
758 goto err;
759 /* Set SignerInfo algorithm details if we used custom parameter */
760 if (si->pctx && !cms_sd_asn1_ctrl(si, 0))
761 goto err;
762
763 /*
764 * If any signed attributes calculate and add messageDigest attribute
765 */
766 if (CMS_signed_get_attr_count(si) >= 0) {
767 unsigned char computed_md[EVP_MAX_MD_SIZE];
768
769 if (md == NULL) {
770 if (!EVP_DigestFinal_ex(mctx, computed_md, &mdlen))
771 goto err;
772 md = computed_md;
773 }
774 if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
775 V_ASN1_OCTET_STRING, md, mdlen))
776 goto err;
777 /* Copy content type across */
778 if (!cms_set_si_contentType_attr(cms, si))
779 goto err;
780
781 if (!CMS_SignerInfo_sign(si))
782 goto err;
783 } else if (si->pctx) {
784 unsigned char *sig;
785 size_t siglen;
786 unsigned char computed_md[EVP_MAX_MD_SIZE];
787
788 pctx = si->pctx;
789 si->pctx = NULL;
790 if (md == NULL) {
791 if (!EVP_DigestFinal_ex(mctx, computed_md, &mdlen))
792 goto err;
793 md = computed_md;
794 }
795 siglen = EVP_PKEY_get_size(si->pkey);
796 if (siglen == 0 || (sig = OPENSSL_malloc(siglen)) == NULL)
797 goto err;
798 if (EVP_PKEY_sign(pctx, sig, &siglen, md, mdlen) <= 0) {
799 OPENSSL_free(sig);
800 goto err;
801 }
802 ASN1_STRING_set0(si->signature, sig, siglen);
803 } else {
804 unsigned char *sig;
805 unsigned int siglen;
806
807 if (md != NULL) {
808 ERR_raise(ERR_LIB_CMS, CMS_R_OPERATION_UNSUPPORTED);
809 goto err;
810 }
811 siglen = EVP_PKEY_get_size(si->pkey);
812 if (siglen == 0 || (sig = OPENSSL_malloc(siglen)) == NULL)
813 goto err;
814 if (!EVP_SignFinal_ex(mctx, sig, &siglen, si->pkey,
815 ossl_cms_ctx_get0_libctx(ctx),
816 ossl_cms_ctx_get0_propq(ctx))) {
817 ERR_raise(ERR_LIB_CMS, CMS_R_SIGNFINAL_ERROR);
818 OPENSSL_free(sig);
819 goto err;
820 }
821 ASN1_STRING_set0(si->signature, sig, siglen);
822 }
823
824 r = 1;
825
826 err:
827 EVP_MD_CTX_free(mctx);
828 EVP_PKEY_CTX_free(pctx);
829 return r;
830
831 }
832
ossl_cms_SignedData_final(CMS_ContentInfo * cms,BIO * chain,const unsigned char * precomp_md,unsigned int precomp_mdlen)833 int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain,
834 const unsigned char *precomp_md,
835 unsigned int precomp_mdlen)
836 {
837 STACK_OF(CMS_SignerInfo) *sinfos;
838 CMS_SignerInfo *si;
839 int i;
840
841 sinfos = CMS_get0_SignerInfos(cms);
842 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
843 si = sk_CMS_SignerInfo_value(sinfos, i);
844 if (!cms_SignerInfo_content_sign(cms, si, chain,
845 precomp_md, precomp_mdlen))
846 return 0;
847 }
848 cms->d.signedData->encapContentInfo->partial = 0;
849 return 1;
850 }
851
CMS_SignerInfo_sign(CMS_SignerInfo * si)852 int CMS_SignerInfo_sign(CMS_SignerInfo *si)
853 {
854 EVP_MD_CTX *mctx = si->mctx;
855 EVP_PKEY_CTX *pctx = NULL;
856 unsigned char *abuf = NULL;
857 int alen;
858 size_t siglen;
859 const CMS_CTX *ctx = si->cms_ctx;
860 char md_name_buf[OSSL_MAX_NAME_SIZE], *md_name;
861
862 if (OBJ_obj2txt(md_name_buf, sizeof(md_name_buf),
863 si->digestAlgorithm->algorithm, 0) <= 0)
864 return 0;
865 md_name = cms_signature_nomd(si->pkey) ? NULL : md_name_buf;
866
867 if (!si->omit_signing_time
868 && CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) {
869 if (!cms_add1_signingTime(si, NULL))
870 goto err;
871 }
872
873 if (!ossl_cms_si_check_attributes(si))
874 goto err;
875
876 if (si->pctx) {
877 pctx = si->pctx;
878 } else {
879 EVP_MD_CTX_reset(mctx);
880 if (EVP_DigestSignInit_ex(mctx, &pctx, md_name,
881 ossl_cms_ctx_get0_libctx(ctx),
882 ossl_cms_ctx_get0_propq(ctx), si->pkey,
883 NULL) <= 0)
884 goto err;
885 EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
886 si->pctx = pctx;
887 }
888
889 if (md_name == NULL) {
890 if (ASN1_item_sign_ctx(ASN1_ITEM_rptr(CMS_Attributes_Sign), NULL,
891 NULL, si->signature, si->signedAttrs, mctx) <= 0)
892 goto err;
893 return 1;
894 }
895
896 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
897 ASN1_ITEM_rptr(CMS_Attributes_Sign));
898 if (alen < 0 || abuf == NULL)
899 goto err;
900 if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
901 goto err;
902 if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
903 goto err;
904 OPENSSL_free(abuf);
905 abuf = OPENSSL_malloc(siglen);
906 if (abuf == NULL)
907 goto err;
908 if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
909 goto err;
910
911 EVP_MD_CTX_reset(mctx);
912
913 ASN1_STRING_set0(si->signature, abuf, siglen);
914
915 return 1;
916
917 err:
918 OPENSSL_free(abuf);
919 EVP_MD_CTX_reset(mctx);
920 return 0;
921 }
922
CMS_SignerInfo_verify(CMS_SignerInfo * si)923 int CMS_SignerInfo_verify(CMS_SignerInfo *si)
924 {
925 EVP_MD_CTX *mctx = NULL;
926 unsigned char *abuf = NULL;
927 int alen, r = -1;
928 char name[OSSL_MAX_NAME_SIZE];
929 const EVP_MD *md;
930 EVP_MD *fetched_md = NULL;
931 const CMS_CTX *ctx = si->cms_ctx;
932 OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx);
933 const char *propq = ossl_cms_ctx_get0_propq(ctx);
934
935 if (si->pkey == NULL) {
936 ERR_raise(ERR_LIB_CMS, CMS_R_NO_PUBLIC_KEY);
937 return -1;
938 }
939
940 if (!ossl_cms_si_check_attributes(si))
941 return -1;
942
943 if (cms_signature_nomd(si->pkey)) {
944 r = ASN1_item_verify_ex(ASN1_ITEM_rptr(CMS_Attributes_Sign),
945 si->signatureAlgorithm, si->signature,
946 si->signedAttrs, NULL, si->pkey,
947 libctx, propq);
948 if (r <= 0)
949 ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE);
950 return r;
951 }
952
953 OBJ_obj2txt(name, sizeof(name), si->digestAlgorithm->algorithm, 0);
954
955 (void)ERR_set_mark();
956 fetched_md = EVP_MD_fetch(libctx, name, propq);
957
958 if (fetched_md != NULL)
959 md = fetched_md;
960 else
961 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
962 if (md == NULL) {
963 (void)ERR_clear_last_mark();
964 ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM);
965 return -1;
966 }
967 (void)ERR_pop_to_mark();
968
969 if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) {
970 ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
971 goto err;
972 }
973 mctx = si->mctx;
974 if (si->pctx != NULL) {
975 EVP_PKEY_CTX_free(si->pctx);
976 si->pctx = NULL;
977 }
978 if (EVP_DigestVerifyInit_ex(mctx, &si->pctx, EVP_MD_get0_name(md), libctx,
979 propq, si->pkey, NULL) <= 0) {
980 si->pctx = NULL;
981 goto err;
982 }
983 EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
984
985 if (!cms_sd_asn1_ctrl(si, 1))
986 goto err;
987
988 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
989 ASN1_ITEM_rptr(CMS_Attributes_Verify));
990 if (abuf == NULL || alen < 0)
991 goto err;
992 r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
993 OPENSSL_free(abuf);
994 if (r <= 0) {
995 r = -1;
996 goto err;
997 }
998 r = EVP_DigestVerifyFinal(mctx,
999 si->signature->data, si->signature->length);
1000 if (r <= 0)
1001 ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE);
1002 err:
1003 EVP_MD_free(fetched_md);
1004 EVP_MD_CTX_reset(mctx);
1005 return r;
1006 }
1007
1008 /* Create a chain of digest BIOs from a CMS ContentInfo */
ossl_cms_SignedData_init_bio(CMS_ContentInfo * cms)1009 BIO *ossl_cms_SignedData_init_bio(CMS_ContentInfo *cms)
1010 {
1011 int i;
1012 CMS_SignedData *sd;
1013 BIO *chain = NULL;
1014
1015 sd = cms_get0_signed(cms);
1016 if (sd == NULL)
1017 return NULL;
1018 if (cms->d.signedData->encapContentInfo->partial)
1019 cms_sd_set_version(sd);
1020 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
1021 X509_ALGOR *digestAlgorithm;
1022 BIO *mdbio;
1023
1024 digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
1025 mdbio = ossl_cms_DigestAlgorithm_init_bio(digestAlgorithm,
1026 ossl_cms_get0_cmsctx(cms));
1027 if (mdbio == NULL)
1028 goto err;
1029 if (chain != NULL)
1030 BIO_push(chain, mdbio);
1031 else
1032 chain = mdbio;
1033 }
1034 return chain;
1035 err:
1036 BIO_free_all(chain);
1037 return NULL;
1038 }
1039
CMS_SignerInfo_verify_content(CMS_SignerInfo * si,BIO * chain)1040 int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
1041 {
1042 ASN1_OCTET_STRING *os = NULL;
1043 EVP_MD_CTX *mctx = EVP_MD_CTX_new();
1044 EVP_PKEY_CTX *pkctx = NULL;
1045 int r = -1;
1046 unsigned char mval[EVP_MAX_MD_SIZE];
1047 unsigned int mlen;
1048
1049 if (mctx == NULL) {
1050 ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
1051 goto err;
1052 }
1053 /* If we have any signed attributes look for messageDigest value */
1054 if (CMS_signed_get_attr_count(si) >= 0) {
1055 os = CMS_signed_get0_data_by_OBJ(si,
1056 OBJ_nid2obj(NID_pkcs9_messageDigest),
1057 -3, V_ASN1_OCTET_STRING);
1058 if (os == NULL) {
1059 ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
1060 goto err;
1061 }
1062 }
1063
1064 if (!ossl_cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
1065 goto err;
1066
1067 if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) {
1068 ERR_raise(ERR_LIB_CMS, CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
1069 goto err;
1070 }
1071
1072 /* If messageDigest found compare it */
1073 if (os != NULL) {
1074 if (mlen != (unsigned int)os->length) {
1075 ERR_raise(ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
1076 goto err;
1077 }
1078
1079 if (memcmp(mval, os->data, mlen)) {
1080 ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE);
1081 r = 0;
1082 } else {
1083 r = 1;
1084 }
1085 } else {
1086 const EVP_MD *md = EVP_MD_CTX_get0_md(mctx);
1087 const CMS_CTX *ctx = si->cms_ctx;
1088
1089 pkctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx),
1090 si->pkey,
1091 ossl_cms_ctx_get0_propq(ctx));
1092 if (pkctx == NULL)
1093 goto err;
1094 if (EVP_PKEY_verify_init(pkctx) <= 0)
1095 goto err;
1096 if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
1097 goto err;
1098 si->pctx = pkctx;
1099 if (!cms_sd_asn1_ctrl(si, 1)) {
1100 si->pctx = NULL;
1101 goto err;
1102 }
1103 si->pctx = NULL;
1104 r = EVP_PKEY_verify(pkctx, si->signature->data,
1105 si->signature->length, mval, mlen);
1106 if (r <= 0) {
1107 ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE);
1108 r = 0;
1109 }
1110 }
1111
1112 err:
1113 EVP_PKEY_CTX_free(pkctx);
1114 EVP_MD_CTX_free(mctx);
1115 return r;
1116
1117 }
1118
CMS_SignedData_verify(CMS_SignedData * sd,BIO * detached_data,STACK_OF (X509)* scerts,X509_STORE * store,STACK_OF (X509)* extra,STACK_OF (X509_CRL)* crls,unsigned int flags,OSSL_LIB_CTX * libctx,const char * propq)1119 BIO *CMS_SignedData_verify(CMS_SignedData *sd, BIO *detached_data,
1120 STACK_OF(X509) *scerts, X509_STORE *store,
1121 STACK_OF(X509) *extra, STACK_OF(X509_CRL) *crls,
1122 unsigned int flags,
1123 OSSL_LIB_CTX *libctx, const char *propq)
1124 {
1125 CMS_ContentInfo *ci;
1126 BIO *bio = NULL;
1127 int i, res = 0;
1128
1129 if (sd == NULL) {
1130 ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER);
1131 return NULL;
1132 }
1133
1134 if ((ci = CMS_ContentInfo_new_ex(libctx, propq)) == NULL)
1135 return NULL;
1136 if ((bio = BIO_new(BIO_s_mem())) == NULL)
1137 goto end;
1138 ci->contentType = OBJ_nid2obj(NID_pkcs7_signed);
1139 ci->d.signedData = sd;
1140
1141 for (i = 0; i < sk_X509_num(extra); i++)
1142 if (!CMS_add1_cert(ci, sk_X509_value(extra, i)))
1143 goto end;
1144 for (i = 0; i < sk_X509_CRL_num(crls); i++)
1145 if (!CMS_add1_crl(ci, sk_X509_CRL_value(crls, i)))
1146 goto end;
1147 res = CMS_verify(ci, scerts, store, detached_data, bio, flags);
1148
1149 end:
1150 if (ci != NULL)
1151 ci->d.signedData = NULL; /* do not indirectly free |sd| */
1152 CMS_ContentInfo_free(ci);
1153 if (!res) {
1154 BIO_free(bio);
1155 bio = NULL;
1156 }
1157 return bio;
1158 }
1159
CMS_add_smimecap(CMS_SignerInfo * si,STACK_OF (X509_ALGOR)* algs)1160 int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
1161 {
1162 unsigned char *smder = NULL;
1163 int smderlen, r;
1164
1165 smderlen = i2d_X509_ALGORS(algs, &smder);
1166 if (smderlen <= 0)
1167 return 0;
1168 r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
1169 V_ASN1_SEQUENCE, smder, smderlen);
1170 OPENSSL_free(smder);
1171 return r;
1172 }
1173
CMS_add_simple_smimecap(STACK_OF (X509_ALGOR)** algs,int algnid,int keysize)1174 int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
1175 int algnid, int keysize)
1176 {
1177 X509_ALGOR *alg;
1178 ASN1_INTEGER *key = NULL;
1179
1180 if (keysize > 0) {
1181 key = ASN1_INTEGER_new();
1182 if (key == NULL || !ASN1_INTEGER_set(key, keysize)) {
1183 ASN1_INTEGER_free(key);
1184 return 0;
1185 }
1186 }
1187 alg = ossl_X509_ALGOR_from_nid(algnid, key != NULL ? V_ASN1_INTEGER :
1188 V_ASN1_UNDEF, key);
1189 if (alg == NULL) {
1190 ASN1_INTEGER_free(key);
1191 return 0;
1192 }
1193
1194 if (*algs == NULL)
1195 *algs = sk_X509_ALGOR_new_null();
1196 if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) {
1197 X509_ALGOR_free(alg);
1198 return 0;
1199 }
1200 return 1;
1201 }
1202
1203 /* Check to see if a cipher exists and if so add S/MIME capabilities */
cms_add_cipher_smcap(STACK_OF (X509_ALGOR)** sk,int nid,int arg)1204 static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
1205 {
1206 if (EVP_get_cipherbynid(nid))
1207 return CMS_add_simple_smimecap(sk, nid, arg);
1208 return 1;
1209 }
1210
cms_add_digest_smcap(STACK_OF (X509_ALGOR)** sk,int nid,int arg)1211 static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
1212 {
1213 if (EVP_get_digestbynid(nid))
1214 return CMS_add_simple_smimecap(sk, nid, arg);
1215 return 1;
1216 }
1217
CMS_add_standard_smimecap(STACK_OF (X509_ALGOR)** smcap)1218 int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
1219 {
1220 if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
1221 || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1)
1222 || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1)
1223 || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
1224 || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
1225 || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
1226 || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
1227 || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
1228 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
1229 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
1230 || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
1231 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
1232 return 0;
1233 return 1;
1234 }
1235