root/openpgpsdk/trunk/tests/test_common.c

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

Signature/verification now interoperates with GPG

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