root/openpgpsdk/trunk/tests/test_common.c

Revision 521 (checked in by rachel, 5 years ago)

Initial implementation of Validation of Document Signatures.
(Note: Does not yet interoperate with GPG)
Renamed validate_cb to more accurate name of validate_key_cb.
Implemented validate_data_cb to handle validation of documents & signed cleartext.
Added in error-handling when validation fails.
Turned off unwanted debug output.

Line 
1 #include <assert.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #ifndef WIN32
6 #include <unistd.h>
7 #endif
8 #include <sys/stat.h>
9
10 #include "CUnit/Basic.h"
11 #include "openpgpsdk/readerwriter.h"
12 // \todo remove the need for this
13 #include "../src/advanced/parse_local.h"
14
15 #include "tests.h"
16
17 char dir[MAXBUF+1];
18 ops_keyring_t pub_keyring;
19 ops_keyring_t sec_keyring;
20 static char* no_passphrase="";
21 ops_memory_t* mem_literal_data=NULL;
22
23 char *alpha_user_id="Alpha (RSA, no passphrase) <alpha@test.com>";
24 char *alpha_name="Alpha";
25 const ops_public_key_t *alpha_pkey;
26 const ops_secret_key_t *alpha_skey;
27 const ops_key_data_t *alpha_pub_keydata;
28 const ops_key_data_t *alpha_sec_keydata;
29 char* alpha_passphrase="";
30
31 char *bravo_user_id="Bravo (RSA, passphrase) <bravo@test.com>";
32 char *bravo_name="Bravo";
33 const ops_public_key_t *bravo_pkey;
34 const ops_secret_key_t *bravo_skey;
35 const ops_key_data_t *bravo_pub_keydata;
36 const ops_key_data_t *bravo_sec_keydata;
37 char* bravo_passphrase="hello";
38
39 const ops_key_data_t *decrypter=NULL;
40
41 void setup_test_keys()
42     {
43     char keydetails[MAXBUF+1];
44     char keyring_name[MAXBUF+1];
45     int fd=0;
46     char cmd[MAXBUF+1];
47
48     char *rsa_nopass="Key-Type: RSA\nKey-Usage: encrypt, sign\nName-Real: Alpha\nName-Comment: RSA, no passphrase\nName-Email: alpha@test.com\nKey-Length: 1024\n";
49     char *rsa_pass="Key-Type: RSA\nKey-Usage: encrypt, sign\nName-Real: Bravo\nName-Comment: RSA, passphrase\nName-Email: bravo@test.com\nPassphrase: hello\nKey-Length: 1024\n";
50
51     // Create temp directory
52     if (!mktmpdir())
53         return;
54
55     /*
56      * Create a RSA keypair with no passphrase
57      */
58
59     snprintf(keydetails,MAXBUF,"%s/%s",dir,"keydetails.alpha");
60
61 #ifdef WIN32
62     if ((fd=open(keydetails,O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600))<0)
63 #else
64     if ((fd=open(keydetails,O_WRONLY | O_CREAT | O_EXCL, 0600))<0)
65 #endif
66         {
67         fprintf(stderr,"Can't create Alpha key details\n");
68         return;
69         }
70
71     write(fd,rsa_nopass,strlen(rsa_nopass));
72     close(fd);
73
74     snprintf(cmd,MAXBUF,"gpg --quiet --no-tty --openpgp --quiet --gen-key --s2k-cipher-algo \"AES\" --expert --homedir=%s --batch %s",dir,keydetails);
75     system(cmd);
76
77     /*
78      * Create a RSA keypair with passphrase
79      */
80
81     snprintf(keydetails,MAXBUF,"%s/%s",dir,"keydetails.bravo");
82
83 #ifdef WIN32
84     if ((fd=open(keydetails,O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600))<0)
85 #else
86     if ((fd=open(keydetails,O_WRONLY | O_CREAT | O_EXCL, 0600))<0)
87 #endif
88         {
89         fprintf(stderr,"Can't create Bravo key details\n");
90         return;
91         }
92
93     write(fd,rsa_pass,strlen(rsa_pass));
94     close(fd);
95
96     snprintf(cmd,MAXBUF,"gpg --quiet --no-tty --openpgp --quiet --gen-key --s2k-cipher-algo \"AES\" --expert --homedir=%s --batch %s",dir,keydetails);
97     system(cmd);
98    
99     /*
100      * read keyrings
101      */
102
103     snprintf(keyring_name,MAXBUF,"%s/pubring.gpg", dir);
104     ops_keyring_read(&pub_keyring,keyring_name);
105
106     snprintf(keyring_name,MAXBUF,"%s/secring.gpg", dir);
107     ops_keyring_read(&sec_keyring,keyring_name);
108
109     /*
110      * set up key pointers
111      */
112
113     assert(pub_keyring.nkeys);
114
115     alpha_pub_keydata=ops_keyring_find_key_by_userid(&pub_keyring, alpha_user_id);
116     bravo_pub_keydata=ops_keyring_find_key_by_userid(&pub_keyring, bravo_user_id);
117     assert(alpha_pub_keydata);
118     assert(bravo_pub_keydata);
119
120     alpha_sec_keydata=ops_keyring_find_key_by_userid(&sec_keyring, alpha_user_id);
121     bravo_sec_keydata=ops_keyring_find_key_by_userid(&sec_keyring, bravo_user_id);
122     assert(alpha_sec_keydata);
123     assert(bravo_sec_keydata);
124
125     alpha_pkey=ops_get_public_key_from_data(alpha_pub_keydata);
126     alpha_skey=ops_get_secret_key_from_data(alpha_sec_keydata);
127     bravo_pkey=ops_get_public_key_from_data(bravo_pub_keydata);
128     bravo_skey=ops_decrypt_secret_key_from_data(bravo_sec_keydata,bravo_passphrase);
129
130     assert(alpha_pkey);
131     assert(alpha_skey);
132     assert(bravo_pkey);
133     assert(bravo_skey); //not yet set because of passphrase
134     }
135
136 void cleanup()
137     {
138     char cmd[MAXBUF];
139
140     return;
141
142     /* Remove test dir and files */
143     snprintf(cmd,MAXBUF,"rm -rf %s", dir);
144     if (system(cmd))
145         {
146         perror("Can't delete test directory ");
147         return;
148         }
149     }
150
151 int mktmpdir (void)
152     {
153     int limit=10; // don't try indefinitely
154     long int rnd=0;
155
156 #ifdef WIN32
157     srand( (unsigned)time( NULL ) );
158 #endif
159     while (limit--)
160         {
161         rnd=random();
162         snprintf(dir,MAXBUF,"./testdir.%ld",rnd);
163        
164         // Try to create directory
165 #ifndef WIN32
166         if (!mkdir(dir,0700))
167 #else
168         if (!_mkdir(dir))
169 #endif
170             {
171             // success
172             return 1;
173             }
174         else
175             {
176             fprintf (stderr,"Couldn't open dir: errno=%d\n", errno);
177             perror(NULL);
178             }
179         }
180     fprintf(stderr,"Too many temp dirs: please delete them\n");
181     exit(1);
182     }
183
184 char* create_testtext(const char *text)
185     {
186     const unsigned int repeats=1;
187     unsigned int i=0;
188
189     const unsigned int maxbuf=1024;
190     char buf[maxbuf+1];
191     unsigned int sz_one=0;
192     unsigned int sz_big=0;
193     char* bigbuf=NULL;
194
195     buf[maxbuf]='\0';
196     snprintf(buf,maxbuf,"%s : Test Text\n", text);
197
198     sz_one=strlen(buf);
199     sz_big=sz_one*repeats+1;
200
201     bigbuf=ops_mallocz(sz_big);
202
203    for (i=0; i<repeats; i++)
204         {
205         char* ptr=bigbuf+ (i*(sz_one-1));
206         snprintf(ptr,sz_one,buf);
207         }
208
209    return bigbuf;
210     }
211
212 void create_testdata(const char *text, unsigned char *buf, const int maxlen)
213     {
214     char *preamble=" : Test Data :";
215     int i=0;
216
217     snprintf((char *)buf,maxlen,"%s%s", text, preamble);
218
219 #ifdef WIN32
220     srand( (unsigned)time( NULL ) );
221 #endif
222     for (i=strlen(text)+strlen(preamble); i<maxlen; i++)
223         {
224         buf[i]=(random() & 0xFF);
225         }
226     }
227
228 void create_testfile(const char *name)
229     {
230     char filename[MAXBUF+1];
231     char* testtext=NULL;
232
233     int fd=0;
234     snprintf(filename,MAXBUF,"%s/%s",dir,name);
235 #ifdef WIN32
236     if ((fd=open(filename,O_WRONLY| O_CREAT | O_EXCL | O_BINARY, 0600))<0)
237 #else
238     if ((fd=open(filename,O_WRONLY| O_CREAT | O_EXCL, 0600))<0)
239 #endif
240         return;
241
242     testtext=create_testtext(name);
243     write(fd,testtext,strlen(testtext));
244     close(fd);
245     free(testtext);
246     }
247
248 ops_parse_cb_return_t
249 callback_general(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
250     {
251     ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content;
252    
253     OPS_USED(cbinfo);
254    
255     //    ops_print_packet(content_);
256     
257     switch(content_->tag)
258         {
259     case OPS_PARSER_PTAG:
260         // ignore
261         break;
262        
263     case OPS_PARSER_PACKET_END:
264         // nothing to do
265         break;
266
267     case OPS_PARSER_ERROR:
268         printf("parse error: %s\n",content->error.error);
269         break;
270        
271     case OPS_PARSER_ERRCODE:
272         printf("parse error: %s\n",
273                ops_errcode(content->errcode.errcode));
274         break;
275        
276     default:
277         fprintf(stderr,"Unexpected packet tag=%d (0x%x)\n",content_->tag,
278                 content_->tag);
279         assert(0);
280         }
281    
282     return OPS_RELEASE_MEMORY;
283     }
284
285 ops_parse_cb_return_t
286 callback_cmd_get_secret_key(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
287     {
288     ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content;
289     const ops_key_data_t *keydata=NULL;
290     const ops_secret_key_t *secret;
291     char *passphrase=NULL;
292
293     OPS_USED(cbinfo);
294
295 //    ops_print_packet(content_);
296
297     switch(content_->tag)
298         {
299     case OPS_PARSER_CMD_GET_SECRET_KEY:
300         keydata=ops_keyring_find_key_by_id(&sec_keyring,content->get_secret_key.pk_session_key->key_id);
301         if (!keydata || !ops_key_is_secret(keydata))
302             return 0;
303
304         // Do we need the passphrase and not have it? If so, get it
305         passphrase=NULL;
306
307         /*
308          * Hard-coded to allow automated test
309          */
310         if (keydata==alpha_sec_keydata)
311             passphrase=alpha_passphrase;
312         else if (keydata==bravo_sec_keydata)
313             passphrase=bravo_passphrase;
314         else
315             assert(0);
316
317         /* now get the key from the data */
318         secret=ops_get_secret_key_from_data(keydata);
319         while(!secret)
320             {
321             /* then it must be encrypted */
322             secret=ops_decrypt_secret_key_from_data(keydata,passphrase);
323             }
324        
325         *content->get_secret_key.secret_key=secret;
326         break;
327
328     default:
329         return callback_general(content_,cbinfo);
330         }
331    
332     return OPS_RELEASE_MEMORY;
333     }
334
335 ops_parse_cb_return_t
336 callback_cmd_get_secret_key_passphrase(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
337     {
338     ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content;
339
340     OPS_USED(cbinfo);
341
342 //    ops_print_packet(content_);
343
344     switch(content_->tag)
345         {
346     case OPS_PARSER_CMD_GET_SK_PASSPHRASE:
347         /*
348           Doing this so the test can be automated.
349         */
350         *(content->secret_key_passphrase.passphrase)=ops_malloc_passphrase(no_passphrase);
351         return OPS_KEEP_MEMORY;
352         break;
353        
354     default:
355         return callback_general(content_,cbinfo);
356         }
357    
358     return OPS_RELEASE_MEMORY;
359     }
360
361 ops_parse_cb_return_t
362 callback_literal_data(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
363     {
364     ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content;
365
366     OPS_USED(cbinfo);
367
368     //    ops_print_packet(content_);
369
370     // Read data from packet into static buffer
371     switch(content_->tag)
372         {
373     case OPS_PTAG_CT_LITERAL_DATA_BODY:
374         ops_memory_add(mem_literal_data,
375                        content->literal_data_body.data,
376                        content->literal_data_body.length);
377         break;
378
379     case OPS_PTAG_CT_LITERAL_DATA_HEADER:
380         // ignore
381         break;
382
383     default:
384         return callback_general(content_,cbinfo);
385         }
386
387     return OPS_RELEASE_MEMORY;
388     }
389  
390 // move definition to better location
391 ops_parse_cb_return_t
392 validate_key_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo);
393 ops_parse_cb_return_t
394 validate_data_cb(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo);
395
396 ops_parse_cb_return_t
397 callback_data_signature(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
398     {
399     //    ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content;
400
401     OPS_USED(cbinfo);
402
403     //    ops_print_packet(content_);
404
405     switch(content_->tag)
406         {
407     case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
408     case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY:
409     case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
410
411     case OPS_PTAG_CT_ONE_PASS_SIGNATURE:
412     case OPS_PTAG_CT_SIGNATURE_HEADER:
413     case OPS_PTAG_CT_SIGNATURE_FOOTER:
414
415     case OPS_PTAG_CT_LITERAL_DATA_HEADER:
416     case OPS_PTAG_CT_LITERAL_DATA_BODY:
417
418     case OPS_PTAG_CT_SIGNATURE:
419         return validate_data_cb(content_,cbinfo);
420         break;
421
422     default:
423         return callback_general(content_,cbinfo);
424         }
425
426     return OPS_RELEASE_MEMORY;
427     }
428  
429 ops_parse_cb_return_t
430 callback_pk_session_key(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
431     {
432     ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content;
433    
434     OPS_USED(cbinfo);
435
436     //    ops_print_packet(content_);
437     
438     // Read data from packet into static buffer
439     switch(content_->tag)
440         {
441     case OPS_PTAG_CT_PK_SESSION_KEY:
442                 //      printf ("OPS_PTAG_CT_PK_SESSION_KEY\n");
443         if(decrypter)
444             break;
445
446         decrypter=ops_keyring_find_key_by_id(&sec_keyring,
447                                              content->pk_session_key.key_id);
448         if(!decrypter)
449             break;
450         break;
451
452     default:
453         return callback_general(content_,cbinfo);
454         }
455
456     return OPS_RELEASE_MEMORY;
457     }
458
459 void reset_vars()
460     {
461     ops_memory_init(mem_literal_data,0);
462
463     if (decrypter)
464         {
465         //        free (decrypter);
466         decrypter=NULL;
467         }
468     }
469
470 int file_compare(char* file1, char* file2)
471     {
472     FILE *fp1=NULL;
473     FILE *fp2=NULL;
474     char ch1, ch2;
475     int err=0;
476
477     // open files
478     if ((fp1=fopen(file1,"rb"))==NULL)
479         {
480         fprintf(stderr,"file_compare: cannot open file %s\n",file1);
481         return -1;
482         }
483     if ((fp2=fopen(file2,"rb"))==NULL)
484         {
485         fprintf(stderr,"file_compare: cannot open file %s\n",file2);
486         fclose(fp1);
487         return -1;
488         }
489
490     while(!feof(fp1))
491         {
492         ch1 = fgetc(fp1);
493         if (ferror(fp1))
494             {
495             fprintf(stderr,"file_compare: error reading from file %s\n",file1);
496             err = -1;
497             break;
498             }
499         ch2 = fgetc(fp2);
500         if (ferror(fp2))
501             {
502             fprintf(stderr,"file_compare: error reading from file %s\n",file2);
503             err = -1;
504             break;
505             }
506         if (ch1 != ch2)
507             {
508             printf("Files %s and %s differ\n",file1,file2);
509             err = 1;
510             break;
511             }
512         }
513     fclose(fp1);
514     fclose(fp2);
515     return err;
516     }
517
518 // EOF
519
Note: See TracBrowser for help on using the browser.