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