root/openpgpsdk/trunk/tests/test_rsa_signature.c

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

Signature/verification now interoperates with GPG

Line 
1 #include "CUnit/Basic.h"
2
3 #include <openpgpsdk/types.h>
4 #include "openpgpsdk/keyring.h"
5 #include <openpgpsdk/armour.h>
6 #include "openpgpsdk/packet.h"
7 #include "openpgpsdk/packet-parse.h"
8 #include "openpgpsdk/packet-show.h"
9 #include "openpgpsdk/util.h"
10 #include "openpgpsdk/std_print.h"
11 #include "openpgpsdk/readerwriter.h"
12 #include "openpgpsdk/validate.h"
13
14 // \todo change this once we know it works
15 #include "../src/advanced/parse_local.h"
16
17 #include "tests.h"
18
19 static int debug=0;
20 static int do_gpgtest=0;
21
22 static char *filename_rsa_noarmour_nopassphrase="ops_rsa_signed_noarmour_nopassphrase.txt";
23 static char *filename_rsa_noarmour_passphrase="ops_rsa_signed_noarmour_passphrase.txt";
24 static char *filename_rsa_armour_nopassphrase="ops_rsa_signed_armour_nopassphrase.txt";
25 static char *filename_rsa_armour_passphrase="ops_rsa_signed_armour_passphrase.txt";
26
27 /* Signature suite initialization.
28  * Create temporary directory.
29  * Create temporary test files.
30  */
31
32 int init_suite_rsa_signature(void)
33     {
34     do_gpgtest=0;
35
36     // Create test files
37
38     create_testfile(filename_rsa_noarmour_nopassphrase);
39     create_testfile(filename_rsa_noarmour_passphrase);
40     create_testfile(filename_rsa_armour_nopassphrase);
41     create_testfile(filename_rsa_armour_passphrase);
42
43     // Return success
44     return 0;
45     }
46
47 int init_suite_rsa_signature_gpgtest(void)
48     {
49     init_suite_rsa_signature();
50
51     do_gpgtest=1;
52
53     return 0;
54     }
55
56 int clean_suite_rsa_signature(void)
57     {
58     ops_finish();
59
60     reset_vars();
61
62     return 0;
63     }
64
65 static void test_rsa_signature(const int has_armour, const char *filename, const ops_secret_key_t *skey, ops_hash_algorithm_t hash_alg)
66     {
67     unsigned char keyid[OPS_KEY_ID_SIZE];
68     ops_create_signature_t *sig=NULL;
69
70     char cmd[MAXBUF+1];
71     char myfile[MAXBUF+1];
72     char signed_file[MAXBUF+1];
73     char *suffix= has_armour ? "asc" : "gpg";
74     int fd_in=0;
75     int fd_out=0;
76     int rtn=0;
77     ops_create_info_t *cinfo=NULL;
78     unsigned char buf[MAXBUF];
79    
80     // open file to sign
81     snprintf(myfile,MAXBUF,"%s/%s",dir,filename);
82 #ifdef WIN32
83     fd_in=open(myfile,O_RDONLY | O_BINARY);
84 #else
85     fd_in=open(myfile,O_RDONLY);
86 #endif
87     if(fd_in < 0)
88         {
89         perror(myfile);
90         exit(2);
91         }
92    
93     snprintf(signed_file,MAXBUF,"%s/%s_%s.%s",dir,filename,ops_show_hash_algorithm(hash_alg),suffix);
94 #ifdef WIN32
95     fd_out=open(signed_file,O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600);
96 #else
97     fd_out=open(signed_file,O_WRONLY | O_CREAT | O_EXCL, 0600);
98 #endif
99     if(fd_out < 0)
100         {
101         perror(signed_file);
102         exit(2);
103         }
104    
105     // Set up armour/passphrase options
106     // OPS code armours signatures by default
107
108     assert(has_armour);
109    
110     // set up signature
111     sig=ops_create_signature_new();
112     ops_signature_start_plaintext_signature(sig,(ops_secret_key_t *)skey,hash_alg,OPS_SIG_BINARY);
113
114     // set up output file
115     cinfo=ops_create_info_new();
116     ops_writer_set_fd(cinfo,fd_out);
117     ops_writer_push_dash_escaped(cinfo,sig);
118
119     // Do the signing
120
121     for (;;)
122         {
123         int n=0;
124    
125         n=read(fd_in,buf,sizeof(buf));
126         if (!n)
127             break;
128         assert(n>=0);
129         ops_write(buf,n,cinfo);
130         }
131     close(fd_in);
132
133     // add signature
134
135     ops_writer_switch_to_signature(cinfo);
136     ops_signature_add_creation_time(sig,time(NULL));
137     ops_keyid(keyid,&skey->public_key);
138     ops_signature_add_issuer_key_id(sig,keyid);
139
140     ops_signature_hashed_subpackets_end(sig);
141     ops_write_signature(sig,(ops_public_key_t *)&skey->public_key,(ops_secret_key_t *)skey,cinfo);
142     ops_writer_close(cinfo);
143     close(fd_out);
144
145     /*
146      * Validate output
147      */
148
149     // Check with OPS
150
151     {
152     int fd=0;
153     ops_parse_info_t *pinfo=NULL;
154     validate_data_cb_arg_t validate_arg;
155     ops_validate_result_t result;
156     int rtn=0;
157    
158     if (debug)
159         {
160         fprintf(stderr,"\n***\n*** Starting to parse for validation\n***\n");
161         }
162    
163     // open signed file
164 #ifdef WIN32
165     fd=open(signed_file,O_RDONLY | O_BINARY);
166 #else
167     fd=open(signed_file,O_RDONLY);
168 #endif
169     if(fd < 0)
170         {
171         perror(signed_file);
172         exit(2);
173         }
174    
175     // Set verification reader and handling options
176     
177     pinfo=ops_parse_info_new();
178    
179     memset(&validate_arg,'\0',sizeof validate_arg);
180     validate_arg.result=&result;
181     validate_arg.keyring=&pub_keyring;
182     validate_arg.rarg=ops_reader_get_arg_from_pinfo(pinfo);
183    
184     ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED);
185     ops_parse_cb_set(pinfo,callback_verify,&validate_arg);
186     ops_reader_set_fd(pinfo,fd);
187     pinfo->rinfo.accumulate=ops_true;
188    
189     // Set up armour/passphrase options
190     
191     if (has_armour)
192         ops_reader_push_dearmour(pinfo,ops_false,ops_false,ops_false);
193     //    current_passphrase=has_passphrase ? passphrase : nopassphrase;
194     
195     // Do the verification
196     
197     rtn=ops_parse(pinfo);
198     ops_print_errors(ops_parse_info_get_errors(pinfo));
199     CU_ASSERT(rtn==1);
200    
201     // Tidy up
202     if (has_armour)
203         ops_reader_pop_dearmour(pinfo);
204    
205     ops_parse_info_delete(pinfo);
206    
207     close(fd);
208     }
209
210     // Check signature with GPG
211     {
212
213     snprintf(cmd,MAXBUF,"%s --verify %s", gpgcmd, signed_file);
214     rtn=system(cmd);
215     CU_ASSERT(rtn==0);
216     }
217     }
218
219 void test_rsa_signature_noarmour_nopassphrase(void)
220     {
221     int armour=0;
222     assert(pub_keyring.nkeys);
223     test_rsa_signature(armour,filename_rsa_noarmour_nopassphrase, alpha_skey, OPS_HASH_SHA1);
224 #ifdef TODO
225     test_rsa_signature(armour,filename_rsa_noarmour_nopassphrase, alpha_skey, OPS_HASH_MD5);
226     test_rsa_signature(armour,filename_rsa_noarmour_nopassphrase, alpha_skey, OPS_HASH_RIPEMD);
227     test_rsa_signature(armour,filename_rsa_noarmour_nopassphrase, alpha_skey, OPS_HASH_SHA256);
228     test_rsa_signature(armour,filename_rsa_noarmour_nopassphrase, alpha_skey, OPS_HASH_SHA384);
229     test_rsa_signature(armour,filename_rsa_noarmour_nopassphrase, alpha_skey, OPS_HASH_SHA512);
230 #endif
231     }
232
233 void test_rsa_signature_noarmour_passphrase(void)
234     {
235     int armour=0;
236     assert(pub_keyring.nkeys);
237     test_rsa_signature(armour,filename_rsa_noarmour_passphrase, bravo_skey, OPS_HASH_SHA1);
238     }
239
240 void test_rsa_signature_armour_nopassphrase(void)
241     {
242     int armour=1;
243     assert(pub_keyring.nkeys);
244     test_rsa_signature(armour,filename_rsa_armour_nopassphrase, alpha_skey, OPS_HASH_SHA1);
245     }
246
247 void test_rsa_signature_armour_passphrase(void)
248     {
249     int armour=1;
250     assert(pub_keyring.nkeys);
251     test_rsa_signature(armour,filename_rsa_armour_passphrase, bravo_skey, OPS_HASH_SHA1);
252     }
253
254 CU_pSuite suite_rsa_signature()
255 {
256     CU_pSuite suite = NULL;
257
258     suite = CU_add_suite("RSA Signature Suite", init_suite_rsa_signature, clean_suite_rsa_signature);
259     if (!suite)
260             return NULL;
261
262     // add tests to suite
263     
264 #ifdef TBD
265     if (NULL == CU_add_test(suite, "Unarmoured, no passphrase", test_rsa_signature_noarmour_nopassphrase))
266             return NULL;
267    
268     if (NULL == CU_add_test(suite, "Unarmoured, passphrase", test_rsa_signature_noarmour_passphrase))
269             return NULL;
270 #endif /*TBD*/
271    
272     if (NULL == CU_add_test(suite, "Armoured, no passphrase", test_rsa_signature_armour_nopassphrase))
273             return NULL;
274    
275 #ifdef TBD
276     if (NULL == CU_add_test(suite, "Armoured, passphrase", test_rsa_signature_armour_passphrase))
277             return NULL;
278 #endif   
279     
280     return suite;
281 }
282
283 CU_pSuite suite_rsa_signature_GPGtest()
284 {
285     CU_pSuite suite = NULL;
286
287     suite = CU_add_suite("RSA Signature Suite (GPG interop)", init_suite_rsa_signature_gpgtest, clean_suite_rsa_signature);
288
289     if (!suite)
290             return NULL;
291
292     // add tests to suite
293     
294 #ifdef TBD
295     if (NULL == CU_add_test(suite, "Unarmoured, no passphrase", test_rsa_signature_noarmour_nopassphrase))
296             return NULL;
297    
298     if (NULL == CU_add_test(suite, "Unarmoured, passphrase", test_rsa_signature_noarmour_passphrase))
299             return NULL;
300 #endif /*TBD*/
301    
302     if (NULL == CU_add_test(suite, "Armoured, no passphrase", test_rsa_signature_armour_nopassphrase))
303             return NULL;
304    
305     if (NULL == CU_add_test(suite, "Armoured, passphrase", test_rsa_signature_armour_passphrase))
306             return NULL;
307    
308    
309     return suite;
310 }
311
312 // EOF
313
Note: See TracBrowser for help on using the browser.