コード例 #1
0
ファイル: pki_x509_pkcs7.c プロジェクト: Brenhilt/libpki
int PKI_X509_PKCS7_encode ( PKI_X509_PKCS7 *p7, unsigned char *data, 
							size_t size ) {

	int type = NID_pkcs7_signed;
	PKCS7_SIGNER_INFO *signerInfo = NULL;
	BIO *bio = NULL;

	if( !p7 || !p7->value ) return ( PKI_ERR );

	type = PKI_X509_PKCS7_get_type ( p7 );

	if (( type == PKI_X509_PKCS7_TYPE_ENCRYPTED ) 
			|| (type == PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED)) {

		if ( PKI_X509_PKCS7_has_recipients ( p7 ) == PKI_ERR ) {
			PKI_log_debug ( "PKI_X509_PKCS7_encode()::Missing "
								"Recipients!");
			return PKI_ERR;
		}
	}

	if ( (type == PKI_X509_PKCS7_TYPE_SIGNED) ||
			(type == PKI_X509_PKCS7_TYPE_SIGNEDANDENCRYPTED )) {

		if(( signerInfo = PKI_X509_PKCS7_get_signer_info( p7,
							-1 )) == NULL ) {
			return ( PKI_ERR );
		}

		PKCS7_add_signed_attribute ( signerInfo, NID_pkcs9_contentType,
			V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));
	}

	if((bio = PKCS7_dataInit(p7->value, NULL)) == NULL ) {
		PKI_log_err("PKI_X509_PKCS7_sign()::Error dataInit [%s]",
			ERR_error_string(ERR_get_error(),NULL));
		return ( PKI_ERR );
	}
	
	if( BIO_write( bio, data, (int) size ) <= 0 ) {
		PKI_log_err("PKI_X509_PKCS7_sign()::Error dataSign [%s]",
			ERR_error_string(ERR_get_error(),NULL));
		return ( PKI_ERR );
	}

	(void)BIO_flush(bio);

	if(!PKCS7_dataFinal( p7->value, bio )) {
		PKI_log_err("PKI_X509_PKCS7_sign()::Error End dataSign [%s]",
			ERR_error_string(ERR_get_error(),NULL));
		return ( PKI_ERR );
	};

	if( bio ) BIO_free_all ( bio );

	return ( PKI_OK );

}
コード例 #2
0
int add_signed_time(PKCS7_SIGNER_INFO *si)
	{
	ASN1_UTCTIME *sign_time;

	/* The last parameter is the amount to add/subtract from the current
	 * time (in seconds) */
	sign_time=X509_gmtime_adj(NULL,0);
	PKCS7_add_signed_attribute(si,NID_pkcs9_signingTime,
		V_ASN1_UTCTIME,(char *)sign_time);
	return(1);
	}
コード例 #3
0
void add_signed_string(PKCS7_SIGNER_INFO *si, char *str)
	{
	ASN1_OCTET_STRING *os;

	/* To a an object of OID 1.2.3.4.5, which is an octet string */
	if (signed_string_nid == -1)
		signed_string_nid=
			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
	os=ASN1_OCTET_STRING_new();
	ASN1_OCTET_STRING_set(os,(unsigned char*)str,TINYCLR_SSL_STRLEN(str));
	/* When we add, we do not free */
	PKCS7_add_signed_attribute(si,signed_string_nid,
		V_ASN1_OCTET_STRING,(char *)os);
	}
コード例 #4
0
static VALUE
ossl_pkcs7_add_signer(VALUE self, VALUE signer)
{
    PKCS7 *pkcs7;
    PKCS7_SIGNER_INFO *p7si;

    p7si = DupPKCS7SignerPtr(signer); /* NEED TO DUP */
    GetPKCS7(self, pkcs7);
    if (!PKCS7_add_signer(pkcs7, p7si)) {
	PKCS7_SIGNER_INFO_free(p7si);
	ossl_raise(ePKCS7Error, "Could not add signer.");
    }
    if (PKCS7_type_is_signed(pkcs7)){
	PKCS7_add_signed_attribute(p7si, NID_pkcs9_contentType,
				   V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data));
    }

    return self;
}
コード例 #5
0
/* ########################################### */
int
add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
{
	/* To add an object of OID 1.9.999, which is a sequence containing
	 * 2 octet strings */
	unsigned char *p;
	ASN1_OCTET_STRING *os1, *os2;
	ASN1_STRING *seq;
	unsigned char *data;
	int i, total;

	if (signed_seq2string_nid == -1)
		signed_seq2string_nid =
		    OBJ_create("1.9.9999","OID_example","Our example OID");

	os1 = ASN1_OCTET_STRING_new();
	os2 = ASN1_OCTET_STRING_new();
	ASN1_OCTET_STRING_set(os1, (unsigned char*)str1, strlen(str1));
	ASN1_OCTET_STRING_set(os2, (unsigned char*)str1, strlen(str1));
	i = i2d_ASN1_OCTET_STRING(os1, NULL);
	i += i2d_ASN1_OCTET_STRING(os2, NULL);
	total = ASN1_object_size(1, i, V_ASN1_SEQUENCE);

	data = malloc(total);
	p = data;
	ASN1_put_object(&p, 1,i, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
	i2d_ASN1_OCTET_STRING(os1, &p);
	i2d_ASN1_OCTET_STRING(os2, &p);

	seq = ASN1_STRING_new();
	ASN1_STRING_set(seq, data, total);
	free(data);
	ASN1_OCTET_STRING_free(os1);
	ASN1_OCTET_STRING_free(os2);

	PKCS7_add_signed_attribute(si, signed_seq2string_nid,
	    V_ASN1_SEQUENCE, (char *)seq);
	return (1);
}
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
	{
	int ret=0;
	int i,j;
	BIO *btmp;
	BUF_MEM *buf_mem=NULL;
	BUF_MEM *buf=NULL;
	PKCS7_SIGNER_INFO *si;
	EVP_MD_CTX *mdc,ctx_tmp;
	STACK_OF(X509_ATTRIBUTE) *sk;
	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
	ASN1_OCTET_STRING *os=NULL;

	EVP_MD_CTX_init(&ctx_tmp);
	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_signedAndEnveloped:
		/* XXXXXXXXXXXXXXXX */
		si_sk=p7->d.signed_and_enveloped->signer_info;
		if (!(os=M_ASN1_OCTET_STRING_new()))
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		p7->d.signed_and_enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_enveloped:
		/* XXXXXXXXXXXXXXXX */
		if (!(os=M_ASN1_OCTET_STRING_new()))
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_MALLOC_FAILURE);
			goto err;
			}
		p7->d.enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_signed:
		si_sk=p7->d.sign->signer_info;
		os=PKCS7_get_octet_string(p7->d.sign->contents);
		/* If detached data then the content is excluded */
		if(PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) {
			M_ASN1_OCTET_STRING_free(os);
			p7->d.sign->contents->d.data = NULL;
		}
		break;

	case NID_pkcs7_digest:
		os=PKCS7_get_octet_string(p7->d.digest->contents);
		/* If detached data then the content is excluded */
		if(PKCS7_type_is_data(p7->d.digest->contents) && p7->detached)
			{
			M_ASN1_OCTET_STRING_free(os);
			p7->d.digest->contents->d.data = NULL;
			}
		break;

		}

	if (si_sk != NULL)
		{
		if ((buf=BUF_MEM_new()) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
			goto err;
			}
		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
			{
			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
			if (si->pkey == NULL) continue;

			j=OBJ_obj2nid(si->digest_alg->algorithm);

			btmp=bio;

			btmp = PKCS7_find_digest(&mdc, btmp, j);

			if (btmp == NULL)
				goto err;

			/* We now have the EVP_MD_CTX, lets do the
			 * signing. */
			EVP_MD_CTX_copy_ex(&ctx_tmp,mdc);
			if (!BUF_MEM_grow_clean(buf,EVP_PKEY_size(si->pkey)))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_BIO_LIB);
				goto err;
				}

			sk=si->auth_attr;

			/* If there are attributes, we add the digest
			 * attribute and only sign the attributes */
			if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
				{
				unsigned char md_data[EVP_MAX_MD_SIZE], *abuf=NULL;
				unsigned int md_len, alen;
				ASN1_OCTET_STRING *digest;
				ASN1_UTCTIME *sign_time;
				const EVP_MD *md_tmp;

				/* Add signing time if not already present */
				if (!PKCS7_get_signed_attribute(si,
							NID_pkcs9_signingTime))
					{
					if (!(sign_time=X509_gmtime_adj(NULL,0)))
						{
						PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
							ERR_R_MALLOC_FAILURE);
						goto err;
						}
					PKCS7_add_signed_attribute(si,
						NID_pkcs9_signingTime,
						V_ASN1_UTCTIME,sign_time);
					}

				/* Add digest */
				md_tmp=EVP_MD_CTX_md(&ctx_tmp);
				EVP_DigestFinal_ex(&ctx_tmp,md_data,&md_len);
				if (!(digest=M_ASN1_OCTET_STRING_new()))
					{
					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
						ERR_R_MALLOC_FAILURE);
					goto err;
					}
				if (!M_ASN1_OCTET_STRING_set(digest,md_data,
								md_len))
					{
					PKCS7err(PKCS7_F_PKCS7_DATAFINAL,
						ERR_R_MALLOC_FAILURE);
					goto err;
					}
				PKCS7_add_signed_attribute(si,
					NID_pkcs9_messageDigest,
					V_ASN1_OCTET_STRING,digest);

				/* Now sign the attributes */
				EVP_SignInit_ex(&ctx_tmp,md_tmp,NULL);
				alen = ASN1_item_i2d((ASN1_VALUE *)sk,&abuf,
							ASN1_ITEM_rptr(PKCS7_ATTR_SIGN));
				if(!abuf) goto err;
				EVP_SignUpdate(&ctx_tmp,abuf,alen);
				OPENSSL_free(abuf);
				}

#ifndef OPENSSL_NO_DSA
			if (si->pkey->type == EVP_PKEY_DSA)
				ctx_tmp.digest=EVP_dss1();
#endif
#ifndef OPENSSL_NO_ECDSA
 			if (si->pkey->type == EVP_PKEY_EC)
 				ctx_tmp.digest=EVP_ecdsa();
#endif

			if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
				(unsigned int *)&buf->length,si->pkey))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_EVP_LIB);
				goto err;
				}
			if (!ASN1_STRING_set(si->enc_digest,
				(unsigned char *)buf->data,buf->length))
				{
				PKCS7err(PKCS7_F_PKCS7_DATAFINAL,ERR_R_ASN1_LIB);
				goto err;
				}
			}
		}
	else if (i == NID_pkcs7_digest)
		{
		unsigned char md_data[EVP_MAX_MD_SIZE];
		unsigned int md_len;
		if (!PKCS7_find_digest(&mdc, bio,
				OBJ_obj2nid(p7->d.digest->md->algorithm)))
			goto err;
		EVP_DigestFinal_ex(mdc,md_data,&md_len);
		M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len);
		}

	if (!PKCS7_is_detached(p7))
		{
		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
		if (btmp == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATAFINAL,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
			goto err;
			}
		BIO_get_mem_ptr(btmp,&buf_mem);
		/* Mark the BIO read only then we can use its copy of the data
		 * instead of making an extra copy.
		 */
		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
		BIO_set_mem_eof_return(btmp, 0);
		os->data = (unsigned char *)buf_mem->data;
		os->length = buf_mem->length;
#if 0
		M_ASN1_OCTET_STRING_set(os,
			(unsigned char *)buf_mem->data,buf_mem->length);
#endif
		}
	ret=1;
err:
	EVP_MD_CTX_cleanup(&ctx_tmp);
	if (buf != NULL) BUF_MEM_free(buf);
	return(ret);
	}
コード例 #7
0
ファイル: cert_scep.c プロジェクト: millken/zhuxianB30
/*******************************************************************************
函数名称: cert_pkcs7_wrap
功能描述: 将要发送的消息采用PKCS#7格式进行编码
输入参数: struct scep *s, SCEP操作的结构体指针。
     s32 hasra, 是否使用RA证书,1,使用;0,不使用

输出参数: 无
返 回 值: 1,成功;-1,失败
--------------------------------------------------------------------------------
最近一次修改记录:
修改作者:王朝
修改目的:添加新函数
修改日期:2009年12月28日
*********************************************************************************/
s32 cert_pkcs7_wrap(struct scep *s, s32 hasra)
{
	BIO *databio = NULL;
	BIO	*encbio = NULL;
	BIO	*pkcs7bio = NULL;
	BIO	*memorybio = NULL;
	BIO	*outbio = NULL;
	BIO	*base64bio = NULL;
	u8 *buffer = NULL;
	s32	len = 0;
	STACK_OF(X509) *recipients = NULL;
	PKCS7 *p7enc = NULL;
	PKCS7_SIGNER_INFO *si = NULL;
	STACK_OF(X509_ATTRIBUTE) *attributes = NULL;
	X509 *signercert = NULL;
	EVP_PKEY *signerkey = NULL;
    s32 retval = -1;

    /* sender nonce */
	s->sender_nonce_len = 16;
	s->sender_nonce = (u8 *)malloc((u32)s->sender_nonce_len);
	RAND_bytes(s->sender_nonce, s->sender_nonce_len);

	/* Prepare data payload */
	switch(s->request_type)
    {
		case SCEP_REQUEST_PKCSREQ:

			s->request_type_str = SCEP_REQUEST_PKCSREQ_STR;

			/* Signer cert */
			signercert = s->signercert;
			signerkey = s->signerkey;

			/* Read request in memory bio */
			databio = BIO_new(BIO_s_mem());
			if ((i2d_X509_REQ_bio(databio, cert_request)) <= 0)
            {
                goto end;
			}
			(void)BIO_flush(databio);
			BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY);
			break;

		case SCEP_REQUEST_GETCERTINIT:

			/* Set printable message type */
			s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR;

			/* Signer cert */
			signercert = s->signercert;
			signerkey = s->signerkey;

			/* Read data in memory bio */
			databio = BIO_new(BIO_s_mem());
			if ((i2d_pkcs7_issuer_and_subject_bio(databio,	s->ias_getcertinit)) <= 0)
            {
				goto end;
			}
			(void)BIO_flush(databio);
			BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY);
			break;

        default:
            goto end;
	}
	/* Below this is the common code for all request_type */

	/* Read in the payload */
	s->request_len = BIO_get_mem_data(databio, &s->request_payload);

	BIO_free(databio);
    databio = NULL;

	/* Create encryption certificate stack */
	if (NULL == (recipients = sk_X509_new_null() ))
    {
		goto end;
	}

	/* Use different CA cert for encryption if requested */
	if (1 == hasra)
    {
		if (sk_X509_push(recipients, cert_encert) <= 0)
        {
			goto end;
		}
	}
    else
    {
        /* Use same CA cert also for encryption */
		if (sk_X509_push(recipients, cert_cacert) <= 0)
        {
			goto end;
		}
	}

	/* Create BIO for encryption  */
	if ((encbio = BIO_new_mem_buf(s->request_payload,s->request_len)) == NULL)
    {
        goto end;
	}

	/* Encrypt */
	if (NULL == (p7enc = PKCS7_encrypt(recipients, encbio,	cert_enc_alg, PKCS7_BINARY)))
    {
        goto end;
	}

    BIO_free(encbio);
    encbio = NULL;
    sk_X509_free(recipients);
    recipients = NULL;

	/* Write encrypted data */
	memorybio = BIO_new(BIO_s_mem());
	if (i2d_PKCS7_bio(memorybio, p7enc) <= 0)
    {
        goto end;
	}

    PKCS7_free(p7enc);
    p7enc = NULL;
	(void)BIO_flush(memorybio);
	BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY);
	len = BIO_get_mem_data(memorybio, &buffer);

	/* Create outer PKCS#7  */
	s->request_p7 = PKCS7_new();
	if (s->request_p7 == NULL)
    {
		goto end;
	}
	if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed))
    {
		goto end;
	}

	/* Add signer certificate  and signature */
	PKCS7_add_certificate(s->request_p7, signercert);
	if ((si = PKCS7_add_signature(s->request_p7,signercert, signerkey, cert_sig_alg)) == NULL)
    {
        goto end;
	}

	/* Set signed attributes */
	attributes = sk_X509_ATTRIBUTE_new_null();
	cert_add_attribute_string(attributes, nid_transId, s->transaction_id);
	cert_add_attribute_string(attributes, nid_messageType, s->request_type_str);
	cert_add_attribute_octet(attributes, nid_senderNonce, (s8 *)(s->sender_nonce),s->sender_nonce_len);
	PKCS7_set_signed_attributes(si, attributes);
    sk_X509_ATTRIBUTE_free(attributes);
    attributes = NULL;

	/* Add contentType */
	if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)))
    {
        goto end;
	}


	/* Create new content */
	if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data))
    {
		goto end;
	}

	/* Write data  */
	pkcs7bio = PKCS7_dataInit(s->request_p7, NULL);
	if (pkcs7bio == NULL)
    {
		goto end;
	}
	if (len != BIO_write(pkcs7bio, buffer, len))
    {
		goto end;
	}

    BIO_free(memorybio);
    memorybio = NULL;

	/* Finalize PKCS#7  */
	if (!PKCS7_dataFinal(s->request_p7, pkcs7bio))
    {
        goto end;
	}

	/* base64-encode the data */

	/* Create base64 filtering bio */
	memorybio = BIO_new(BIO_s_mem());
	base64bio = BIO_new(BIO_f_base64());
	outbio = BIO_push(base64bio, memorybio);

	/* Copy PKCS#7 */
	i2d_PKCS7_bio(outbio, s->request_p7);
	(void)BIO_flush(outbio);
	BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY);
	s->request_len = BIO_get_mem_data(memorybio, &s->request_payload);

    retval = 1;

   end:

    if(NULL != databio)
    {
        BIO_free(databio);
    }

    if(NULL != encbio)
    {
        BIO_free(encbio);
    }
    
    if(NULL != p7enc)
    {
        PKCS7_free(p7enc);
    }

    if(NULL != pkcs7bio)
    {
        BIO_free(pkcs7bio);
    }

    if(NULL != memorybio)
    {
        BIO_free(memorybio);
    }

    if(NULL != base64bio)
    {
        BIO_free(base64bio);
    }

	if(NULL != recipients)
	{
        sk_X509_free(recipients);
    }

    if(NULL != attributes)
	{
        sk_X509_ATTRIBUTE_free(attributes);
    }

	return retval;
}
コード例 #8
0
int create_envelope(PluginInstance *inst, u8 **data, int *datalen)
{
        int r;
        PKCS7 *p7 = NULL;
        X509 *x509 = NULL;
	PKCS7_SIGNER_INFO *si = NULL;
        EVP_PKEY *pkey = NULL;
	BIO *in = NULL, *p7bio = NULL;
	u8 *buf;
        
	r = extract_certificate_and_pkey(inst, &x509, &pkey);
	if (r)
		goto err;
        p7 = PKCS7_new();
        if (p7 == NULL) {
        	r = -1;
        	goto err;
        }
        r = PKCS7_set_type(p7, NID_pkcs7_signed);
        if (r != 1) {
        	r = -1;
                goto err;
	}
	EVP_add_digest(EVP_sha1());
        si = PKCS7_add_signature(p7, x509, pkey, EVP_sha1());
        if (si == NULL) {
        	r = -1;
		goto err;
	}
	PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT,
				   OBJ_nid2obj(NID_pkcs7_data));
	r = PKCS7_add_certificate(p7, x509);
	if (r != 1) {
		printf("PKCS7_add_certificate failed.\n");
		goto err;
	}
	PKCS7_content_new(p7, NID_pkcs7_data);

	p7bio = PKCS7_dataInit(p7, NULL);
	if (p7bio == NULL) {
        	r = -1;
		goto err;
	}
	in = BIO_new_mem_buf(inst->signdata, inst->signdata_len);
	if (in == NULL) {
		r = -1;
		goto err;
	}
	for (;;) {
		char lbuf[1024];
		int i = BIO_read(in, lbuf, sizeof(lbuf));
		if (i <= 0)
			break;
		BIO_write(p7bio, lbuf, i);
	}
	if (!PKCS7_dataFinal(p7, p7bio)) {
		r = -1;
		goto err;
	}
	/* FIXME: remove this */
	r = i2d_PKCS7(p7, NULL);
	if (r <= 0) {
		r = -1;
		goto err;
	}
	buf = (u8 *) malloc(r);
	if (buf == NULL)
		goto err;
	*data = buf;
	r = i2d_PKCS7(p7, &buf);
	*datalen = r;
	if (r <= 0) {
		free(buf);
		r = -1;
		goto err;
	}
	r = 0;
err:
	if (p7)
		PKCS7_free(p7);
	if (in)
		BIO_free(in);
	if (p7bio)
		BIO_free(p7bio);
#if 0
	if (si)
		PKCS7_SIGNER_INFO_free(si);
#endif
	if (pkey)
		EVP_PKEY_free(pkey);
	if (x509)
		X509_free(x509);
	if (r) {
#if 0
		ERR_load_crypto_strings();
		ERR_print_errors_fp(stderr);
#endif
	}
        return r;
}
コード例 #9
0
ファイル: pkcs7.c プロジェクト: JianlongCao/qeo-core
/*
 * Wrap data in PKCS#7 envelopes and base64-encode the result.
 * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject
 * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in
 * GetCert and GETCrl.
 */
int pkcs7_wrap(struct scep *s, struct sscep_ctx *ctx, struct sscep_operation_info *op_info)
{
    BIO *databio = NULL;
    BIO *encbio = NULL;
    BIO *pkcs7bio = NULL;
    BIO *memorybio = NULL;
    BIO *outbio = NULL;
    unsigned char *buffer = NULL;
    int len = 0;
    STACK_OF(X509) *recipients = NULL;
    PKCS7 *p7enc = NULL;
    PKCS7_SIGNER_INFO *si;
    STACK_OF(X509_ATTRIBUTE) *attributes;
    X509 *signercert = NULL;
    EVP_PKEY *signerkey = NULL;
    int ret = SCEP_PKISTATUS_P7;
    char *payload = NULL;
    int payload_len;

    /* Create a new sender nonce for all messages
     * XXXXXXXXXXXXXX should it be per transaction? */
    s->sender_nonce_len = 16;
    free(s->sender_nonce);/* Clean up from previous runs */
    s->sender_nonce = (char *)malloc(s->sender_nonce_len * sizeof(char));
    RAND_bytes((unsigned char *) s->sender_nonce, s->sender_nonce_len);

    /* Prepare data payload */
    switch (s->request_type) {
        case SCEP_REQUEST_PKCSREQ:
            /*
             * Set printable message type
             * We set this later as an autheticated attribute
             * "messageType".
             */
            s->request_type_str = SCEP_REQUEST_PKCSREQ_STR;

            /* Signer cert */
            signercert = s->signercert;
            signerkey = s->signerkey;

            /* Create inner PKCS#7  */
            if (ctx->verbose){
                qeo_log_i("creating inner PKCS#7");
            }

            /* Read request in memory bio */
            databio = BIO_new(BIO_s_mem());
            if (i2d_X509_REQ_bio(databio, op_info->request) <= 0) {
                qeo_log_e("error writing certificate request in bio");
                goto error;
            }
            (void)BIO_flush(databio);
            break;

        case SCEP_REQUEST_GETCERTINIT:

            /* Set printable message type */
            s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR;

            /* Signer cert */
            signercert = s->signercert;
            signerkey = s->signerkey;

            /* Create inner PKCS#7  */
            if (ctx->verbose){
                qeo_log_i("creating inner PKCS#7");
            }

            /* Read data in memory bio */
            databio = BIO_new(BIO_s_mem());
            if (i2d_pkcs7_issuer_and_subject_bio(databio, s->ias_getcertinit)) {
                qeo_log_e("error writing GetCertInitial data in bio");
                goto error;
            }
            (void)BIO_flush(databio);
            break;
    }
    /* Below this is the common code for all request_type */

    /* Read in the payload */
    payload_len = BIO_get_mem_data(databio, &payload);
    if (ctx->verbose){
        qeo_log_i("data payload size: %d bytes", payload_len);
    }

    /* Create encryption certificate stack */
    if ((recipients = sk_X509_new(NULL) ) == NULL) {
        qeo_log_e("error creating certificate stack");
        goto error;
    }
    if (sk_X509_push(recipients, op_info->racert) <= 0) {
        qeo_log_e("error adding recipient encryption certificate");
        goto error;
    }

    /* Create BIO for encryption  */
    if ((encbio = BIO_new_mem_buf(payload, payload_len)) == NULL ) {
        qeo_log_e("error creating data bio");
        goto error;
    }

    /* Encrypt */
    if (!(p7enc = PKCS7_encrypt(recipients, encbio, ctx->enc_alg, PKCS7_BINARY))) {
        qeo_log_e("request payload encrypt failed");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("successfully encrypted payload");
    }

    /* Write encrypted data */
    memorybio = BIO_new(BIO_s_mem());
    if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) {
        qeo_log_e("error writing encrypted data");
        goto error;
    }
    (void)BIO_flush(memorybio);
    BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY);
    len = BIO_get_mem_data(memorybio, &buffer);
    BIO_free(memorybio);
    memorybio=NULL;
    if (ctx->verbose){
        qeo_log_i("envelope size: %d bytes", len);
    }
    if (ctx->debug) {
        qeo_log_i("printing PEM fomatted PKCS#7");
        PEM_write_PKCS7(stdout, p7enc);
    }

    /* Create outer PKCS#7  */
    if (ctx->verbose){
        qeo_log_i("creating outer PKCS#7");
    }
    s->request_p7 = PKCS7_new();
    if (s->request_p7 == NULL ) {
        qeo_log_e("failed creating PKCS#7 for signing");
        goto error;
    }
    if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) {
        qeo_log_e("failed setting PKCS#7 type");
        goto error;
    }

    /* Add signer certificate  and signature */
    PKCS7_add_certificate(s->request_p7, signercert);
    if ((si = PKCS7_add_signature(s->request_p7, signercert, signerkey, ctx->sig_alg)) == NULL ) {
        qeo_log_e("error adding PKCS#7 signature");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("signature added successfully");
    }

    /* Set signed attributes */
    if (ctx->verbose){
        qeo_log_i("adding signed attributes");
    }
    attributes = sk_X509_ATTRIBUTE_new_null();
    add_attribute_string(attributes, ctx->nid_transId, s->transaction_id, ctx);
    add_attribute_string(attributes, ctx->nid_messageType, s->request_type_str, ctx);
    add_attribute_octet(attributes, ctx->nid_senderNonce, s->sender_nonce, s->sender_nonce_len, ctx);
    PKCS7_set_signed_attributes(si, attributes);
    sk_X509_ATTRIBUTE_pop_free(attributes, X509_ATTRIBUTE_free);

    /* Add contentType */
    if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) {
        qeo_log_e("error adding NID_pkcs9_contentType");
        goto error;
    }

    /* Create new content */
    if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) {
        qeo_log_e("failed setting PKCS#7 content type");
        goto error;
    }

    /* Write data  */
    pkcs7bio = PKCS7_dataInit(s->request_p7, NULL );
    if (pkcs7bio == NULL ) {
        qeo_log_e("error opening bio for writing PKCS#7 data");
        goto error;
    }
    if (len != BIO_write(pkcs7bio, buffer, len)) {
        qeo_log_e("error writing PKCS#7 data");
        goto error;
    }
    if (ctx->verbose){
        qeo_log_i("PKCS#7 data written successfully");
    }

    /* Finalize PKCS#7  */
    if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) {
        qeo_log_e("error finalizing outer PKCS#7");
        goto error;
    }
    if (ctx->debug) {
        qeo_log_i("printing PEM fomatted PKCS#7");
        PEM_write_PKCS7(stdout, s->request_p7);
    }

    /* base64-encode the data */
    if (ctx->verbose){
        qeo_log_i("applying base64 encoding");
    }

    /* Create base64 filtering bio */
    memorybio = BIO_new(BIO_s_mem());
    outbio = BIO_push(BIO_new(BIO_f_base64()), memorybio);

    /* Copy PKCS#7 */
    i2d_PKCS7_bio(outbio, s->request_p7);
    (void)BIO_flush(outbio);
    payload_len = BIO_get_mem_data(memorybio, &payload);
    s->request_payload = (char*) malloc(sizeof(char)*payload_len);
    if (!s->request_payload){
        goto error;
    }
    s->request_len = payload_len;
    memcpy(s->request_payload, payload, s->request_len);
    if (ctx->verbose){
        qeo_log_i("base64 encoded payload size: %d bytes", payload_len);
    }

    ret = 0;
error:
    BIO_free(databio);
    BIO_free(encbio);
    BIO_free_all(pkcs7bio);
    BIO_free(memorybio);
    BIO_free(outbio);
    if (recipients != NULL){
        sk_X509_free(recipients);/* Only free the stack, not the certificates */
    }
    PKCS7_free(p7enc);
    OPENSSL_free(buffer);
    return ret;
}
コード例 #10
0
ファイル: uefisign.c プロジェクト: 2asoft/freebsd
static void
sign(X509 *cert, EVP_PKEY *key, int pipefd)
{
	PKCS7 *pkcs7;
	BIO *bio, *out;
	const EVP_MD *md;
	PKCS7_SIGNER_INFO *info;
	void *digest, *signature;
	size_t digest_len, signature_len;
	int ok;

	assert(cert != NULL);
	assert(key != NULL);

	receive_chunk(&digest, &digest_len, pipefd);

	bio = BIO_new_mem_buf(digest, digest_len);
	if (bio == NULL) {
		ERR_print_errors_fp(stderr);
		errx(1, "BIO_new_mem_buf(3) failed");
	}

	pkcs7 = PKCS7_sign(NULL, NULL, NULL, bio, PKCS7_BINARY | PKCS7_PARTIAL);
	if (pkcs7 == NULL) {
		ERR_print_errors_fp(stderr);
		errx(1, "PKCS7_sign(3) failed");
	}

	md = EVP_get_digestbyname(DIGEST);
	if (md == NULL) {
		ERR_print_errors_fp(stderr);
		errx(1, "EVP_get_digestbyname(\"%s\") failed", DIGEST);
	}

	info = PKCS7_sign_add_signer(pkcs7, cert, key, md, 0);
	if (info == NULL) {
		ERR_print_errors_fp(stderr);
		errx(1, "PKCS7_sign_add_signer(3) failed");
	}

	/*
	 * XXX: All the signed binaries seem to have this, but where is it
	 *      described in the spec?
	 */
	PKCS7_add_signed_attribute(info, NID_pkcs9_contentType,
	    V_ASN1_OBJECT, OBJ_txt2obj("1.3.6.1.4.1.311.2.1.4", 1));

	magic(pkcs7, digest, digest_len);

#if 0
	out = BIO_new(BIO_s_file());
	BIO_set_fp(out, stdout, BIO_NOCLOSE);
	PKCS7_print_ctx(out, pkcs7, 0, NULL);

	i2d_PKCS7_bio(out, pkcs7);
#endif

	out = BIO_new(BIO_s_mem());
	if (out == NULL) {
		ERR_print_errors_fp(stderr);
		errx(1, "BIO_new(3) failed");
	}

	ok = i2d_PKCS7_bio(out, pkcs7);
	if (ok == 0) {
		ERR_print_errors_fp(stderr);
		errx(1, "i2d_PKCS7_bio(3) failed");
	}

	signature_len = BIO_get_mem_data(out, &signature);
	if (signature_len <= 0) {
		ERR_print_errors_fp(stderr);
		errx(1, "BIO_get_mem_data(3) failed");
	}

	(void)BIO_set_close(out, BIO_NOCLOSE);
	BIO_free(out);

	send_chunk(signature, signature_len, pipefd);
}
コード例 #11
0
ファイル: pkcs7.c プロジェクト: OPSF/uClinux
/*
 * Wrap data in PKCS#7 envelopes and base64-encode the result.
 * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject
 * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in
 * GetCert and GETCrl.
 */
int pkcs7_wrap(struct scep *s) {
	BIO			*databio = NULL;
	BIO			*encbio = NULL;
	BIO			*pkcs7bio = NULL;
	BIO			*memorybio = NULL;
	BIO			*outbio = NULL;
	BIO			*base64bio = NULL;
	unsigned char		*buffer = NULL;
	int			rc, len = 0;
	STACK_OF(X509)		*recipients;
	PKCS7			*p7enc;
	PKCS7_SIGNER_INFO	*si;
	STACK_OF(X509_ATTRIBUTE) *attributes;
	X509			*signercert = NULL;
	EVP_PKEY		*signerkey = NULL;

	/* Create a new sender nonce for all messages 
	 * XXXXXXXXXXXXXX should it be per transaction? */
	s->sender_nonce_len = 16;
	s->sender_nonce = (unsigned char *)malloc(s->sender_nonce_len); 
	RAND_bytes(s->sender_nonce, s->sender_nonce_len);

	/* Prepare data payload */
	switch(s->request_type) {
		case SCEP_REQUEST_PKCSREQ:
			/*
			 * Set printable message type
			 * We set this later as an autheticated attribute
			 * "messageType".
			 */
			s->request_type_str = SCEP_REQUEST_PKCSREQ_STR;

			/* Signer cert */
			signercert = s->signercert;
			signerkey = s->signerkey;

			/* Create inner PKCS#7  */
			if (v_flag)
				printf("%s: creating inner PKCS#7\n", pname);

			/* Read request in memory bio */
			databio = BIO_new(BIO_s_mem());
			if ((rc = i2d_X509_REQ_bio(databio, request)) <= 0) {
				fprintf(stderr, "%s: error writing "
					"certificate request in bio\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_P7);
			}
			BIO_flush(databio);
			BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); 
			break;

		case SCEP_REQUEST_GETCERTINIT:

			/* Set printable message type */
			s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR;

			/* Signer cert */
			signercert = s->signercert;
			signerkey = s->signerkey;

			/* Create inner PKCS#7  */
			if (v_flag)
				printf("%s: creating inner PKCS#7\n", pname);

			/* Read data in memory bio */
			databio = BIO_new(BIO_s_mem());
			if ((rc = i2d_pkcs7_issuer_and_subject_bio(databio,
						s->ias_getcertinit)) <= 0) {
				fprintf(stderr, "%s: error writing "
					"GetCertInitial data in bio\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_P7);
			}
			BIO_flush(databio);
			BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); 
			break;

		case SCEP_REQUEST_GETCERT:
			/* Set printable message type */
			s->request_type_str = SCEP_REQUEST_GETCERT_STR;

			/* Signer cert */
			signercert = localcert;
			signerkey = rsa;

			/* Read data in memory bio */
			databio = BIO_new(BIO_s_mem());
			if ((rc = i2d_PKCS7_ISSUER_AND_SERIAL_bio(databio,
						s->ias_getcert)) <= 0) {
				fprintf(stderr, "%s: error writing "
					"GetCert data in bio\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_P7);
			}
			BIO_flush(databio);
			BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); 
			break;

		case SCEP_REQUEST_GETCRL:
			/* Set printable message type */
			s->request_type_str = SCEP_REQUEST_GETCRL_STR;

			/* Signer cert */
			signercert = localcert;
			signerkey = rsa;

			/* Read data in memory bio */
			databio = BIO_new(BIO_s_mem());
			if ((rc = i2d_PKCS7_ISSUER_AND_SERIAL_bio(databio,
						s->ias_getcrl)) <= 0) {
				fprintf(stderr, "%s: error writing "
					"GetCert data in bio\n", pname);
				ERR_print_errors_fp(stderr);
				exit (SCEP_PKISTATUS_P7);
			}
			BIO_flush(databio);
			BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); 
			break;
	}
	/* Below this is the common code for all request_type */

	/* Read in the payload */
	s->request_len = BIO_get_mem_data(databio, &s->request_payload);
	if (v_flag)
		printf("%s: data payload size: %d bytes\n", pname,
				s->request_len);
	BIO_free(databio);

	/* Create encryption certificate stack */
	if ((recipients = sk_X509_new(NULL)) == NULL) {
		fprintf(stderr, "%s: error creating "
					"certificate stack\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}
	/* Use different CA cert for encryption if requested */
	if (e_flag) {
		if (sk_X509_push(recipients, encert) <= 0) {
			fprintf(stderr, "%s: error adding recipient encryption "
					"certificate\n", pname);
			ERR_print_errors_fp(stderr);
			exit (SCEP_PKISTATUS_P7);
		}
	/* Use same CA cert also for encryption */
	} else {
		if (sk_X509_push(recipients, cacert) <= 0) {
			fprintf(stderr, "%s: error adding recipient encryption "
					"certificate\n", pname);
			ERR_print_errors_fp(stderr);
			exit (SCEP_PKISTATUS_P7);
		}
	}

	/* Create BIO for encryption  */
	if ((encbio = BIO_new_mem_buf(s->request_payload,
				s->request_len)) == NULL) {
		fprintf(stderr, "%s: error creating data " "bio\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	} 

	/* Encrypt */
	if (!(p7enc = PKCS7_encrypt(recipients, encbio,
					enc_alg, PKCS7_BINARY))) {
		fprintf(stderr, "%s: request payload encrypt failed\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}
	if (v_flag)
		printf("%s: successfully encrypted payload\n", pname);

	/* Write encrypted data */
	memorybio = BIO_new(BIO_s_mem());
	if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) {
		fprintf(stderr, "%s: error writing encrypted data\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}
	BIO_flush(memorybio);
	BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); 
	len = BIO_get_mem_data(memorybio, &buffer);
	if (v_flag)
		printf("%s: envelope size: %d bytes\n", pname, len);
	if (d_flag) {
		printf("%s: printing PEM fomatted PKCS#7\n", pname);
		PEM_write_PKCS7(stdout, p7enc);
	}
	BIO_free(memorybio); 

	/* Create outer PKCS#7  */
	if (v_flag)
		printf("%s: creating outer PKCS#7\n", pname);
	s->request_p7 = PKCS7_new();
	if (s->request_p7 == NULL) {
		fprintf(stderr, "%s: failed creating PKCS#7 for signing\n",
					pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}
	if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) {
		fprintf(stderr, "%s: failed setting PKCS#7 type\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}

	/* Add signer certificate  and signature */
	PKCS7_add_certificate(s->request_p7, signercert);
	if ((si = PKCS7_add_signature(s->request_p7,
				signercert, signerkey, sig_alg)) == NULL) {
		fprintf(stderr, "%s: error adding PKCS#7 signature\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}
	if (v_flag)
		printf("%s: signature added successfully\n", pname);

	/* Set signed attributes */
	if (v_flag)
		printf("%s: adding signed attributes\n", pname);
	attributes = sk_X509_ATTRIBUTE_new_null();	
	add_attribute_string(attributes, nid_transId, s->transaction_id);
	add_attribute_string(attributes, nid_messageType, s->request_type_str);
	add_attribute_octet(attributes, nid_senderNonce, s->sender_nonce,
			s->sender_nonce_len);
	PKCS7_set_signed_attributes(si, attributes);
	
	/* Add contentType */
	if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,
			V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) {
		fprintf(stderr, "%s: error adding NID_pkcs9_contentType\n",
					pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}

	/* Create new content */
	if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) {
		fprintf(stderr, "%s: failed setting PKCS#7 content type\n",
					pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}

	/* Write data  */
	pkcs7bio = PKCS7_dataInit(s->request_p7, NULL);
	if (pkcs7bio == NULL) {
		fprintf(stderr, "%s: error opening bio for writing PKCS#7 "
			"data\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}
	if (len != BIO_write(pkcs7bio, buffer, len)) {
		fprintf(stderr, "%s: error writing PKCS#7 data\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}
	if (v_flag)
		printf("%s: PKCS#7 data written successfully\n", pname);

	/* Finalize PKCS#7  */
	if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) {
		fprintf(stderr, "%s: error finalizing outer PKCS#7\n", pname);
		ERR_print_errors_fp(stderr);
		exit (SCEP_PKISTATUS_P7);
	}
	if (d_flag) {
		printf("%s: printing PEM fomatted PKCS#7\n", pname);
		PEM_write_PKCS7(stdout, s->request_p7);
	}

	/* base64-encode the data */
	if (v_flag)
		printf("%s: applying base64 encoding\n",pname);

	/* Create base64 filtering bio */
	memorybio = BIO_new(BIO_s_mem());
	base64bio = BIO_new(BIO_f_base64());
	outbio = BIO_push(base64bio, memorybio);

	/* Copy PKCS#7 */
	i2d_PKCS7_bio(outbio, s->request_p7);
	BIO_flush(outbio);
	BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY);
	s->request_len = BIO_get_mem_data(memorybio, &s->request_payload);
	if (v_flag)
		printf("%s: base64 encoded payload size: %d bytes\n",
				pname, s->request_len);
	BIO_free(outbio);

	return (0);
}
コード例 #12
0
ファイル: paypalSignEncrypt.c プロジェクト: davidhoover/kent
char* sign_and_encrypt(const char *data, RSA *rsa, X509 *x509, X509 *PPx509, int verbose)
/* sign and encrypt button data for safe delivery to paypal */
{
	char *ret = NULL;
	EVP_PKEY *pkey;
	PKCS7 *p7 = NULL;
	BIO *p7bio = NULL;
	BIO *bio = NULL;
	PKCS7_SIGNER_INFO* si;
	int len;
	char *str;

	pkey = EVP_PKEY_new();

	if (EVP_PKEY_set1_RSA(pkey, rsa) == 0)
	{
		fprintf(stderr,"Fatal Error: Unable to create EVP_KEY from RSA key\n");fflush(stderr);
		goto end;
	} else if (verbose) {
		printf("Successfully created EVP_KEY from RSA key\n");
	}

	/* Create a signed and enveloped PKCS7 */
	p7 = PKCS7_new();
	PKCS7_set_type(p7, NID_pkcs7_signedAndEnveloped);

	si = PKCS7_add_signature(p7, x509, pkey, EVP_sha1());

	if (si) {
		if (PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT,
			OBJ_nid2obj(NID_pkcs7_data)) <= 0)
		{
			fprintf(stderr,"Fatal Error: Unable to add signed attribute to certificate\n");
			fprintf(stderr,"OpenSSL Error: %s\n", ERR_error_string(ERR_get_error(), NULL));
			fflush(stderr);
			goto end;
		} else if (verbose) {
			printf("Successfully added signed attribute to certificate\n");
		}

	} else {
		fprintf(stderr,"Fatal Error: Failed to sign PKCS7\n");fflush(stderr);
		goto end;
	}

	/* Encryption */
	if (PKCS7_set_cipher(p7, EVP_des_ede3_cbc()) <= 0)
	{
		fprintf(stderr,"Fatal Error: Failed to set encryption algorithm\n");
		fprintf(stderr,"OpenSSL Error: %s\n", ERR_error_string(ERR_get_error(), NULL));
		fflush(stderr);
		goto end;
	} else if (verbose) {
		printf("Successfully added encryption algorithm\n");
	}

	if (PKCS7_add_recipient(p7, PPx509) <= 0)
	{
		fprintf(stderr,"Fatal Error: Failed to add PKCS7 recipient\n");
		fprintf(stderr,"OpenSSL Error: %s\n", ERR_error_string(ERR_get_error(), NULL));
		fflush(stderr);
		goto end;
	} else if (verbose) {
		printf("Successfully added recipient\n");
	}

	if (PKCS7_add_certificate(p7, x509) <= 0)
	{
		fprintf(stderr,"Fatal Error: Failed to add PKCS7 certificate\n");
		fprintf(stderr,"OpenSSL Error: %s\n", ERR_error_string(ERR_get_error(), NULL));
		fflush(stderr);
		goto end;
	} else if (verbose) {
		printf("Successfully added certificate\n");
	}

	p7bio = PKCS7_dataInit(p7, NULL);
	if (!p7bio) {
		fprintf(stderr,"OpenSSL Error: %s\n", ERR_error_string(ERR_get_error(), NULL));
		fflush(stderr);
		goto end;
	}

	/* Pump data to special PKCS7 BIO. This encrypts and signs it. */
	BIO_write(p7bio, data, strlen(data));
	BIO_flush(p7bio);
	PKCS7_dataFinal(p7, p7bio);

	/* Write PEM encoded PKCS7 */
	bio = BIO_new(BIO_s_mem());

	if (!bio || (PEM_write_bio_PKCS7(bio, p7) == 0))
	{
		fprintf(stderr,"Fatal Error: Failed to create PKCS7 PEM\n");fflush(stderr);
	} else if (verbose) {
		printf("Successfully created PKCS7 PEM\n");
	}

	BIO_flush(bio);
	len = BIO_get_mem_data(bio, &str);
	ret = malloc(sizeof(char)*(len+1));
	memcpy(ret, str, len);
	ret[len] = 0;

end:
	/* Free everything */
	if (bio)
		BIO_free_all(bio);
	if (p7bio)
		BIO_free_all(p7bio);
	if (p7)
		PKCS7_free(p7);
	if (pkey)
		EVP_PKEY_free(pkey);
	return ret;
}
コード例 #13
0
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio)
	{
	int ret=0;
	int i,j;
	BIO *btmp;
	BUF_MEM *buf_mem=NULL;
	BUF_MEM *buf=NULL;
	PKCS7_SIGNER_INFO *si;
	EVP_MD_CTX *mdc,ctx_tmp;
	STACK_OF(X509_ATTRIBUTE) *sk;
	STACK_OF(PKCS7_SIGNER_INFO) *si_sk=NULL;
	unsigned char *p,*pp=NULL;
	int x;
	ASN1_OCTET_STRING *os=NULL;

	i=OBJ_obj2nid(p7->type);
	p7->state=PKCS7_S_HEADER;

	switch (i)
		{
	case NID_pkcs7_signedAndEnveloped:
		/* XXXXXXXXXXXXXXXX */
		si_sk=p7->d.signed_and_enveloped->signer_info;
		os=M_ASN1_OCTET_STRING_new();
		p7->d.signed_and_enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_enveloped:
		/* XXXXXXXXXXXXXXXX */
		os=M_ASN1_OCTET_STRING_new();
		p7->d.enveloped->enc_data->enc_data=os;
		break;
	case NID_pkcs7_signed:
		si_sk=p7->d.sign->signer_info;
		os=p7->d.sign->contents->d.data;
		/* If detached data then the content is excluded */
		if(p7->detached) {
			M_ASN1_OCTET_STRING_free(os);
			p7->d.sign->contents->d.data = NULL;
		}
		break;
		}

	if (si_sk != NULL)
		{
		if ((buf=BUF_MEM_new()) == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
			goto err;
			}
		for (i=0; i<sk_PKCS7_SIGNER_INFO_num(si_sk); i++)
			{
			si=sk_PKCS7_SIGNER_INFO_value(si_sk,i);
			if (si->pkey == NULL) continue;

			j=OBJ_obj2nid(si->digest_alg->algorithm);

			btmp=bio;
			for (;;)
				{
				if ((btmp=BIO_find_type(btmp,BIO_TYPE_MD)) 
					== NULL)
					{
					PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST);
					goto err;
					}
				BIO_get_md_ctx(btmp,&mdc);
				if (mdc == NULL)
					{
					PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_INTERNAL_ERROR);
					goto err;
					}
				if (EVP_MD_CTX_type(mdc) == j)
					break;
				else
					btmp=BIO_next(btmp);
				}
			
			/* We now have the EVP_MD_CTX, lets do the
			 * signing. */
			memcpy(&ctx_tmp,mdc,sizeof(ctx_tmp));
			if (!BUF_MEM_grow(buf,EVP_PKEY_size(si->pkey)))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_BIO_LIB);
				goto err;
				}

			sk=si->auth_attr;

			/* If there are attributes, we add the digest
			 * attribute and only sign the attributes */
			if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0))
				{
				unsigned char md_data[EVP_MAX_MD_SIZE];
				unsigned int md_len;
				ASN1_OCTET_STRING *digest;
				ASN1_UTCTIME *sign_time;
				const EVP_MD *md_tmp;

				/* Add signing time */
				sign_time=X509_gmtime_adj(NULL,0);
				PKCS7_add_signed_attribute(si,
					NID_pkcs9_signingTime,
					V_ASN1_UTCTIME,sign_time);

				/* Add digest */
				md_tmp=EVP_MD_CTX_md(&ctx_tmp);
				EVP_DigestFinal(&ctx_tmp,md_data,&md_len);
				digest=M_ASN1_OCTET_STRING_new();
				M_ASN1_OCTET_STRING_set(digest,md_data,md_len);
				PKCS7_add_signed_attribute(si,
					NID_pkcs9_messageDigest,
					V_ASN1_OCTET_STRING,digest);

				/* Now sign the mess */
				EVP_SignInit(&ctx_tmp,md_tmp);
				x=i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,NULL,
					   i2d_X509_ATTRIBUTE,
					   V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
				pp=(unsigned char *)OPENSSL_malloc(x);
				p=pp;
				i2d_ASN1_SET_OF_X509_ATTRIBUTE(sk,&p,
				           i2d_X509_ATTRIBUTE,
					   V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET);
				EVP_SignUpdate(&ctx_tmp,pp,x);
				OPENSSL_free(pp);
				pp=NULL;
				}

#ifndef NO_DSA
			if (si->pkey->type == EVP_PKEY_DSA)
				ctx_tmp.digest=EVP_dss1();
#endif

			if (!EVP_SignFinal(&ctx_tmp,(unsigned char *)buf->data,
				(unsigned int *)&buf->length,si->pkey))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_EVP_LIB);
				goto err;
				}
			if (!ASN1_STRING_set(si->enc_digest,
				(unsigned char *)buf->data,buf->length))
				{
				PKCS7err(PKCS7_F_PKCS7_DATASIGN,ERR_R_ASN1_LIB);
				goto err;
				}
			}
		}

	if (!p7->detached)
		{
		btmp=BIO_find_type(bio,BIO_TYPE_MEM);
		if (btmp == NULL)
			{
			PKCS7err(PKCS7_F_PKCS7_DATASIGN,PKCS7_R_UNABLE_TO_FIND_MEM_BIO);
			goto err;
			}
		BIO_get_mem_ptr(btmp,&buf_mem);
		/* Mark the BIO read only then we can use its copy of the data
		 * instead of making an extra copy.
		 */
		BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY);
		BIO_set_mem_eof_return(btmp, 0);
		os->data = (unsigned char *)buf_mem->data;
		os->length = buf_mem->length;
#if 0
		M_ASN1_OCTET_STRING_set(os,
			(unsigned char *)buf_mem->data,buf_mem->length);
#endif
		}
	if (pp != NULL) OPENSSL_free(pp);
	pp=NULL;

	ret=1;
err:
	if (buf != NULL) BUF_MEM_free(buf);
	return(ret);
	}