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