• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
add_signed_time(PKCS7_SIGNER_INFO * si)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 
get_signed_time(PKCS7_SIGNER_INFO * si)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 
add_signed_string(PKCS7_SIGNER_INFO * si,char * str)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 
get_signed_string(PKCS7_SIGNER_INFO * si,char * buf,int len)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 /* ########################################### */
add_signed_seq2string(PKCS7_SIGNER_INFO * si,char * str1,char * str2)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 */
get_signed_seq2string(PKCS7_SIGNER_INFO * si,char ** str1,char ** str2)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  */
create_time(void)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 
sk_get_time(STACK_OF (X509_ATTRIBUTE)* sk)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 
create_string(char * str)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 
sk_get_string(STACK_OF (X509_ATTRIBUTE)* sk,char * buf,int len)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 
add_seq2string(PKCS7_SIGNER_INFO * si,char * str1,char * str2)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 */
sk_get_seq2string(STACK_OF (X509_ATTRIBUTE)* sk,char ** str1,char ** str2)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