xref: /onnv-gate/usr/src/common/openssl/crypto/pkcs7/example.c (revision 2139:6243c3338933)
10Sstevel@tonic-gate #include <stdio.h>
20Sstevel@tonic-gate #include <stdlib.h>
30Sstevel@tonic-gate #include <string.h>
40Sstevel@tonic-gate #include <openssl/pkcs7.h>
50Sstevel@tonic-gate #include <openssl/asn1_mac.h>
60Sstevel@tonic-gate #include <openssl/x509.h>
70Sstevel@tonic-gate 
add_signed_time(PKCS7_SIGNER_INFO * si)80Sstevel@tonic-gate int add_signed_time(PKCS7_SIGNER_INFO *si)
90Sstevel@tonic-gate 	{
100Sstevel@tonic-gate 	ASN1_UTCTIME *sign_time;
110Sstevel@tonic-gate 
120Sstevel@tonic-gate 	/* The last parameter is the amount to add/subtract from the current
130Sstevel@tonic-gate 	 * time (in seconds) */
140Sstevel@tonic-gate 	sign_time=X509_gmtime_adj(NULL,0);
150Sstevel@tonic-gate 	PKCS7_add_signed_attribute(si,NID_pkcs9_signingTime,
160Sstevel@tonic-gate 		V_ASN1_UTCTIME,(char *)sign_time);
170Sstevel@tonic-gate 	return(1);
180Sstevel@tonic-gate 	}
190Sstevel@tonic-gate 
get_signed_time(PKCS7_SIGNER_INFO * si)200Sstevel@tonic-gate ASN1_UTCTIME *get_signed_time(PKCS7_SIGNER_INFO *si)
210Sstevel@tonic-gate 	{
220Sstevel@tonic-gate 	ASN1_TYPE *so;
230Sstevel@tonic-gate 
240Sstevel@tonic-gate 	so=PKCS7_get_signed_attribute(si,NID_pkcs9_signingTime);
250Sstevel@tonic-gate 	if (so->type == V_ASN1_UTCTIME)
260Sstevel@tonic-gate 	    return so->value.utctime;
270Sstevel@tonic-gate 	return NULL;
280Sstevel@tonic-gate 	}
290Sstevel@tonic-gate 
300Sstevel@tonic-gate static int signed_string_nid= -1;
310Sstevel@tonic-gate 
add_signed_string(PKCS7_SIGNER_INFO * si,char * str)320Sstevel@tonic-gate void add_signed_string(PKCS7_SIGNER_INFO *si, char *str)
330Sstevel@tonic-gate 	{
340Sstevel@tonic-gate 	ASN1_OCTET_STRING *os;
350Sstevel@tonic-gate 
360Sstevel@tonic-gate 	/* To a an object of OID 1.2.3.4.5, which is an octet string */
370Sstevel@tonic-gate 	if (signed_string_nid == -1)
380Sstevel@tonic-gate 		signed_string_nid=
390Sstevel@tonic-gate 			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
400Sstevel@tonic-gate 	os=ASN1_OCTET_STRING_new();
410Sstevel@tonic-gate 	ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
420Sstevel@tonic-gate 	/* When we add, we do not free */
430Sstevel@tonic-gate 	PKCS7_add_signed_attribute(si,signed_string_nid,
440Sstevel@tonic-gate 		V_ASN1_OCTET_STRING,(char *)os);
450Sstevel@tonic-gate 	}
460Sstevel@tonic-gate 
get_signed_string(PKCS7_SIGNER_INFO * si,char * buf,int len)470Sstevel@tonic-gate int get_signed_string(PKCS7_SIGNER_INFO *si, char *buf, int len)
480Sstevel@tonic-gate 	{
490Sstevel@tonic-gate 	ASN1_TYPE *so;
500Sstevel@tonic-gate 	ASN1_OCTET_STRING *os;
510Sstevel@tonic-gate 	int i;
520Sstevel@tonic-gate 
530Sstevel@tonic-gate 	if (signed_string_nid == -1)
540Sstevel@tonic-gate 		signed_string_nid=
550Sstevel@tonic-gate 			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
560Sstevel@tonic-gate 	/* To retrieve */
570Sstevel@tonic-gate 	so=PKCS7_get_signed_attribute(si,signed_string_nid);
580Sstevel@tonic-gate 	if (so != NULL)
590Sstevel@tonic-gate 		{
600Sstevel@tonic-gate 		if (so->type == V_ASN1_OCTET_STRING)
610Sstevel@tonic-gate 			{
620Sstevel@tonic-gate 			os=so->value.octet_string;
630Sstevel@tonic-gate 			i=os->length;
640Sstevel@tonic-gate 			if ((i+1) > len)
650Sstevel@tonic-gate 				i=len-1;
660Sstevel@tonic-gate 			memcpy(buf,os->data,i);
670Sstevel@tonic-gate 			return(i);
680Sstevel@tonic-gate 			}
690Sstevel@tonic-gate 		}
700Sstevel@tonic-gate 	return(0);
710Sstevel@tonic-gate 	}
720Sstevel@tonic-gate 
730Sstevel@tonic-gate static int signed_seq2string_nid= -1;
740Sstevel@tonic-gate /* ########################################### */
add_signed_seq2string(PKCS7_SIGNER_INFO * si,char * str1,char * str2)750Sstevel@tonic-gate int add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
760Sstevel@tonic-gate 	{
770Sstevel@tonic-gate 	/* To add an object of OID 1.9.999, which is a sequence containing
780Sstevel@tonic-gate 	 * 2 octet strings */
790Sstevel@tonic-gate 	unsigned char *p;
800Sstevel@tonic-gate 	ASN1_OCTET_STRING *os1,*os2;
810Sstevel@tonic-gate 	ASN1_STRING *seq;
820Sstevel@tonic-gate 	unsigned char *data;
830Sstevel@tonic-gate 	int i,total;
840Sstevel@tonic-gate 
850Sstevel@tonic-gate 	if (signed_seq2string_nid == -1)
860Sstevel@tonic-gate 		signed_seq2string_nid=
870Sstevel@tonic-gate 			OBJ_create("1.9.9999","OID_example","Our example OID");
880Sstevel@tonic-gate 
890Sstevel@tonic-gate 	os1=ASN1_OCTET_STRING_new();
900Sstevel@tonic-gate 	os2=ASN1_OCTET_STRING_new();
910Sstevel@tonic-gate 	ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
920Sstevel@tonic-gate 	ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
930Sstevel@tonic-gate 	i =i2d_ASN1_OCTET_STRING(os1,NULL);
940Sstevel@tonic-gate 	i+=i2d_ASN1_OCTET_STRING(os2,NULL);
950Sstevel@tonic-gate 	total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
960Sstevel@tonic-gate 
970Sstevel@tonic-gate 	data=malloc(total);
980Sstevel@tonic-gate 	p=data;
990Sstevel@tonic-gate 	ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
1000Sstevel@tonic-gate 	i2d_ASN1_OCTET_STRING(os1,&p);
1010Sstevel@tonic-gate 	i2d_ASN1_OCTET_STRING(os2,&p);
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 	seq=ASN1_STRING_new();
1040Sstevel@tonic-gate 	ASN1_STRING_set(seq,data,total);
1050Sstevel@tonic-gate 	free(data);
1060Sstevel@tonic-gate 	ASN1_OCTET_STRING_free(os1);
1070Sstevel@tonic-gate 	ASN1_OCTET_STRING_free(os2);
1080Sstevel@tonic-gate 
1090Sstevel@tonic-gate 	PKCS7_add_signed_attribute(si,signed_seq2string_nid,
1100Sstevel@tonic-gate 		V_ASN1_SEQUENCE,(char *)seq);
1110Sstevel@tonic-gate 	return(1);
1120Sstevel@tonic-gate 	}
1130Sstevel@tonic-gate 
1140Sstevel@tonic-gate /* For this case, I will malloc the return strings */
get_signed_seq2string(PKCS7_SIGNER_INFO * si,char ** str1,char ** str2)1150Sstevel@tonic-gate int get_signed_seq2string(PKCS7_SIGNER_INFO *si, char **str1, char **str2)
1160Sstevel@tonic-gate 	{
1170Sstevel@tonic-gate 	ASN1_TYPE *so;
1180Sstevel@tonic-gate 
1190Sstevel@tonic-gate 	if (signed_seq2string_nid == -1)
1200Sstevel@tonic-gate 		signed_seq2string_nid=
1210Sstevel@tonic-gate 			OBJ_create("1.9.9999","OID_example","Our example OID");
1220Sstevel@tonic-gate 	/* To retrieve */
1230Sstevel@tonic-gate 	so=PKCS7_get_signed_attribute(si,signed_seq2string_nid);
1240Sstevel@tonic-gate 	if (so && (so->type == V_ASN1_SEQUENCE))
1250Sstevel@tonic-gate 		{
126*2139Sjp161948 		ASN1_const_CTX c;
1270Sstevel@tonic-gate 		ASN1_STRING *s;
1280Sstevel@tonic-gate 		long length;
1290Sstevel@tonic-gate 		ASN1_OCTET_STRING *os1,*os2;
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 		s=so->value.sequence;
1320Sstevel@tonic-gate 		c.p=ASN1_STRING_data(s);
1330Sstevel@tonic-gate 		c.max=c.p+ASN1_STRING_length(s);
1340Sstevel@tonic-gate 		if (!asn1_GetSequence(&c,&length)) goto err;
1350Sstevel@tonic-gate 		/* Length is the length of the seqence */
1360Sstevel@tonic-gate 
1370Sstevel@tonic-gate 		c.q=c.p;
1380Sstevel@tonic-gate 		if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL)
1390Sstevel@tonic-gate 			goto err;
1400Sstevel@tonic-gate 		c.slen-=(c.p-c.q);
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate 		c.q=c.p;
1430Sstevel@tonic-gate 		if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL)
1440Sstevel@tonic-gate 			goto err;
1450Sstevel@tonic-gate 		c.slen-=(c.p-c.q);
1460Sstevel@tonic-gate 
147*2139Sjp161948 		if (!asn1_const_Finish(&c)) goto err;
1480Sstevel@tonic-gate 		*str1=malloc(os1->length+1);
1490Sstevel@tonic-gate 		*str2=malloc(os2->length+1);
1500Sstevel@tonic-gate 		memcpy(*str1,os1->data,os1->length);
1510Sstevel@tonic-gate 		memcpy(*str2,os2->data,os2->length);
1520Sstevel@tonic-gate 		(*str1)[os1->length]='\0';
1530Sstevel@tonic-gate 		(*str2)[os2->length]='\0';
1540Sstevel@tonic-gate 		ASN1_OCTET_STRING_free(os1);
1550Sstevel@tonic-gate 		ASN1_OCTET_STRING_free(os2);
1560Sstevel@tonic-gate 		return(1);
1570Sstevel@tonic-gate 		}
1580Sstevel@tonic-gate err:
1590Sstevel@tonic-gate 	return(0);
1600Sstevel@tonic-gate 	}
1610Sstevel@tonic-gate 
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate /* #######################################
1640Sstevel@tonic-gate  * THE OTHER WAY TO DO THINGS
1650Sstevel@tonic-gate  * #######################################
1660Sstevel@tonic-gate  */
create_time(void)1670Sstevel@tonic-gate X509_ATTRIBUTE *create_time(void)
1680Sstevel@tonic-gate 	{
1690Sstevel@tonic-gate 	ASN1_UTCTIME *sign_time;
1700Sstevel@tonic-gate 	X509_ATTRIBUTE *ret;
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 	/* The last parameter is the amount to add/subtract from the current
1730Sstevel@tonic-gate 	 * time (in seconds) */
1740Sstevel@tonic-gate 	sign_time=X509_gmtime_adj(NULL,0);
1750Sstevel@tonic-gate 	ret=X509_ATTRIBUTE_create(NID_pkcs9_signingTime,
1760Sstevel@tonic-gate 		V_ASN1_UTCTIME,(char *)sign_time);
1770Sstevel@tonic-gate 	return(ret);
1780Sstevel@tonic-gate 	}
1790Sstevel@tonic-gate 
sk_get_time(STACK_OF (X509_ATTRIBUTE)* sk)1800Sstevel@tonic-gate ASN1_UTCTIME *sk_get_time(STACK_OF(X509_ATTRIBUTE) *sk)
1810Sstevel@tonic-gate 	{
1820Sstevel@tonic-gate 	ASN1_TYPE *so;
1830Sstevel@tonic-gate 	PKCS7_SIGNER_INFO si;
1840Sstevel@tonic-gate 
1850Sstevel@tonic-gate 	si.auth_attr=sk;
1860Sstevel@tonic-gate 	so=PKCS7_get_signed_attribute(&si,NID_pkcs9_signingTime);
1870Sstevel@tonic-gate 	if (so->type == V_ASN1_UTCTIME)
1880Sstevel@tonic-gate 	    return so->value.utctime;
1890Sstevel@tonic-gate 	return NULL;
1900Sstevel@tonic-gate 	}
1910Sstevel@tonic-gate 
create_string(char * str)1920Sstevel@tonic-gate X509_ATTRIBUTE *create_string(char *str)
1930Sstevel@tonic-gate 	{
1940Sstevel@tonic-gate 	ASN1_OCTET_STRING *os;
1950Sstevel@tonic-gate 	X509_ATTRIBUTE *ret;
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	/* To a an object of OID 1.2.3.4.5, which is an octet string */
1980Sstevel@tonic-gate 	if (signed_string_nid == -1)
1990Sstevel@tonic-gate 		signed_string_nid=
2000Sstevel@tonic-gate 			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
2010Sstevel@tonic-gate 	os=ASN1_OCTET_STRING_new();
2020Sstevel@tonic-gate 	ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
2030Sstevel@tonic-gate 	/* When we add, we do not free */
2040Sstevel@tonic-gate 	ret=X509_ATTRIBUTE_create(signed_string_nid,
2050Sstevel@tonic-gate 		V_ASN1_OCTET_STRING,(char *)os);
2060Sstevel@tonic-gate 	return(ret);
2070Sstevel@tonic-gate 	}
2080Sstevel@tonic-gate 
sk_get_string(STACK_OF (X509_ATTRIBUTE)* sk,char * buf,int len)2090Sstevel@tonic-gate int sk_get_string(STACK_OF(X509_ATTRIBUTE) *sk, char *buf, int len)
2100Sstevel@tonic-gate 	{
2110Sstevel@tonic-gate 	ASN1_TYPE *so;
2120Sstevel@tonic-gate 	ASN1_OCTET_STRING *os;
2130Sstevel@tonic-gate 	int i;
2140Sstevel@tonic-gate 	PKCS7_SIGNER_INFO si;
2150Sstevel@tonic-gate 
2160Sstevel@tonic-gate 	si.auth_attr=sk;
2170Sstevel@tonic-gate 
2180Sstevel@tonic-gate 	if (signed_string_nid == -1)
2190Sstevel@tonic-gate 		signed_string_nid=
2200Sstevel@tonic-gate 			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
2210Sstevel@tonic-gate 	/* To retrieve */
2220Sstevel@tonic-gate 	so=PKCS7_get_signed_attribute(&si,signed_string_nid);
2230Sstevel@tonic-gate 	if (so != NULL)
2240Sstevel@tonic-gate 		{
2250Sstevel@tonic-gate 		if (so->type == V_ASN1_OCTET_STRING)
2260Sstevel@tonic-gate 			{
2270Sstevel@tonic-gate 			os=so->value.octet_string;
2280Sstevel@tonic-gate 			i=os->length;
2290Sstevel@tonic-gate 			if ((i+1) > len)
2300Sstevel@tonic-gate 				i=len-1;
2310Sstevel@tonic-gate 			memcpy(buf,os->data,i);
2320Sstevel@tonic-gate 			return(i);
2330Sstevel@tonic-gate 			}
2340Sstevel@tonic-gate 		}
2350Sstevel@tonic-gate 	return(0);
2360Sstevel@tonic-gate 	}
2370Sstevel@tonic-gate 
add_seq2string(PKCS7_SIGNER_INFO * si,char * str1,char * str2)2380Sstevel@tonic-gate X509_ATTRIBUTE *add_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
2390Sstevel@tonic-gate 	{
2400Sstevel@tonic-gate 	/* To add an object of OID 1.9.999, which is a sequence containing
2410Sstevel@tonic-gate 	 * 2 octet strings */
2420Sstevel@tonic-gate 	unsigned char *p;
2430Sstevel@tonic-gate 	ASN1_OCTET_STRING *os1,*os2;
2440Sstevel@tonic-gate 	ASN1_STRING *seq;
2450Sstevel@tonic-gate 	X509_ATTRIBUTE *ret;
2460Sstevel@tonic-gate 	unsigned char *data;
2470Sstevel@tonic-gate 	int i,total;
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	if (signed_seq2string_nid == -1)
2500Sstevel@tonic-gate 		signed_seq2string_nid=
2510Sstevel@tonic-gate 			OBJ_create("1.9.9999","OID_example","Our example OID");
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate 	os1=ASN1_OCTET_STRING_new();
2540Sstevel@tonic-gate 	os2=ASN1_OCTET_STRING_new();
2550Sstevel@tonic-gate 	ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
2560Sstevel@tonic-gate 	ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
2570Sstevel@tonic-gate 	i =i2d_ASN1_OCTET_STRING(os1,NULL);
2580Sstevel@tonic-gate 	i+=i2d_ASN1_OCTET_STRING(os2,NULL);
2590Sstevel@tonic-gate 	total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate 	data=malloc(total);
2620Sstevel@tonic-gate 	p=data;
2630Sstevel@tonic-gate 	ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
2640Sstevel@tonic-gate 	i2d_ASN1_OCTET_STRING(os1,&p);
2650Sstevel@tonic-gate 	i2d_ASN1_OCTET_STRING(os2,&p);
2660Sstevel@tonic-gate 
2670Sstevel@tonic-gate 	seq=ASN1_STRING_new();
2680Sstevel@tonic-gate 	ASN1_STRING_set(seq,data,total);
2690Sstevel@tonic-gate 	free(data);
2700Sstevel@tonic-gate 	ASN1_OCTET_STRING_free(os1);
2710Sstevel@tonic-gate 	ASN1_OCTET_STRING_free(os2);
2720Sstevel@tonic-gate 
2730Sstevel@tonic-gate 	ret=X509_ATTRIBUTE_create(signed_seq2string_nid,
2740Sstevel@tonic-gate 		V_ASN1_SEQUENCE,(char *)seq);
2750Sstevel@tonic-gate 	return(ret);
2760Sstevel@tonic-gate 	}
2770Sstevel@tonic-gate 
2780Sstevel@tonic-gate /* For this case, I will malloc the return strings */
sk_get_seq2string(STACK_OF (X509_ATTRIBUTE)* sk,char ** str1,char ** str2)2790Sstevel@tonic-gate int sk_get_seq2string(STACK_OF(X509_ATTRIBUTE) *sk, char **str1, char **str2)
2800Sstevel@tonic-gate 	{
2810Sstevel@tonic-gate 	ASN1_TYPE *so;
2820Sstevel@tonic-gate 	PKCS7_SIGNER_INFO si;
2830Sstevel@tonic-gate 
2840Sstevel@tonic-gate 	if (signed_seq2string_nid == -1)
2850Sstevel@tonic-gate 		signed_seq2string_nid=
2860Sstevel@tonic-gate 			OBJ_create("1.9.9999","OID_example","Our example OID");
2870Sstevel@tonic-gate 
2880Sstevel@tonic-gate 	si.auth_attr=sk;
2890Sstevel@tonic-gate 	/* To retrieve */
2900Sstevel@tonic-gate 	so=PKCS7_get_signed_attribute(&si,signed_seq2string_nid);
2910Sstevel@tonic-gate 	if (so->type == V_ASN1_SEQUENCE)
2920Sstevel@tonic-gate 		{
293*2139Sjp161948 		ASN1_const_CTX c;
2940Sstevel@tonic-gate 		ASN1_STRING *s;
2950Sstevel@tonic-gate 		long length;
2960Sstevel@tonic-gate 		ASN1_OCTET_STRING *os1,*os2;
2970Sstevel@tonic-gate 
2980Sstevel@tonic-gate 		s=so->value.sequence;
2990Sstevel@tonic-gate 		c.p=ASN1_STRING_data(s);
3000Sstevel@tonic-gate 		c.max=c.p+ASN1_STRING_length(s);
3010Sstevel@tonic-gate 		if (!asn1_GetSequence(&c,&length)) goto err;
3020Sstevel@tonic-gate 		/* Length is the length of the seqence */
3030Sstevel@tonic-gate 
3040Sstevel@tonic-gate 		c.q=c.p;
3050Sstevel@tonic-gate 		if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL)
3060Sstevel@tonic-gate 			goto err;
3070Sstevel@tonic-gate 		c.slen-=(c.p-c.q);
3080Sstevel@tonic-gate 
3090Sstevel@tonic-gate 		c.q=c.p;
3100Sstevel@tonic-gate 		if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL)
3110Sstevel@tonic-gate 			goto err;
3120Sstevel@tonic-gate 		c.slen-=(c.p-c.q);
3130Sstevel@tonic-gate 
314*2139Sjp161948 		if (!asn1_const_Finish(&c)) goto err;
3150Sstevel@tonic-gate 		*str1=malloc(os1->length+1);
3160Sstevel@tonic-gate 		*str2=malloc(os2->length+1);
3170Sstevel@tonic-gate 		memcpy(*str1,os1->data,os1->length);
3180Sstevel@tonic-gate 		memcpy(*str2,os2->data,os2->length);
3190Sstevel@tonic-gate 		(*str1)[os1->length]='\0';
3200Sstevel@tonic-gate 		(*str2)[os2->length]='\0';
3210Sstevel@tonic-gate 		ASN1_OCTET_STRING_free(os1);
3220Sstevel@tonic-gate 		ASN1_OCTET_STRING_free(os2);
3230Sstevel@tonic-gate 		return(1);
3240Sstevel@tonic-gate 		}
3250Sstevel@tonic-gate err:
3260Sstevel@tonic-gate 	return(0);
3270Sstevel@tonic-gate 	}
3280Sstevel@tonic-gate 
3290Sstevel@tonic-gate 
330