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 = OBJ_nid2obj(NID_pkcs7_data);
46 cms->d.signedData->encapContentInfo->partial = 1;
47 ASN1_OBJECT_free(cms->contentType);
48 cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);
49 return cms->d.signedData;
50 }
51 return cms_get0_signed(cms);
52 }
53
54 /* Just initialise SignedData e.g. for certs only structure */
CMS_SignedData_init(CMS_ContentInfo * cms)55 int CMS_SignedData_init(CMS_ContentInfo *cms)
56 {
57 if (cms_signed_data_init(cms))
58 return 1;
59 else
60 return 0;
61 }
62
63 /* Check structures and fixup version numbers (if necessary) */
cms_sd_set_version(CMS_SignedData * sd)64 static void cms_sd_set_version(CMS_SignedData *sd)
65 {
66 int i;
67 CMS_CertificateChoices *cch;
68 CMS_RevocationInfoChoice *rch;
69 CMS_SignerInfo *si;
70
71 for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) {
72 cch = sk_CMS_CertificateChoices_value(sd->certificates, i);
73 if (cch->type == CMS_CERTCHOICE_OTHER) {
74 if (sd->version < 5)
75 sd->version = 5;
76 } else if (cch->type == CMS_CERTCHOICE_V2ACERT) {
77 if (sd->version < 4)
78 sd->version = 4;
79 } else if (cch->type == CMS_CERTCHOICE_V1ACERT) {
80 if (sd->version < 3)
81 sd->version = 3;
82 }
83 }
84
85 for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) {
86 rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);
87 if (rch->type == CMS_REVCHOICE_OTHER) {
88 if (sd->version < 5)
89 sd->version = 5;
90 }
91 }
92
93 if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)
94 && (sd->version < 3))
95 sd->version = 3;
96
97 for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) {
98 si = sk_CMS_SignerInfo_value(sd->signerInfos, i);
99 if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
100 if (si->version < 3)
101 si->version = 3;
102 if (sd->version < 3)
103 sd->version = 3;
104 } else if (si->version < 1) {
105 si->version = 1;
106 }
107 }
108
109 if (sd->version < 1)
110 sd->version = 1;
111 }
112
113 /*
114 * RFC 5652 Section 11.1 Content Type
115 * The content-type attribute within signed-data MUST
116 * 1) be present if there are signed attributes
117 * 2) match the content type in the signed-data,
118 * 3) be a signed attribute.
119 * 4) not have more than one copy of the attribute.
120 *
121 * Note that since the CMS_SignerInfo_sign() always adds the "signing time"
122 * attribute, the content type attribute MUST be added also.
123 * Assumptions: This assumes that the attribute does not already exist.
124 */
cms_set_si_contentType_attr(CMS_ContentInfo * cms,CMS_SignerInfo * si)125 static int cms_set_si_contentType_attr(CMS_ContentInfo *cms, CMS_SignerInfo *si)
126 {
127 ASN1_OBJECT *ctype = cms->d.signedData->encapContentInfo->eContentType;
128
129 /* Add the contentType attribute */
130 return CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType,
131 V_ASN1_OBJECT, ctype, -1)
132 > 0;
133 }
134
135 /* Copy an existing messageDigest value */
cms_copy_messageDigest(CMS_ContentInfo * cms,CMS_SignerInfo * si)136 static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)
137 {
138 STACK_OF(CMS_SignerInfo) *sinfos;
139 CMS_SignerInfo *sitmp;
140 int i;
141
142 sinfos = CMS_get0_SignerInfos(cms);
143 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
144 ASN1_OCTET_STRING *messageDigest;
145
146 sitmp = sk_CMS_SignerInfo_value(sinfos, i);
147 if (sitmp == si)
148 continue;
149 if (CMS_signed_get_attr_count(sitmp) < 0)
150 continue;
151 if (OBJ_cmp(si->digestAlgorithm->algorithm,
152 sitmp->digestAlgorithm->algorithm))
153 continue;
154 messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,
155 OBJ_nid2obj(NID_pkcs9_messageDigest),
156 -3, V_ASN1_OCTET_STRING);
157 if (!messageDigest) {
158 ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
159 return 0;
160 }
161
162 if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,
163 V_ASN1_OCTET_STRING,
164 messageDigest, -1))
165 return 1;
166 else
167 return 0;
168 }
169 ERR_raise(ERR_LIB_CMS, CMS_R_NO_MATCHING_DIGEST);
170 return 0;
171 }
172
ossl_cms_set1_SignerIdentifier(CMS_SignerIdentifier * sid,X509 * cert,int type,const CMS_CTX * ctx)173 int ossl_cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert,
174 int type, const CMS_CTX *ctx)
175 {
176 switch (type) {
177 case CMS_SIGNERINFO_ISSUER_SERIAL:
178 if (!ossl_cms_set1_ias(&sid->d.issuerAndSerialNumber, cert))
179 return 0;
180 break;
181
182 case CMS_SIGNERINFO_KEYIDENTIFIER:
183 if (!ossl_cms_set1_keyid(&sid->d.subjectKeyIdentifier, cert))
184 return 0;
185 break;
186
187 default:
188 ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_ID);
189 return 0;
190 }
191
192 sid->type = type;
193
194 return 1;
195 }
196
ossl_cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier * sid,ASN1_OCTET_STRING ** keyid,X509_NAME ** issuer,ASN1_INTEGER ** sno)197 int ossl_cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,
198 ASN1_OCTET_STRING **keyid,
199 X509_NAME **issuer,
200 ASN1_INTEGER **sno)
201 {
202 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) {
203 if (issuer)
204 *issuer = sid->d.issuerAndSerialNumber->issuer;
205 if (sno)
206 *sno = sid->d.issuerAndSerialNumber->serialNumber;
207 } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) {
208 if (keyid)
209 *keyid = sid->d.subjectKeyIdentifier;
210 } else {
211 return 0;
212 }
213 return 1;
214 }
215
ossl_cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier * sid,X509 * cert)216 int ossl_cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)
217 {
218 if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)
219 return ossl_cms_ias_cert_cmp(sid->d.issuerAndSerialNumber, cert);
220 else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)
221 return ossl_cms_keyid_cert_cmp(sid->d.subjectKeyIdentifier, cert);
222 else
223 return -1;
224 }
225
cms_signature_nomd(EVP_PKEY * pkey)226 static int cms_signature_nomd(EVP_PKEY *pkey)
227 {
228 char def_md[80];
229
230 return EVP_PKEY_get_default_digest_name(pkey, def_md, sizeof(def_md)) == 2
231 && strcmp(def_md, "UNDEF") == 0
232 ? 1
233 : 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))
490 == NULL)
491 goto err;
492 add_sc = ossl_cms_add1_signing_cert(si, sc);
493 ESS_SIGNING_CERT_free(sc);
494 } else {
495 if ((sc2 = OSSL_ESS_signing_cert_v2_new_init(md, signer,
496 NULL, 1))
497 == NULL)
498 goto err;
499 add_sc = ossl_cms_add1_signing_cert_v2(si, sc2);
500 ESS_SIGNING_CERT_V2_free(sc2);
501 }
502 if (!add_sc)
503 goto err;
504 }
505 if (flags & CMS_REUSE_DIGEST) {
506 if (!cms_copy_messageDigest(cms, si))
507 goto err;
508 if (!cms_set_si_contentType_attr(cms, si))
509 goto err;
510 if (!(flags & (CMS_PARTIAL | CMS_KEY_PARAM)) && !CMS_SignerInfo_sign(si))
511 goto err;
512 }
513 }
514
515 if (!(flags & CMS_NOCERTS)) {
516 /* NB ignore -1 return for duplicate cert */
517 if (!CMS_add1_cert(cms, signer)) {
518 ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
519 goto err;
520 }
521 }
522
523 if (flags & CMS_KEY_PARAM) {
524 if (flags & CMS_NOATTR) {
525 si->pctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx),
526 si->pkey,
527 ossl_cms_ctx_get0_propq(ctx));
528 if (si->pctx == NULL)
529 goto err;
530 if (EVP_PKEY_sign_init(si->pctx) <= 0)
531 goto err;
532 if (EVP_PKEY_CTX_set_signature_md(si->pctx, md) <= 0)
533 goto err;
534 } else if (EVP_DigestSignInit_ex(si->mctx, &si->pctx,
535 EVP_MD_get0_name(md),
536 ossl_cms_ctx_get0_libctx(ctx),
537 ossl_cms_ctx_get0_propq(ctx),
538 pk, NULL)
539 <= 0) {
540 si->pctx = NULL;
541 goto err;
542 } else {
543 EVP_MD_CTX_set_flags(si->mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
544 }
545 }
546
547 if (sd->signerInfos == NULL)
548 sd->signerInfos = sk_CMS_SignerInfo_new_null();
549 if (sd->signerInfos == NULL || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) {
550 ERR_raise(ERR_LIB_CMS, ERR_R_CRYPTO_LIB);
551 goto err;
552 }
553
554 return si;
555
556 err:
557 M_ASN1_free_of(si, CMS_SignerInfo);
558 return NULL;
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)
596 <= 0) {
597 ERR_raise(ERR_LIB_CMS, ERR_R_CMS_LIB);
598 goto err;
599 }
600
601 r = 1;
602 err:
603 if (t == NULL)
604 ASN1_TIME_free(tt);
605
606 return r;
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
ossl_cms_SignedData_final(CMS_ContentInfo * cms,BIO * chain,const unsigned char * precomp_md,unsigned int precomp_mdlen)832 int ossl_cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain,
833 const unsigned char *precomp_md,
834 unsigned int precomp_mdlen)
835 {
836 STACK_OF(CMS_SignerInfo) *sinfos;
837 CMS_SignerInfo *si;
838 int i;
839
840 sinfos = CMS_get0_SignerInfos(cms);
841 for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) {
842 si = sk_CMS_SignerInfo_value(sinfos, i);
843 if (!cms_SignerInfo_content_sign(cms, si, chain,
844 precomp_md, precomp_mdlen))
845 return 0;
846 }
847 cms->d.signedData->encapContentInfo->partial = 0;
848 return 1;
849 }
850
CMS_SignerInfo_sign(CMS_SignerInfo * si)851 int CMS_SignerInfo_sign(CMS_SignerInfo *si)
852 {
853 EVP_MD_CTX *mctx = si->mctx;
854 EVP_PKEY_CTX *pctx = NULL;
855 unsigned char *abuf = NULL;
856 int alen;
857 size_t siglen;
858 const CMS_CTX *ctx = si->cms_ctx;
859 char md_name_buf[OSSL_MAX_NAME_SIZE], *md_name;
860
861 if (OBJ_obj2txt(md_name_buf, sizeof(md_name_buf),
862 si->digestAlgorithm->algorithm, 0)
863 <= 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)
884 <= 0)
885 goto err;
886 EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
887 si->pctx = pctx;
888 }
889
890 if (md_name == NULL) {
891 if (ASN1_item_sign_ctx(ASN1_ITEM_rptr(CMS_Attributes_Sign), NULL,
892 NULL, si->signature, si->signedAttrs, mctx)
893 <= 0)
894 goto err;
895 return 1;
896 }
897
898 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
899 ASN1_ITEM_rptr(CMS_Attributes_Sign));
900 if (alen < 0 || abuf == NULL)
901 goto err;
902 if (EVP_DigestSignUpdate(mctx, abuf, alen) <= 0)
903 goto err;
904 if (EVP_DigestSignFinal(mctx, NULL, &siglen) <= 0)
905 goto err;
906 OPENSSL_free(abuf);
907 abuf = OPENSSL_malloc(siglen);
908 if (abuf == NULL)
909 goto err;
910 if (EVP_DigestSignFinal(mctx, abuf, &siglen) <= 0)
911 goto err;
912
913 EVP_MD_CTX_reset(mctx);
914
915 ASN1_STRING_set0(si->signature, abuf, siglen);
916
917 return 1;
918
919 err:
920 OPENSSL_free(abuf);
921 EVP_MD_CTX_reset(mctx);
922 return 0;
923 }
924
CMS_SignerInfo_verify(CMS_SignerInfo * si)925 int CMS_SignerInfo_verify(CMS_SignerInfo *si)
926 {
927 EVP_MD_CTX *mctx = NULL;
928 unsigned char *abuf = NULL;
929 int alen, r = -1;
930 char name[OSSL_MAX_NAME_SIZE];
931 const EVP_MD *md;
932 EVP_MD *fetched_md = NULL;
933 const CMS_CTX *ctx = si->cms_ctx;
934 OSSL_LIB_CTX *libctx = ossl_cms_ctx_get0_libctx(ctx);
935 const char *propq = ossl_cms_ctx_get0_propq(ctx);
936
937 if (si->pkey == NULL) {
938 ERR_raise(ERR_LIB_CMS, CMS_R_NO_PUBLIC_KEY);
939 return -1;
940 }
941
942 if (!ossl_cms_si_check_attributes(si))
943 return -1;
944
945 if (cms_signature_nomd(si->pkey)) {
946 r = ASN1_item_verify_ex(ASN1_ITEM_rptr(CMS_Attributes_Sign),
947 si->signatureAlgorithm, si->signature,
948 si->signedAttrs, NULL, si->pkey,
949 libctx, propq);
950 if (r <= 0)
951 ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE);
952 return r;
953 }
954
955 OBJ_obj2txt(name, sizeof(name), si->digestAlgorithm->algorithm, 0);
956
957 (void)ERR_set_mark();
958 fetched_md = EVP_MD_fetch(libctx, name, propq);
959
960 if (fetched_md != NULL)
961 md = fetched_md;
962 else
963 md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm);
964 if (md == NULL) {
965 (void)ERR_clear_last_mark();
966 ERR_raise(ERR_LIB_CMS, CMS_R_UNKNOWN_DIGEST_ALGORITHM);
967 return -1;
968 }
969 (void)ERR_pop_to_mark();
970
971 if (si->mctx == NULL && (si->mctx = EVP_MD_CTX_new()) == NULL) {
972 ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
973 goto err;
974 }
975 mctx = si->mctx;
976 if (si->pctx != NULL) {
977 EVP_PKEY_CTX_free(si->pctx);
978 si->pctx = NULL;
979 }
980 if (EVP_DigestVerifyInit_ex(mctx, &si->pctx, EVP_MD_get0_name(md), libctx,
981 propq, si->pkey, NULL)
982 <= 0) {
983 si->pctx = NULL;
984 goto err;
985 }
986 EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_KEEP_PKEY_CTX);
987
988 if (!cms_sd_asn1_ctrl(si, 1))
989 goto err;
990
991 alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf,
992 ASN1_ITEM_rptr(CMS_Attributes_Verify));
993 if (abuf == NULL || alen < 0)
994 goto err;
995 r = EVP_DigestVerifyUpdate(mctx, abuf, alen);
996 OPENSSL_free(abuf);
997 if (r <= 0) {
998 r = -1;
999 goto err;
1000 }
1001 r = EVP_DigestVerifyFinal(mctx,
1002 si->signature->data, si->signature->length);
1003 if (r <= 0)
1004 ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE);
1005 err:
1006 EVP_MD_free(fetched_md);
1007 EVP_MD_CTX_reset(mctx);
1008 return r;
1009 }
1010
1011 /* Create a chain of digest BIOs from a CMS ContentInfo */
ossl_cms_SignedData_init_bio(CMS_ContentInfo * cms)1012 BIO *ossl_cms_SignedData_init_bio(CMS_ContentInfo *cms)
1013 {
1014 int i;
1015 CMS_SignedData *sd;
1016 BIO *chain = NULL;
1017
1018 sd = cms_get0_signed(cms);
1019 if (sd == NULL)
1020 return NULL;
1021 if (cms->d.signedData->encapContentInfo->partial)
1022 cms_sd_set_version(sd);
1023 for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) {
1024 X509_ALGOR *digestAlgorithm;
1025 BIO *mdbio;
1026
1027 digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i);
1028 mdbio = ossl_cms_DigestAlgorithm_init_bio(digestAlgorithm,
1029 ossl_cms_get0_cmsctx(cms));
1030 if (mdbio == NULL)
1031 goto err;
1032 if (chain != NULL)
1033 BIO_push(chain, mdbio);
1034 else
1035 chain = mdbio;
1036 }
1037 return chain;
1038 err:
1039 BIO_free_all(chain);
1040 return NULL;
1041 }
1042
CMS_SignerInfo_verify_content(CMS_SignerInfo * si,BIO * chain)1043 int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain)
1044 {
1045 ASN1_OCTET_STRING *os = NULL;
1046 EVP_MD_CTX *mctx = EVP_MD_CTX_new();
1047 EVP_PKEY_CTX *pkctx = NULL;
1048 int r = -1;
1049 unsigned char mval[EVP_MAX_MD_SIZE];
1050 unsigned int mlen;
1051
1052 if (mctx == NULL) {
1053 ERR_raise(ERR_LIB_CMS, ERR_R_EVP_LIB);
1054 goto err;
1055 }
1056 /* If we have any signed attributes look for messageDigest value */
1057 if (CMS_signed_get_attr_count(si) >= 0) {
1058 os = CMS_signed_get0_data_by_OBJ(si,
1059 OBJ_nid2obj(NID_pkcs9_messageDigest),
1060 -3, V_ASN1_OCTET_STRING);
1061 if (os == NULL) {
1062 ERR_raise(ERR_LIB_CMS, CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);
1063 goto err;
1064 }
1065 }
1066
1067 if (!ossl_cms_DigestAlgorithm_find_ctx(mctx, chain, si->digestAlgorithm))
1068 goto err;
1069
1070 if (EVP_DigestFinal_ex(mctx, mval, &mlen) <= 0) {
1071 ERR_raise(ERR_LIB_CMS, CMS_R_UNABLE_TO_FINALIZE_CONTEXT);
1072 goto err;
1073 }
1074
1075 /* If messageDigest found compare it */
1076 if (os != NULL) {
1077 if (mlen != (unsigned int)os->length) {
1078 ERR_raise(ERR_LIB_CMS, CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH);
1079 goto err;
1080 }
1081
1082 if (memcmp(mval, os->data, mlen)) {
1083 ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE);
1084 r = 0;
1085 } else {
1086 r = 1;
1087 }
1088 } else {
1089 const EVP_MD *md = EVP_MD_CTX_get0_md(mctx);
1090 const CMS_CTX *ctx = si->cms_ctx;
1091
1092 pkctx = EVP_PKEY_CTX_new_from_pkey(ossl_cms_ctx_get0_libctx(ctx),
1093 si->pkey,
1094 ossl_cms_ctx_get0_propq(ctx));
1095 if (pkctx == NULL)
1096 goto err;
1097 if (EVP_PKEY_verify_init(pkctx) <= 0)
1098 goto err;
1099 if (EVP_PKEY_CTX_set_signature_md(pkctx, md) <= 0)
1100 goto err;
1101 si->pctx = pkctx;
1102 if (!cms_sd_asn1_ctrl(si, 1)) {
1103 si->pctx = NULL;
1104 goto err;
1105 }
1106 si->pctx = NULL;
1107 r = EVP_PKEY_verify(pkctx, si->signature->data,
1108 si->signature->length, mval, mlen);
1109 if (r <= 0) {
1110 ERR_raise(ERR_LIB_CMS, CMS_R_VERIFICATION_FAILURE);
1111 r = 0;
1112 }
1113 }
1114
1115 err:
1116 EVP_PKEY_CTX_free(pkctx);
1117 EVP_MD_CTX_free(mctx);
1118 return r;
1119 }
1120
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)1121 BIO *CMS_SignedData_verify(CMS_SignedData *sd, BIO *detached_data,
1122 STACK_OF(X509) *scerts, X509_STORE *store,
1123 STACK_OF(X509) *extra, STACK_OF(X509_CRL) *crls,
1124 unsigned int flags,
1125 OSSL_LIB_CTX *libctx, const char *propq)
1126 {
1127 CMS_ContentInfo *ci;
1128 BIO *bio = NULL;
1129 int i, res = 0;
1130
1131 if (sd == NULL) {
1132 ERR_raise(ERR_LIB_CMS, ERR_R_PASSED_NULL_PARAMETER);
1133 return NULL;
1134 }
1135
1136 if ((ci = CMS_ContentInfo_new_ex(libctx, propq)) == NULL)
1137 return NULL;
1138 if ((bio = BIO_new(BIO_s_mem())) == NULL)
1139 goto end;
1140 ci->contentType = OBJ_nid2obj(NID_pkcs7_signed);
1141 ci->d.signedData = sd;
1142
1143 for (i = 0; i < sk_X509_num(extra); i++)
1144 if (!CMS_add1_cert(ci, sk_X509_value(extra, i)))
1145 goto end;
1146 for (i = 0; i < sk_X509_CRL_num(crls); i++)
1147 if (!CMS_add1_crl(ci, sk_X509_CRL_value(crls, i)))
1148 goto end;
1149 res = CMS_verify(ci, scerts, store, detached_data, bio, flags);
1150
1151 end:
1152 if (ci != NULL)
1153 ci->d.signedData = NULL; /* do not indirectly free |sd| */
1154 CMS_ContentInfo_free(ci);
1155 if (!res) {
1156 BIO_free(bio);
1157 bio = NULL;
1158 }
1159 return bio;
1160 }
1161
CMS_add_smimecap(CMS_SignerInfo * si,STACK_OF (X509_ALGOR)* algs)1162 int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs)
1163 {
1164 unsigned char *smder = NULL;
1165 int smderlen, r;
1166
1167 smderlen = i2d_X509_ALGORS(algs, &smder);
1168 if (smderlen <= 0)
1169 return 0;
1170 r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities,
1171 V_ASN1_SEQUENCE, smder, smderlen);
1172 OPENSSL_free(smder);
1173 return r;
1174 }
1175
CMS_add_simple_smimecap(STACK_OF (X509_ALGOR)** algs,int algnid,int keysize)1176 int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs,
1177 int algnid, int keysize)
1178 {
1179 X509_ALGOR *alg;
1180 ASN1_INTEGER *key = NULL;
1181
1182 if (keysize > 0) {
1183 key = ASN1_INTEGER_new();
1184 if (key == NULL || !ASN1_INTEGER_set(key, keysize)) {
1185 ASN1_INTEGER_free(key);
1186 return 0;
1187 }
1188 }
1189 alg = ossl_X509_ALGOR_from_nid(algnid, key != NULL ? V_ASN1_INTEGER : V_ASN1_UNDEF, key);
1190 if (alg == NULL) {
1191 ASN1_INTEGER_free(key);
1192 return 0;
1193 }
1194
1195 if (*algs == NULL)
1196 *algs = sk_X509_ALGOR_new_null();
1197 if (*algs == NULL || !sk_X509_ALGOR_push(*algs, alg)) {
1198 X509_ALGOR_free(alg);
1199 return 0;
1200 }
1201 return 1;
1202 }
1203
1204 /* 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)1205 static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
1206 {
1207 if (EVP_get_cipherbynid(nid))
1208 return CMS_add_simple_smimecap(sk, nid, arg);
1209 return 1;
1210 }
1211
cms_add_digest_smcap(STACK_OF (X509_ALGOR)** sk,int nid,int arg)1212 static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg)
1213 {
1214 if (EVP_get_digestbynid(nid))
1215 return CMS_add_simple_smimecap(sk, nid, arg);
1216 return 1;
1217 }
1218
CMS_add_standard_smimecap(STACK_OF (X509_ALGOR)** smcap)1219 int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap)
1220 {
1221 if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1)
1222 || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_256, -1)
1223 || !cms_add_digest_smcap(smcap, NID_id_GostR3411_2012_512, -1)
1224 || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1)
1225 || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1)
1226 || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1)
1227 || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1)
1228 || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1)
1229 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128)
1230 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64)
1231 || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1)
1232 || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40))
1233 return 0;
1234 return 1;
1235 }
1236