root/openpgpsdk/trunk/tests/test_rsa_signature.c

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

Added large file test.
Changed the way gpg is called to cut down on annoying
"standard input has been reopened" messages.

Line 
1 /*
2  * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
3  * All rights reserved.
4  * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
5  * their moral rights under the UK Copyright Design and Patents Act 1988 to
6  * be recorded as the authors of this copyright work.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
9  * use this file except in compliance with the License.
10  *
11  * You may obtain a copy of the License at
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  *
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21
22 #include "CUnit/Basic.h"
23
24 #include <openpgpsdk/types.h>
25 #include "openpgpsdk/keyring.h"
26 #include <openpgpsdk/armour.h>
27 #include "openpgpsdk/packet.h"
28 #include "openpgpsdk/packet-parse.h"
29 #include "openpgpsdk/packet-show.h"
30 #include "openpgpsdk/util.h"
31 #include "openpgpsdk/std_print.h"
32 #include "openpgpsdk/readerwriter.h"
33 #include "openpgpsdk/validate.h"
34
35 // \todo change this once we know it works
36 #include "../src/lib/parse_local.h"
37
38 #include "tests.h"
39
40 static int debug=0;
41
42 static char *filename_rsa_noarmour_nopassphrase="ops_rsa_signed_noarmour_nopassphrase.txt";
43 static char *filename_rsa_noarmour_passphrase="ops_rsa_signed_noarmour_passphrase.txt";
44 static char *filename_rsa_armour_nopassphrase="ops_rsa_signed_armour_nopassphrase.txt";
45 static char *filename_rsa_armour_passphrase="ops_rsa_signed_armour_passphrase.txt";
46 static char *filename_rsa_clearsign_file_nopassphrase="ops_rsa_signed_clearsign_file_nopassphrase.txt";
47 static char *filename_rsa_clearsign_file_passphrase="ops_rsa_signed_clearsign_file_passphrase.txt";
48 static char *filename_rsa_clearsign_buf_nopassphrase="ops_rsa_signed_clearsign_buf_nopassphrase.txt";
49 static char *filename_rsa_clearsign_buf_passphrase="ops_rsa_signed_clearsign_buf_passphrase.txt";
50
51 /* Signature suite initialization.
52  * Create temporary directory.
53  * Create temporary test files.
54  */
55
56 int init_suite_rsa_signature(void)
57     {
58     // Create test files
59
60     create_small_testfile(filename_rsa_noarmour_nopassphrase);
61     create_small_testfile(filename_rsa_noarmour_passphrase);
62     create_small_testfile(filename_rsa_armour_nopassphrase);
63     create_small_testfile(filename_rsa_armour_passphrase);
64     create_small_testfile(filename_rsa_clearsign_file_nopassphrase);
65     create_small_testfile(filename_rsa_clearsign_file_passphrase);
66     create_small_testfile(filename_rsa_clearsign_buf_nopassphrase);
67     create_small_testfile(filename_rsa_clearsign_buf_passphrase);
68
69     // Return success
70     return 0;
71     }
72
73 int clean_suite_rsa_signature(void)
74     {
75     ops_finish();
76
77     reset_vars();
78
79     return 0;
80     }
81
82 static void test_rsa_signature_clearsign_file(const char *filename, const ops_secret_key_t *skey)
83     {
84     char cmd[MAXBUF+1];
85     char myfile[MAXBUF+1];
86     char signed_file[MAXBUF+1];
87     int rtn=0;
88     ops_boolean_t overwrite;
89
90     // setup filenames
91     snprintf(myfile,sizeof myfile,"%s/%s",dir,filename);
92     snprintf(signed_file,sizeof signed_file,"%s.asc",myfile);
93
94     // sign file
95     overwrite=ops_true;
96     ops_sign_file_as_cleartext(myfile, skey, overwrite);
97
98     /*
99      * Validate output
100      */
101
102     // Check with OPS
103
104     {
105     int fd=0;
106     ops_parse_info_t *pinfo=NULL;
107     validate_data_cb_arg_t validate_arg;
108     ops_validate_result_t* result=ops_mallocz(sizeof (ops_validate_result_t));
109     int rtn=0;
110    
111     if (debug)
112         {
113         fprintf(stderr,"\n***\n*** Starting to parse for validation\n***\n");
114         }
115    
116     // open signed file
117 #ifdef WIN32
118     fd=open(signed_file,O_RDONLY | O_BINARY);
119 #else
120     fd=open(signed_file,O_RDONLY);
121 #endif
122     if(fd < 0)
123         {
124         perror(signed_file);
125         exit(2);
126         }
127    
128     // Set verification reader and handling options
129     
130     pinfo=ops_parse_info_new();
131    
132     memset(&validate_arg,'\0',sizeof validate_arg);
133     validate_arg.result=result;
134     validate_arg.keyring=&pub_keyring;
135     validate_arg.rarg=ops_reader_get_arg_from_pinfo(pinfo);
136    
137     ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED);
138     ops_parse_cb_set(pinfo,callback_verify,&validate_arg);
139     ops_reader_set_fd(pinfo,fd);
140     pinfo->rinfo.accumulate=ops_true;
141    
142     // Must de-armour because it's clearsigned
143     
144     ops_reader_push_dearmour(pinfo,ops_false,ops_false,ops_false);
145    
146     // Do the verification
147     
148     rtn=ops_parse(pinfo);
149     ops_print_errors(ops_parse_info_get_errors(pinfo));
150     CU_ASSERT(rtn==1);
151    
152     // Tidy up
153     //    if (has_armour)
154         ops_reader_pop_dearmour(pinfo);
155    
156     ops_parse_info_delete(pinfo);
157    
158     close(fd);
159     ops_validate_result_free(result);
160     }
161
162     // Check signature with GPG
163     {
164
165     //snprintf(cmd,sizeof cmd,"%s --verify %s", gpgcmd, signed_file);
166     snprintf(cmd,sizeof cmd,"cat %s | %s --verify", signed_file, gpgcmd);
167     rtn=system(cmd);
168     CU_ASSERT(rtn==0);
169     }
170     }
171
172 static void test_rsa_signature_clearsign_buf(const char *filename, const ops_secret_key_t *skey)
173     {
174     char cmd[MAXBUF+1];
175     char myfile[MAXBUF+1];
176     char signed_file[MAXBUF+1];
177     int rtn=0;
178     ops_memory_t *input=NULL;
179     ops_memory_t *output=NULL;
180     ops_boolean_t overwrite;
181
182     // setup filenames
183     // (we are testing the function which signs a buf, but still want
184     // to read/write the buffers from/to files for external viewing
185
186     snprintf(myfile,sizeof myfile,"%s/%s",dir,filename);
187     snprintf(signed_file,sizeof signed_file,"%s.asc",myfile);
188
189     // read file contents
190     input=ops_write_buf_from_file(myfile);
191
192     // sign file
193     ops_sign_buf_as_cleartext((const char *)ops_memory_get_data(input),ops_memory_get_length(input),&output,skey);
194
195     // write to file
196     overwrite=ops_true;
197     ops_write_file_from_buf(signed_file, (const char*)ops_memory_get_data(output),ops_memory_get_length(output),overwrite);
198
199     /*
200      * Validate output
201      */
202
203     // Check with OPS
204
205     {
206     int fd=0;
207     ops_parse_info_t *pinfo=NULL;
208     validate_data_cb_arg_t validate_arg;
209     ops_validate_result_t* result=ops_mallocz(sizeof (ops_validate_result_t));
210
211     int rtn=0;
212    
213     if (debug)
214         {
215         fprintf(stderr,"\n***\n*** Starting to parse for validation\n***\n");
216         }
217    
218     // open signed file
219 #ifdef WIN32
220     fd=open(signed_file,O_RDONLY | O_BINARY);
221 #else
222     fd=open(signed_file,O_RDONLY);
223 #endif
224     if(fd < 0)
225         {
226         perror(signed_file);
227         exit(2);
228         }
229    
230     // Set verification reader and handling options
231     
232     pinfo=ops_parse_info_new();
233    
234     memset(&validate_arg,'\0',sizeof validate_arg);
235     validate_arg.result=result;
236     validate_arg.keyring=&pub_keyring;
237     validate_arg.rarg=ops_reader_get_arg_from_pinfo(pinfo);
238    
239     ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED);
240     ops_parse_cb_set(pinfo,callback_verify,&validate_arg);
241     ops_reader_set_fd(pinfo,fd);
242     pinfo->rinfo.accumulate=ops_true;
243    
244     // Must de-armour because it's clearsigned
245     
246     ops_reader_push_dearmour(pinfo,ops_false,ops_false,ops_false);
247    
248     // Do the verification
249     
250     rtn=ops_parse(pinfo);
251     ops_print_errors(ops_parse_info_get_errors(pinfo));
252     CU_ASSERT(rtn==1);
253    
254     // Tidy up
255     //    if (has_armour)
256         ops_reader_pop_dearmour(pinfo);
257    
258     ops_parse_info_delete(pinfo);
259    
260     close(fd);
261     ops_validate_result_free(result);
262     }
263
264     // Check signature with GPG
265     {
266
267     snprintf(cmd,sizeof cmd,"%s --verify %s", gpgcmd, signed_file);
268     rtn=system(cmd);
269     CU_ASSERT(rtn==0);
270     }
271     }
272
273 static void test_rsa_signature_sign(const int use_armour, const char *filename, const ops_secret_key_t *skey)
274     {
275     char cmd[MAXBUF+1];
276     char myfile[MAXBUF+1];
277     char signed_file[MAXBUF+1];
278     char *suffix= use_armour ? "asc" : "gpg";
279     int rtn=0;
280     ops_boolean_t overwrite=ops_true;
281
282     // filenames
283     snprintf(myfile,sizeof myfile,"%s/%s",dir,filename);
284     snprintf(signed_file,sizeof signed_file,"%s.%s",myfile,suffix);
285
286     ops_sign_file(myfile, signed_file, skey, use_armour, overwrite);
287     //ops_sign_file(myfile, NULL, skey, use_armour, overwrite);
288
289     /*
290      * Validate output
291      */
292
293     // Check with OPS
294
295     {
296     int fd=0;
297     ops_parse_info_t *pinfo=NULL;
298     validate_data_cb_arg_t validate_arg;
299     ops_validate_result_t* result=ops_mallocz(sizeof (ops_validate_result_t));;
300     int rtn=0;
301    
302     if (debug)
303         {
304         fprintf(stderr,"\n***\n*** Starting to parse for validation\n***\n");
305         }
306    
307     // open signed file
308 #ifdef WIN32
309     fd=open(signed_file,O_RDONLY | O_BINARY);
310 #else
311     fd=open(signed_file,O_RDONLY);
312 #endif
313     if(fd < 0)
314         {
315         perror(signed_file);
316         exit(2);
317         }
318    
319     // Set verification reader and handling options
320     
321     pinfo=ops_parse_info_new();
322    
323     memset(&validate_arg,'\0',sizeof validate_arg);
324     validate_arg.result=result;
325     validate_arg.keyring=&pub_keyring;
326     validate_arg.rarg=ops_reader_get_arg_from_pinfo(pinfo);
327    
328     ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED);
329     ops_parse_cb_set(pinfo,callback_verify,&validate_arg);
330     ops_reader_set_fd(pinfo,fd);
331     pinfo->rinfo.accumulate=ops_true;
332    
333     // Set up armour/passphrase options
334     
335     if (use_armour)
336         ops_reader_push_dearmour(pinfo,ops_false,ops_false,ops_false);
337    
338     // Do the verification
339     
340     rtn=ops_parse_and_print_errors(pinfo);
341     CU_ASSERT(rtn==1);
342    
343     // Tidy up
344     if (use_armour)
345         ops_reader_pop_dearmour(pinfo);
346    
347     ops_parse_info_delete(pinfo);
348    
349     close(fd);
350     ops_validate_result_free(result);
351     }
352
353     // Check signature with GPG
354     {
355
356     snprintf(cmd,sizeof cmd,"%s --verify %s", gpgcmd, signed_file);
357     rtn=system(cmd);
358     CU_ASSERT(rtn==0);
359     }
360     }
361
362 static void test_rsa_signature_sign_memory(const int use_armour, const void* input, const int input_len, const ops_secret_key_t *skey)
363     {
364     int rtn=0;
365     ops_memory_t* mem=NULL;
366     ops_parse_info_t *pinfo=NULL;
367     validate_data_cb_arg_t validate_arg;
368     ops_validate_result_t* result=ops_mallocz(sizeof (ops_validate_result_t));
369    
370
371     // filenames
372
373     mem=ops_sign_mem(input, input_len, OPS_SIG_TEXT, skey, use_armour);
374
375     /*
376      * Validate output
377      */
378
379     if (debug)
380         {
381         fprintf(stderr,"\n***\n*** Starting to parse for validation\n***\n");
382         }
383    
384     ops_write_file_from_buf("/tmp/memory.asc", ops_memory_get_data(mem), ops_memory_get_length(mem),ops_true);
385
386     // Set verification reader and handling options
387     
388     ops_setup_memory_read(&pinfo, mem, &validate_arg, callback_verify);
389    
390     memset(&validate_arg,'\0',sizeof validate_arg);
391     validate_arg.result=result;
392     validate_arg.keyring=&pub_keyring;
393     validate_arg.rarg=ops_reader_get_arg_from_pinfo(pinfo);
394    
395     ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED);
396     pinfo->rinfo.accumulate=ops_true;
397    
398     // Set up armour/passphrase options
399     
400     if (use_armour)
401         ops_reader_push_dearmour(pinfo,ops_false,ops_false,ops_false);
402    
403     // Do the verification
404     
405     rtn=ops_parse_and_print_errors(pinfo);
406     CU_ASSERT(rtn==1);
407    
408     // Tidy up
409     if (use_armour)
410         ops_reader_pop_dearmour(pinfo);
411    
412     ops_parse_info_delete(pinfo);
413     ops_memory_free(mem);
414     ops_validate_result_free(result);
415     }
416
417 static void test_rsa_signature_noarmour_nopassphrase(void)
418     {
419     unsigned char testdata[MAXBUF];
420     int armour=0;
421     assert(pub_keyring.nkeys);
422     test_rsa_signature_sign(armour,filename_rsa_noarmour_nopassphrase, alpha_skey);
423     create_testdata("test_rsa_signature_noarmour_nopassphrase",testdata, MAXBUF);
424     test_rsa_signature_sign_memory(armour,testdata,MAXBUF, alpha_skey);
425     }
426
427 static void test_rsa_signature_noarmour_passphrase(void)
428     {
429     unsigned char testdata[MAXBUF];
430     int armour=0;
431     assert(pub_keyring.nkeys);
432     test_rsa_signature_sign(armour,filename_rsa_noarmour_passphrase, bravo_skey);
433
434     create_testdata("test_rsa_signature_noarmour_passphrase",testdata, MAXBUF);
435     test_rsa_signature_sign_memory(armour,testdata,MAXBUF, bravo_skey);
436     }
437
438 static void test_rsa_signature_armour_nopassphrase(void)
439     {
440     unsigned char testdata[MAXBUF];
441     int armour=1;
442     assert(pub_keyring.nkeys);
443     test_rsa_signature_sign(armour,filename_rsa_armour_nopassphrase, alpha_skey);
444
445     create_testdata("test_rsa_signature_armour_nopassphrase",testdata, MAXBUF);
446     test_rsa_signature_sign_memory(armour,testdata,MAXBUF, alpha_skey);
447     }
448
449 static void test_rsa_signature_armour_passphrase(void)
450     {
451     unsigned char testdata[MAXBUF];
452
453     int armour=1;
454     assert(pub_keyring.nkeys);
455     test_rsa_signature_sign(armour,filename_rsa_armour_passphrase, bravo_skey);
456
457     create_testdata("test_rsa_signature_armour_passphrase",testdata, MAXBUF);
458     test_rsa_signature_sign_memory(armour,testdata,MAXBUF, bravo_skey);
459     }
460
461 static void test_rsa_signature_clearsign_file_nopassphrase(void)
462     {
463     assert(pub_keyring.nkeys);
464     test_rsa_signature_clearsign_file(filename_rsa_clearsign_file_nopassphrase, alpha_skey);
465     }
466
467 static void test_rsa_signature_clearsign_file_passphrase(void)
468     {
469     assert(pub_keyring.nkeys);
470     test_rsa_signature_clearsign_file(filename_rsa_clearsign_file_passphrase, bravo_skey);
471     }
472
473 static void test_rsa_signature_clearsign_buf_nopassphrase(void)
474     {
475     assert(pub_keyring.nkeys);
476     test_rsa_signature_clearsign_buf(filename_rsa_clearsign_buf_nopassphrase, alpha_skey);
477     }
478
479 static void test_rsa_signature_clearsign_buf_passphrase(void)
480     {
481     assert(pub_keyring.nkeys);
482     test_rsa_signature_clearsign_buf(filename_rsa_clearsign_buf_passphrase, bravo_skey);
483     }
484
485 static void test_todo(void)
486     {
487     CU_FAIL("Test TODO: Test large files");
488     CU_FAIL("Test TODO: Sign with V3 signature?");
489     CU_FAIL("Test TODO: Use other hash algorithms?");
490     CU_FAIL("Test TODO: Check for key/signature expiry");
491     CU_FAIL("Test TODO: Check for key/signature revocation");
492     }
493
494 static int add_tests(CU_pSuite suite)
495     {
496     // add tests to suite
497     
498     if (NULL == CU_add_test(suite, "Unarmoured, no passphrase", test_rsa_signature_noarmour_nopassphrase))
499             return 0;
500    
501     if (NULL == CU_add_test(suite, "Unarmoured, passphrase", test_rsa_signature_noarmour_passphrase))
502             return 0;
503    
504     if (NULL == CU_add_test(suite, "Clearsigned file, no passphrase", test_rsa_signature_clearsign_file_nopassphrase))
505             return 0;
506    
507     if (NULL == CU_add_test(suite, "Clearsigned file, passphrase", test_rsa_signature_clearsign_file_passphrase))
508             return 0;
509
510     if (NULL == CU_add_test(suite, "Clearsigned buf, no passphrase", test_rsa_signature_clearsign_buf_nopassphrase))
511             return 0;
512    
513     if (NULL == CU_add_test(suite, "Clearsigned buf, passphrase", test_rsa_signature_clearsign_buf_passphrase))
514             return 0;
515
516     if (NULL == CU_add_test(suite, "Armoured, no passphrase", test_rsa_signature_armour_nopassphrase))
517             return 0;
518    
519     if (NULL == CU_add_test(suite, "Armoured, passphrase", test_rsa_signature_armour_passphrase))
520             return 0;
521    
522     if (NULL == CU_add_test(suite, "Tests to be implemented", test_todo))
523             return 0;
524    
525     return 1;
526 }
527
528 CU_pSuite suite_rsa_signature()
529 {
530     CU_pSuite suite = NULL;
531
532     suite = CU_add_suite("RSA Signature Suite", init_suite_rsa_signature, clean_suite_rsa_signature);
533     if (!suite)
534             return NULL;
535
536     if (!add_tests(suite))
537         return NULL;
538
539     return suite;
540     }
541
542
543 // EOF
544
Note: See TracBrowser for help on using the browser.