⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cms_sd.c

📁 OpenSSL 0.9.8k 最新版OpenSSL
💻 C
📖 第 1 页 / 共 2 页
字号:
/* crypto/cms/cms_sd.c *//* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project. *//* ==================================================================== * Copyright (c) 2008 The OpenSSL Project.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. All advertising materials mentioning features or use of this *    software must display the following acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" * * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to *    endorse or promote products derived from this software without *    prior written permission. For written permission, please contact *    licensing@OpenSSL.org. * * 5. Products derived from this software may not be called "OpenSSL" *    nor may "OpenSSL" appear in their names without prior written *    permission of the OpenSSL Project. * * 6. Redistributions of any form whatsoever must retain the following *    acknowledgment: *    "This product includes software developed by the OpenSSL Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" * * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== */#include "cryptlib.h"#include <openssl/asn1t.h>#include <openssl/pem.h>#include <openssl/x509v3.h>#include <openssl/err.h>#include <openssl/cms.h>#include "cms_lcl.h"/* CMS SignedData Utilities */DECLARE_ASN1_ITEM(CMS_SignedData)static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms)	{	if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed)		{		CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA);		return NULL;		}	return cms->d.signedData;	}static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms)	{	if (cms->d.other == NULL)		{		cms->d.signedData = M_ASN1_new_of(CMS_SignedData);		if (!cms->d.signedData)			{			CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE);			return NULL;			}		cms->d.signedData->version = 1;		cms->d.signedData->encapContentInfo->eContentType =						OBJ_nid2obj(NID_pkcs7_data);		cms->d.signedData->encapContentInfo->partial = 1;		ASN1_OBJECT_free(cms->contentType);		cms->contentType = OBJ_nid2obj(NID_pkcs7_signed);		return cms->d.signedData;		}	return cms_get0_signed(cms);	}/* Just initialize SignedData e.g. for certs only structure */int CMS_SignedData_init(CMS_ContentInfo *cms)	{	if (cms_signed_data_init(cms))		return 1;	else		return 0;	}/* Check structures and fixup version numbers (if necessary) */static void cms_sd_set_version(CMS_SignedData *sd)	{	int i;	CMS_CertificateChoices *cch;	CMS_RevocationInfoChoice *rch;	CMS_SignerInfo *si;	for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++)		{		cch = sk_CMS_CertificateChoices_value(sd->certificates, i);		if (cch->type == CMS_CERTCHOICE_OTHER)			{			if (sd->version < 5)				sd->version = 5;			}		else if (cch->type == CMS_CERTCHOICE_V2ACERT)			{			if (sd->version < 4)				sd->version = 4;			}		else if (cch->type == CMS_CERTCHOICE_V1ACERT)			{			if (sd->version < 3)				sd->version = 3;			}		}	for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++)		{		rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i);		if (rch->type == CMS_REVCHOICE_OTHER)			{			if (sd->version < 5)				sd->version = 5;			}		}	if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data)			&& (sd->version < 3))		sd->version = 3;	for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++)		{		si = sk_CMS_SignerInfo_value(sd->signerInfos, i);		if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)			{			if (si->version < 3)				si->version = 3;			if (sd->version < 3)				sd->version = 3;			}		else			sd->version = 1;		}	if (sd->version < 1)		sd->version = 1;	}	/* Copy an existing messageDigest value */static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si)	{	STACK_OF(CMS_SignerInfo) *sinfos;	CMS_SignerInfo *sitmp;	int i;	sinfos = CMS_get0_SignerInfos(cms);	for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++)		{		ASN1_OCTET_STRING *messageDigest;		sitmp = sk_CMS_SignerInfo_value(sinfos, i);		if (sitmp == si)			continue;		if (CMS_signed_get_attr_count(sitmp) < 0)			continue;		if (OBJ_cmp(si->digestAlgorithm->algorithm,				sitmp->digestAlgorithm->algorithm))			continue;		messageDigest = CMS_signed_get0_data_by_OBJ(sitmp,					OBJ_nid2obj(NID_pkcs9_messageDigest),					-3, V_ASN1_OCTET_STRING);		if (!messageDigest)			{			CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST,				CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE);			return 0;			}		if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest,						V_ASN1_OCTET_STRING,						messageDigest, -1))			return 1;		else			return 0;		}		CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST);		return 0;	}int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type)	{	switch(type)		{		case CMS_SIGNERINFO_ISSUER_SERIAL:		sid->d.issuerAndSerialNumber =			M_ASN1_new_of(CMS_IssuerAndSerialNumber);		if (!sid->d.issuerAndSerialNumber)			goto merr;		if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer,					X509_get_issuer_name(cert)))			goto merr;		ASN1_STRING_free(sid->d.issuerAndSerialNumber->serialNumber);		sid->d.issuerAndSerialNumber->serialNumber =				ASN1_STRING_dup(X509_get_serialNumber(cert));		if(!sid->d.issuerAndSerialNumber->serialNumber)			goto merr;		break;		case CMS_SIGNERINFO_KEYIDENTIFIER:		if (!cert->skid)			{			CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER,					CMS_R_CERTIFICATE_HAS_NO_KEYID);			return 0;			}		sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid);		if (!sid->d.subjectKeyIdentifier)			goto merr;		break;		default:		CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID);		return 0;		}	sid->type = type;	return 1;	merr:	CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE);	return 0;	}int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid,					ASN1_OCTET_STRING **keyid,					X509_NAME **issuer, ASN1_INTEGER **sno)	{	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)		{		if (issuer)			*issuer = sid->d.issuerAndSerialNumber->issuer;		if (sno)			*sno = sid->d.issuerAndSerialNumber->serialNumber;		}	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)		{		if (keyid)			*keyid = sid->d.subjectKeyIdentifier;		}	else		return 0;	return 1;	}int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert)	{	int ret;	if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL)		{		ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer,					X509_get_issuer_name(cert));		if (ret)			return ret;		return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber,					X509_get_serialNumber(cert));		}	else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER)		{		X509_check_purpose(cert, -1, -1);		if (!cert->skid)			return -1;		return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier,							cert->skid);		}	else		return -1;	}CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,			X509 *signer, EVP_PKEY *pk, const EVP_MD *md,			unsigned int flags)	{	CMS_SignedData *sd;	CMS_SignerInfo *si = NULL;	X509_ALGOR *alg;	int i, type;	if(!X509_check_private_key(signer, pk))		{		CMSerr(CMS_F_CMS_ADD1_SIGNER,			CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE);                return NULL;		}	sd = cms_signed_data_init(cms);	if (!sd)		goto err;	si = M_ASN1_new_of(CMS_SignerInfo);	if (!si)		goto merr;	X509_check_purpose(signer, -1, -1);	CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY);	CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509);	si->pkey = pk;	si->signer = signer;	if (flags & CMS_USE_KEYID)		{		si->version = 3;		if (sd->version < 3)			sd->version = 3;		type = CMS_SIGNERINFO_KEYIDENTIFIER;		}	else		{		type = CMS_SIGNERINFO_ISSUER_SERIAL;		si->version = 1;		}	if (!cms_set1_SignerIdentifier(si->sid, signer, type))		goto err;	/* Since no EVP_PKEY_METHOD in 0.9.8 hard code SHA1 as default */	if (md == NULL)		md = EVP_sha1();	/* OpenSSL 0.9.8 only supports SHA1 with non-RSA keys */	if ((pk->type != EVP_PKEY_RSA) && (EVP_MD_type(md) != NID_sha1))		{		CMSerr(CMS_F_CMS_ADD1_SIGNER,				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);		goto err;		}	cms_DigestAlgorithm_set(si->digestAlgorithm, md);	/* See if digest is present in digestAlgorithms */	for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++)		{		ASN1_OBJECT *aoid;		alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i);		X509_ALGOR_get0(&aoid, NULL, NULL, alg);		if (OBJ_obj2nid(aoid) == EVP_MD_type(md))			break;		}	if (i == sk_X509_ALGOR_num(sd->digestAlgorithms))		{		alg = X509_ALGOR_new();		if (!alg)			goto merr;		cms_DigestAlgorithm_set(alg, md);		if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg))			{			X509_ALGOR_free(alg);			goto merr;			}		}	/* Since we have no EVP_PKEY_ASN1_METHOD in OpenSSL 0.9.8,	 * hard code algorithm parameters.	 */	switch (pk->type)		{		case EVP_PKEY_RSA:		X509_ALGOR_set0(si->signatureAlgorithm,					OBJ_nid2obj(NID_rsaEncryption),					V_ASN1_NULL, 0);		break;		case EVP_PKEY_DSA:		X509_ALGOR_set0(si->signatureAlgorithm,					OBJ_nid2obj(NID_dsaWithSHA1),					V_ASN1_UNDEF, 0);		break;		case EVP_PKEY_EC:		X509_ALGOR_set0(si->signatureAlgorithm,					OBJ_nid2obj(NID_ecdsa_with_SHA1),					V_ASN1_UNDEF, 0);		break;		default:		CMSerr(CMS_F_CMS_ADD1_SIGNER,				CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);		goto err;		}	if (!(flags & CMS_NOATTR))		{		/* Initialialize signed attributes strutucture so other		 * attributes such as signing time etc are added later		 * even if we add none here.		 */		if (!si->signedAttrs)			{			si->signedAttrs = sk_X509_ATTRIBUTE_new_null();			if (!si->signedAttrs)				goto merr;			}		if (!(flags & CMS_NOSMIMECAP))			{			STACK_OF(X509_ALGOR) *smcap = NULL;			i = CMS_add_standard_smimecap(&smcap);			if (i)				i = CMS_add_smimecap(si, smcap);			sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free);			if (!i)				goto merr;			}		if (flags & CMS_REUSE_DIGEST)			{			if (!cms_copy_messageDigest(cms, si))				goto err;			if (!(flags & CMS_PARTIAL) &&					!CMS_SignerInfo_sign(si))				goto err;			}		}	if (!(flags & CMS_NOCERTS))		{		/* NB ignore -1 return for duplicate cert */		if (!CMS_add1_cert(cms, signer))			goto merr;		}	if (!sd->signerInfos)		sd->signerInfos = sk_CMS_SignerInfo_new_null();	if (!sd->signerInfos ||		!sk_CMS_SignerInfo_push(sd->signerInfos, si))		goto merr;	return si;	merr:	CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE);	err:	if (si)		M_ASN1_free_of(si, CMS_SignerInfo);	return NULL;	}static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t)	{	ASN1_TIME *tt;	int r = 0;	if (t)		tt = t;	else		tt = X509_gmtime_adj(NULL, 0);	if (!tt)		goto merr;	if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime,						tt->type, tt, -1) <= 0)		goto merr;	r = 1;	merr:	if (!t)		ASN1_TIME_free(tt);	if (!r)		CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE);	return r;	}STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms)	{	CMS_SignedData *sd;	sd = cms_get0_signed(cms);	if (!sd)		return NULL;	return sd->signerInfos;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -