int get_signed_string(PKCS7_SIGNER_INFO *si, char *buf, int len)
	{
	ASN1_TYPE *so;
	ASN1_OCTET_STRING *os;
	int i;

	if (signed_string_nid == -1)
		signed_string_nid=
			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
	/* To retrieve */
	so=PKCS7_get_signed_attribute(si,signed_string_nid);
	if (so != NULL)
		{
		if (so->type == V_ASN1_OCTET_STRING)
			{
			os=so->value.octet_string;
			i=os->length;
			if ((i+1) > len)
				i=len-1;
			TINYCLR_SSL_MEMCPY(buf,os->data,i);
			return(i);
			}
		}
	return(0);
	}
Exemplo n.º 2
0
static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx)
{
    unsigned char md_data[EVP_MAX_MD_SIZE];
    unsigned int md_len;

    /* Add signing time if not already present */
    if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) {
        if (!PKCS7_add0_attrib_signing_time(si, NULL)) {
            PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
            return 0;
        }
    }

    /* Add digest */
    if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) {
        PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB);
        return 0;
    }
    if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) {
        PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    /* Now sign the attributes */
    if (!PKCS7_SIGNER_INFO_sign(si))
        return 0;

    return 1;
}
ASN1_UTCTIME *get_signed_time(PKCS7_SIGNER_INFO *si)
	{
	ASN1_TYPE *so;

	so=PKCS7_get_signed_attribute(si,NID_pkcs9_signingTime);
	if (so->type == V_ASN1_UTCTIME)
	    return so->value.utctime;
	return NULL;
	}
Exemplo n.º 4
0
/* For this case, I will malloc the return strings */
int
get_signed_seq2string(PKCS7_SIGNER_INFO *si, char **str1, char **str2)
{
	ASN1_TYPE *so;

	if (signed_seq2string_nid == -1)
		signed_seq2string_nid =
		    OBJ_create("1.9.9999","OID_example","Our example OID");
	/* To retrieve */
	so = PKCS7_get_signed_attribute(si, signed_seq2string_nid);
	if (so && (so->type == V_ASN1_SEQUENCE)) {
		ASN1_const_CTX c;
		ASN1_STRING *s;
		long length;
		ASN1_OCTET_STRING *os1, *os2;

		s = so->value.sequence;
		c.p = ASN1_STRING_data(s);
		c.max = c.p + ASN1_STRING_length(s);
		if (!asn1_GetSequence(&c, &length))
			goto err;
		/* Length is the length of the seqence */

		c.q = c.p;
		if ((os1 = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
			goto err;
		c.slen -= (c.p - c.q);

		c.q = c.p;
		if ((os2 = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
			goto err;
		c.slen -= (c.p - c.q);

		if (!asn1_const_Finish(&c))
			goto err;
		*str1 = malloc(os1->length + 1);
		*str2 = malloc(os2->length + 1);
		memcpy(*str1, os1->data, os1->length);
		memcpy(*str2, os2->data, os2->length);
		(*str1)[os1->length]='\0';
		(*str2)[os2->length]='\0';
		ASN1_OCTET_STRING_free(os1);
		ASN1_OCTET_STRING_free(os2);
		return (1);
	}
err:
	return (0);
}
static VALUE
ossl_pkcs7si_get_signed_time(VALUE self)
{
    PKCS7_SIGNER_INFO *p7si;
    ASN1_TYPE *asn1obj;

    GetPKCS7si(self, p7si);

    if (!(asn1obj = PKCS7_get_signed_attribute(p7si, NID_pkcs9_signingTime))) {
	ossl_raise(ePKCS7Error, NULL);
    }
    if (asn1obj->type == V_ASN1_UTCTIME) {
	return asn1time_to_time(asn1obj->value.utctime);
    }
    /*
     * OR
     * ossl_raise(ePKCS7Error, "...");
     * ?
     */

    return Qnil;
}
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);
	}
	/* The last parameter is the amount to add/subtract from the current
	 * time (in seconds) */
	sign_time=X509_gmtime_adj(NULL,0);
	ret=X509_ATTRIBUTE_create(NID_pkcs9_signingTime,
		V_ASN1_UTCTIME,(char *)sign_time);
	return(ret);
	}

ASN1_UTCTIME *sk_get_time(STACK_OF(X509_ATTRIBUTE) *sk)
	{
	ASN1_TYPE *so;
	PKCS7_SIGNER_INFO si;

	si.auth_attr=sk;
	so=PKCS7_get_signed_attribute(&si,NID_pkcs9_signingTime);
	if (so->type == V_ASN1_UTCTIME)
	    return so->value.utctime;
	return NULL;
	}
	
X509_ATTRIBUTE *create_string(char *str)
	{
	ASN1_OCTET_STRING *os;
	X509_ATTRIBUTE *ret;

	/* 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();