Home | History | Annotate | Download | only in pkcs7
      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <openssl/pkcs7.h>
      5 #include <openssl/asn1_mac.h>
      6 #include <openssl/x509.h>
      7 
      8 int add_signed_time(PKCS7_SIGNER_INFO *si)
      9 	{
     10 	ASN1_UTCTIME *sign_time;
     11 
     12 	/* The last parameter is the amount to add/subtract from the current
     13 	 * time (in seconds) */
     14 	sign_time=X509_gmtime_adj(NULL,0);
     15 	PKCS7_add_signed_attribute(si,NID_pkcs9_signingTime,
     16 		V_ASN1_UTCTIME,(char *)sign_time);
     17 	return(1);
     18 	}
     19 
     20 ASN1_UTCTIME *get_signed_time(PKCS7_SIGNER_INFO *si)
     21 	{
     22 	ASN1_TYPE *so;
     23 
     24 	so=PKCS7_get_signed_attribute(si,NID_pkcs9_signingTime);
     25 	if (so->type == V_ASN1_UTCTIME)
     26 	    return so->value.utctime;
     27 	return NULL;
     28 	}
     29 
     30 static int signed_string_nid= -1;
     31 
     32 void add_signed_string(PKCS7_SIGNER_INFO *si, char *str)
     33 	{
     34 	ASN1_OCTET_STRING *os;
     35 
     36 	/* To a an object of OID 1.2.3.4.5, which is an octet string */
     37 	if (signed_string_nid == -1)
     38 		signed_string_nid=
     39 			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
     40 	os=ASN1_OCTET_STRING_new();
     41 	ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
     42 	/* When we add, we do not free */
     43 	PKCS7_add_signed_attribute(si,signed_string_nid,
     44 		V_ASN1_OCTET_STRING,(char *)os);
     45 	}
     46 
     47 int get_signed_string(PKCS7_SIGNER_INFO *si, char *buf, int len)
     48 	{
     49 	ASN1_TYPE *so;
     50 	ASN1_OCTET_STRING *os;
     51 	int i;
     52 
     53 	if (signed_string_nid == -1)
     54 		signed_string_nid=
     55 			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
     56 	/* To retrieve */
     57 	so=PKCS7_get_signed_attribute(si,signed_string_nid);
     58 	if (so != NULL)
     59 		{
     60 		if (so->type == V_ASN1_OCTET_STRING)
     61 			{
     62 			os=so->value.octet_string;
     63 			i=os->length;
     64 			if ((i+1) > len)
     65 				i=len-1;
     66 			memcpy(buf,os->data,i);
     67 			return(i);
     68 			}
     69 		}
     70 	return(0);
     71 	}
     72 
     73 static int signed_seq2string_nid= -1;
     74 /* ########################################### */
     75 int add_signed_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
     76 	{
     77 	/* To add an object of OID 1.9.999, which is a sequence containing
     78 	 * 2 octet strings */
     79 	unsigned char *p;
     80 	ASN1_OCTET_STRING *os1,*os2;
     81 	ASN1_STRING *seq;
     82 	unsigned char *data;
     83 	int i,total;
     84 
     85 	if (signed_seq2string_nid == -1)
     86 		signed_seq2string_nid=
     87 			OBJ_create("1.9.9999","OID_example","Our example OID");
     88 
     89 	os1=ASN1_OCTET_STRING_new();
     90 	os2=ASN1_OCTET_STRING_new();
     91 	ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
     92 	ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
     93 	i =i2d_ASN1_OCTET_STRING(os1,NULL);
     94 	i+=i2d_ASN1_OCTET_STRING(os2,NULL);
     95 	total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
     96 
     97 	data=malloc(total);
     98 	p=data;
     99 	ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
    100 	i2d_ASN1_OCTET_STRING(os1,&p);
    101 	i2d_ASN1_OCTET_STRING(os2,&p);
    102 
    103 	seq=ASN1_STRING_new();
    104 	ASN1_STRING_set(seq,data,total);
    105 	free(data);
    106 	ASN1_OCTET_STRING_free(os1);
    107 	ASN1_OCTET_STRING_free(os2);
    108 
    109 	PKCS7_add_signed_attribute(si,signed_seq2string_nid,
    110 		V_ASN1_SEQUENCE,(char *)seq);
    111 	return(1);
    112 	}
    113 
    114 /* For this case, I will malloc the return strings */
    115 int get_signed_seq2string(PKCS7_SIGNER_INFO *si, char **str1, char **str2)
    116 	{
    117 	ASN1_TYPE *so;
    118 
    119 	if (signed_seq2string_nid == -1)
    120 		signed_seq2string_nid=
    121 			OBJ_create("1.9.9999","OID_example","Our example OID");
    122 	/* To retrieve */
    123 	so=PKCS7_get_signed_attribute(si,signed_seq2string_nid);
    124 	if (so && (so->type == V_ASN1_SEQUENCE))
    125 		{
    126 		ASN1_const_CTX c;
    127 		ASN1_STRING *s;
    128 		long length;
    129 		ASN1_OCTET_STRING *os1,*os2;
    130 
    131 		s=so->value.sequence;
    132 		c.p=ASN1_STRING_data(s);
    133 		c.max=c.p+ASN1_STRING_length(s);
    134 		if (!asn1_GetSequence(&c,&length)) goto err;
    135 		/* Length is the length of the seqence */
    136 
    137 		c.q=c.p;
    138 		if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL)
    139 			goto err;
    140 		c.slen-=(c.p-c.q);
    141 
    142 		c.q=c.p;
    143 		if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL)
    144 			goto err;
    145 		c.slen-=(c.p-c.q);
    146 
    147 		if (!asn1_const_Finish(&c)) goto err;
    148 		*str1=malloc(os1->length+1);
    149 		*str2=malloc(os2->length+1);
    150 		memcpy(*str1,os1->data,os1->length);
    151 		memcpy(*str2,os2->data,os2->length);
    152 		(*str1)[os1->length]='\0';
    153 		(*str2)[os2->length]='\0';
    154 		ASN1_OCTET_STRING_free(os1);
    155 		ASN1_OCTET_STRING_free(os2);
    156 		return(1);
    157 		}
    158 err:
    159 	return(0);
    160 	}
    161 
    162 
    163 /* #######################################
    164  * THE OTHER WAY TO DO THINGS
    165  * #######################################
    166  */
    167 X509_ATTRIBUTE *create_time(void)
    168 	{
    169 	ASN1_UTCTIME *sign_time;
    170 	X509_ATTRIBUTE *ret;
    171 
    172 	/* The last parameter is the amount to add/subtract from the current
    173 	 * time (in seconds) */
    174 	sign_time=X509_gmtime_adj(NULL,0);
    175 	ret=X509_ATTRIBUTE_create(NID_pkcs9_signingTime,
    176 		V_ASN1_UTCTIME,(char *)sign_time);
    177 	return(ret);
    178 	}
    179 
    180 ASN1_UTCTIME *sk_get_time(STACK_OF(X509_ATTRIBUTE) *sk)
    181 	{
    182 	ASN1_TYPE *so;
    183 	PKCS7_SIGNER_INFO si;
    184 
    185 	si.auth_attr=sk;
    186 	so=PKCS7_get_signed_attribute(&si,NID_pkcs9_signingTime);
    187 	if (so->type == V_ASN1_UTCTIME)
    188 	    return so->value.utctime;
    189 	return NULL;
    190 	}
    191 
    192 X509_ATTRIBUTE *create_string(char *str)
    193 	{
    194 	ASN1_OCTET_STRING *os;
    195 	X509_ATTRIBUTE *ret;
    196 
    197 	/* To a an object of OID 1.2.3.4.5, which is an octet string */
    198 	if (signed_string_nid == -1)
    199 		signed_string_nid=
    200 			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
    201 	os=ASN1_OCTET_STRING_new();
    202 	ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
    203 	/* When we add, we do not free */
    204 	ret=X509_ATTRIBUTE_create(signed_string_nid,
    205 		V_ASN1_OCTET_STRING,(char *)os);
    206 	return(ret);
    207 	}
    208 
    209 int sk_get_string(STACK_OF(X509_ATTRIBUTE) *sk, char *buf, int len)
    210 	{
    211 	ASN1_TYPE *so;
    212 	ASN1_OCTET_STRING *os;
    213 	int i;
    214 	PKCS7_SIGNER_INFO si;
    215 
    216 	si.auth_attr=sk;
    217 
    218 	if (signed_string_nid == -1)
    219 		signed_string_nid=
    220 			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
    221 	/* To retrieve */
    222 	so=PKCS7_get_signed_attribute(&si,signed_string_nid);
    223 	if (so != NULL)
    224 		{
    225 		if (so->type == V_ASN1_OCTET_STRING)
    226 			{
    227 			os=so->value.octet_string;
    228 			i=os->length;
    229 			if ((i+1) > len)
    230 				i=len-1;
    231 			memcpy(buf,os->data,i);
    232 			return(i);
    233 			}
    234 		}
    235 	return(0);
    236 	}
    237 
    238 X509_ATTRIBUTE *add_seq2string(PKCS7_SIGNER_INFO *si, char *str1, char *str2)
    239 	{
    240 	/* To add an object of OID 1.9.999, which is a sequence containing
    241 	 * 2 octet strings */
    242 	unsigned char *p;
    243 	ASN1_OCTET_STRING *os1,*os2;
    244 	ASN1_STRING *seq;
    245 	X509_ATTRIBUTE *ret;
    246 	unsigned char *data;
    247 	int i,total;
    248 
    249 	if (signed_seq2string_nid == -1)
    250 		signed_seq2string_nid=
    251 			OBJ_create("1.9.9999","OID_example","Our example OID");
    252 
    253 	os1=ASN1_OCTET_STRING_new();
    254 	os2=ASN1_OCTET_STRING_new();
    255 	ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
    256 	ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
    257 	i =i2d_ASN1_OCTET_STRING(os1,NULL);
    258 	i+=i2d_ASN1_OCTET_STRING(os2,NULL);
    259 	total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
    260 
    261 	data=malloc(total);
    262 	p=data;
    263 	ASN1_put_object(&p,1,i,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
    264 	i2d_ASN1_OCTET_STRING(os1,&p);
    265 	i2d_ASN1_OCTET_STRING(os2,&p);
    266 
    267 	seq=ASN1_STRING_new();
    268 	ASN1_STRING_set(seq,data,total);
    269 	free(data);
    270 	ASN1_OCTET_STRING_free(os1);
    271 	ASN1_OCTET_STRING_free(os2);
    272 
    273 	ret=X509_ATTRIBUTE_create(signed_seq2string_nid,
    274 		V_ASN1_SEQUENCE,(char *)seq);
    275 	return(ret);
    276 	}
    277 
    278 /* For this case, I will malloc the return strings */
    279 int sk_get_seq2string(STACK_OF(X509_ATTRIBUTE) *sk, char **str1, char **str2)
    280 	{
    281 	ASN1_TYPE *so;
    282 	PKCS7_SIGNER_INFO si;
    283 
    284 	if (signed_seq2string_nid == -1)
    285 		signed_seq2string_nid=
    286 			OBJ_create("1.9.9999","OID_example","Our example OID");
    287 
    288 	si.auth_attr=sk;
    289 	/* To retrieve */
    290 	so=PKCS7_get_signed_attribute(&si,signed_seq2string_nid);
    291 	if (so->type == V_ASN1_SEQUENCE)
    292 		{
    293 		ASN1_const_CTX c;
    294 		ASN1_STRING *s;
    295 		long length;
    296 		ASN1_OCTET_STRING *os1,*os2;
    297 
    298 		s=so->value.sequence;
    299 		c.p=ASN1_STRING_data(s);
    300 		c.max=c.p+ASN1_STRING_length(s);
    301 		if (!asn1_GetSequence(&c,&length)) goto err;
    302 		/* Length is the length of the seqence */
    303 
    304 		c.q=c.p;
    305 		if ((os1=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL)
    306 			goto err;
    307 		c.slen-=(c.p-c.q);
    308 
    309 		c.q=c.p;
    310 		if ((os2=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL)
    311 			goto err;
    312 		c.slen-=(c.p-c.q);
    313 
    314 		if (!asn1_const_Finish(&c)) goto err;
    315 		*str1=malloc(os1->length+1);
    316 		*str2=malloc(os2->length+1);
    317 		memcpy(*str1,os1->data,os1->length);
    318 		memcpy(*str2,os2->data,os2->length);
    319 		(*str1)[os1->length]='\0';
    320 		(*str2)[os2->length]='\0';
    321 		ASN1_OCTET_STRING_free(os1);
    322 		ASN1_OCTET_STRING_free(os2);
    323 		return(1);
    324 		}
    325 err:
    326 	return(0);
    327 	}
    328 
    329 
    330