#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <openssl/pkcs7.h>

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);
	}

ASN1_UTCTIME *get_signed_time(PKCS7_SIGNER_INFO *si)
	{
	ASN1_TYPE *so;
	ASN1_UTCTIME *ut;

	so=PKCS7_get_signed_attribute(si,NID_pkcs9_signingTime);
	if (so->type == V_ASN1_UTCTIME)
		{
		ut=so->value.utctime;
		}
	return(ut);
	}
	
static int signed_string_nid= -1;

int 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,str,strlen(str));
	/* When we add, we do not free */
	PKCS7_add_signed_attribute(si,signed_string_nid,
		V_ASN1_OCTET_STRING,(char *)os);
	}

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;
			memcpy(buf,os->data,i);
			return(i);
			}
		}
	return(0);
	}

static signed_seq2string_nid= -1;
/* ########################################### */
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;
	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,str1,strlen(str1));
	ASN1_OCTET_STRING_set(os2,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);
	}

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


/* #######################################
 * THE OTHER WAY TO DO THINGS
 * #######################################
 */
X509_ATTRIBUTE *create_time(void)
	{
	ASN1_UTCTIME *sign_time;
	X509_ATTRIBUTE *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 *sk)
	{
	ASN1_TYPE *so;
	ASN1_UTCTIME *ut;
	PKCS7_SIGNER_INFO si;

	si.auth_attr=sk;
	so=PKCS7_get_signed_attribute(&si,NID_pkcs9_signingTime);
	if (so->type == V_ASN1_UTCTIME)
		{
		ut=so->value.utctime;
		}
	return(ut);
	}
	
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();
	ASN1_OCTET_STRING_set(os,str,strlen(str));
	/* When we add, we do not free */
	ret=X509_ATTRIBUTE_create(signed_string_nid,
		V_ASN1_OCTET_STRING,(char *)os);
	return(ret);
	}

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

	si.auth_attr=sk;

	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;
			memcpy(buf,os->data,i);
			return(i);
			}
		}
	return(0);
	}

X509_ATTRIBUTE *add_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;
	X509_ATTRIBUTE *ret;
	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,str1,strlen(str1));
	ASN1_OCTET_STRING_set(os2,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);

	ret=X509_ATTRIBUTE_create(signed_seq2string_nid,
		V_ASN1_SEQUENCE,(char *)seq);
	return(ret);
	}

/* For this case, I will malloc the return strings */
int sk_get_seq2string(STACK *sk, char **str1, char **str2)
	{
	ASN1_TYPE *so;
	PKCS7_SIGNER_INFO si;

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

	si.auth_attr=sk;
	/* To retrieve */
	so=PKCS7_get_signed_attribute(&si,signed_seq2string_nid);
	if (so->type == V_ASN1_SEQUENCE)
		{
		ASN1_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_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);
	}


