root/openpgpsdk/trunk/tests/tests.c

Revision 485 (checked in by rachel, 6 years ago)

RSA encryption produces packets which can be decrypted by GPG.
MDC error still to fix.
Some refactoring to re-use common code in tests.

Line 
1 #include <assert.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <sys/stat.h>
7
8 #include "CUnit/Basic.h"
9 #include "openpgpsdk/readerwriter.h"
10 // \todo remove the need for this
11 #include "../src/advanced/parse_local.h"
12
13 #include "tests.h"
14
15 extern CU_pSuite suite_crypto();
16 extern CU_pSuite suite_packet_types();
17 //extern CU_pSuite suite_crypt_mpi();
18 extern CU_pSuite suite_rsa_decrypt();
19 extern CU_pSuite suite_rsa_encrypt();
20
21 char dir[MAXBUF+1];
22 ops_keyring_t pub_keyring;
23 ops_keyring_t sec_keyring;
24 static char* no_passphrase="";
25 unsigned char* literal_data=NULL;
26 size_t sz_literal_data=0;
27 char *alpha_user_id="Alpha (RSA, no passphrase) <alpha@test.com>";
28
29 void setup_test_keys()
30     {
31     char keydetails[MAXBUF+1];
32     char keyring_name[MAXBUF+1];
33     int fd=0;
34     char cmd[MAXBUF+1];
35
36     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";
37     // Create temp directory
38     if (!mktmpdir())
39         return;
40
41     /*
42      * Create a RSA keypair with no passphrase
43      */
44
45     snprintf(keydetails,MAXBUF,"%s/%s",dir,"keydetails.alpha");
46
47     if ((fd=open(keydetails,O_WRONLY | O_CREAT | O_EXCL, 0600))<0)
48         {
49         fprintf(stderr,"Can't create key details\n");
50         return;
51         }
52
53     write(fd,rsa_nopass,strlen(rsa_nopass));
54     close(fd);
55
56     snprintf(cmd,MAXBUF,"gpg --quiet --gen-key --expert --homedir=%s --batch %s",dir,keydetails);
57     system(cmd);
58    
59     // read keyrings
60
61     snprintf(keyring_name,MAXBUF,"%s/pubring.gpg", dir);
62     ops_keyring_read(&pub_keyring,keyring_name);
63
64     snprintf(keyring_name,MAXBUF,"%s/secring.gpg", dir);
65     ops_keyring_read(&sec_keyring,keyring_name);
66
67     }
68
69 static void cleanup()
70     {
71     char cmd[MAXBUF];
72
73     return;
74
75     /* Remove test dir and files */
76     snprintf(cmd,MAXBUF,"rm -rf %s", dir);
77     if (system(cmd))
78         {
79         perror("Can't delete test directory ");
80         return;
81         }
82     }
83
84 int main()
85     {
86
87     setup_test_keys();
88
89     if (CUE_SUCCESS != CU_initialize_registry())
90         return CU_get_error();
91
92     if (NULL == suite_crypto())
93         {
94         CU_cleanup_registry();
95         return CU_get_error();
96         }
97
98     /*
99     if (NULL == suite_crypt_mpi())
100         {
101         CU_cleanup_registry();
102         return CU_get_error();
103         }
104     */
105
106     if (NULL == suite_packet_types())
107         {
108         CU_cleanup_registry();
109         return CU_get_error();
110         }
111
112     /*
113     if (NULL == suite_rsa_decrypt())
114         {
115         CU_cleanup_registry();
116         return CU_get_error();
117         }
118     */
119
120     if (NULL == suite_rsa_encrypt())
121         {
122         CU_cleanup_registry();
123         return CU_get_error();
124         }
125
126     // Run tests
127     CU_basic_set_mode(CU_BRM_VERBOSE);
128     CU_basic_run_tests();
129     CU_cleanup_registry();
130
131     cleanup();
132
133     return CU_get_error();
134     }
135
136 int mktmpdir (void)
137     {
138     int limit=10; // don't try indefinitely
139     long int rnd=0;
140     while (limit--)
141         {
142         rnd=random();
143         snprintf(dir,MAXBUF,"./testdir.%ld",rnd);
144
145         // Try to create directory
146         if (!mkdir(dir,0700))
147             {
148             // success
149             return 1;
150             }
151         else
152             {
153             fprintf (stderr,"Couldn't open dir: errno=%d\n", errno);
154             perror(NULL);
155             }
156         }
157     return 0;
158     }
159
160 void create_testtext(const char *text, char *buf, const int maxlen)
161     {
162     buf[maxlen]='\0';
163     snprintf(buf,maxlen,"%s : Test Text\n", text);
164     }
165
166 void create_testdata(const char *text, unsigned char *buf, const int maxlen)
167     {
168     char *preamble=" : Test Data :";
169     int i=0;
170
171     snprintf((char *)buf,maxlen,"%s%s", text, preamble);
172
173     for (i=strlen(text)+strlen(preamble); i<maxlen; i++)
174         {
175         buf[i]=(random() & 0xFF);
176         }
177     }
178
179 void create_testfile(const char *name)
180     {
181     char filename[MAXBUF+1];
182     char buffer[MAXBUF+1];
183
184     int fd=0;
185     snprintf(filename,MAXBUF,"%s/%s",dir,name);
186     if ((fd=open(filename,O_WRONLY| O_CREAT | O_EXCL, 0600))<0)
187         return;
188
189     create_testtext(name,&buffer[0],MAXBUF);
190     write(fd,buffer,strlen(buffer));
191     close(fd);
192     }
193
194 ops_parse_cb_return_t
195 callback_general(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
196     {
197     ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content;
198    
199     OPS_USED(cbinfo);
200    
201     //    ops_print_packet(content_);
202     
203     switch(content_->tag)
204         {
205     case OPS_PARSER_PTAG:
206         // ignore
207         break;
208        
209     case OPS_PARSER_ERROR:
210         printf("parse error: %s\n",content->error.error);
211         break;
212        
213     case OPS_PARSER_ERRCODE:
214         printf("parse error: %s\n",
215                ops_errcode(content->errcode.errcode));
216         break;
217        
218     default:
219         fprintf(stderr,"Unexpected packet tag=%d (0x%x)\n",content_->tag,
220                 content_->tag);
221         assert(0);
222         }
223    
224     return OPS_RELEASE_MEMORY;
225     }
226
227 ops_parse_cb_return_t
228 callback_cmd_get_secret_key(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
229     {
230     ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content;
231     const ops_key_data_t *keydata=NULL;
232     const ops_secret_key_t *secret;
233     /*
234     static const ops_key_data_t *decrypt_key;
235     */
236
237     OPS_USED(cbinfo);
238
239 //    ops_print_packet(content_);
240
241     switch(content_->tag)
242         {
243     case OPS_PARSER_CMD_GET_SECRET_KEY:
244         keydata=ops_keyring_find_key_by_id(&sec_keyring,content->get_secret_key.pk_session_key->key_id);
245         if (!keydata || !ops_key_is_secret(keydata))
246             return 0;
247
248         // Do we need the passphrase and not have it? If so, get it
249         ops_parser_content_t pc;
250         char *passphrase;
251         memset(&pc,'\0',sizeof pc);
252         passphrase=NULL;
253         pc.content.secret_key_passphrase.passphrase=&passphrase;
254         //        pc.content.secret_key_passphrase.secret_key=&(keydata->key.skey);
255         pc.content.secret_key_passphrase.secret_key=ops_get_secret_key_from_data(keydata);
256
257         /* Ugh. Need to duplicate this macro here to get the passphrase
258            Duplication to be removed when the callback gets moved to main code.
259            Can we make this inline code rather than a macro?
260         */
261 #define CB(cbinfo,t,pc) do { (pc)->tag=(t); if((cbinfo)->cb(pc,(cbinfo)) == OPS_RELEASE_MEMORY) ops_parser_content_free(pc); } while(0)
262         CB(cbinfo,OPS_PARSER_CMD_GET_SK_PASSPHRASE,&pc);
263        
264         /* now get the key from the data */
265         secret=ops_get_secret_key_from_data(keydata);
266         while(!secret)
267             {
268             /* then it must be encrypted */
269             secret=ops_decrypt_secret_key_from_data(keydata,passphrase);
270             free(passphrase);
271             }
272        
273         *content->get_secret_key.secret_key=secret;
274         break;
275
276     default:
277         return callback_general(content_,cbinfo);
278         }
279    
280     return OPS_RELEASE_MEMORY;
281     }
282
283 ops_parse_cb_return_t
284 callback_cmd_get_secret_key_passphrase(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
285     {
286     ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content;
287     /*
288     static const ops_key_data_t *decrypt_key;
289     const ops_key_data_t *keydata=NULL;
290     const ops_secret_key_t *secret;
291     */
292
293     OPS_USED(cbinfo);
294
295 //    ops_print_packet(content_);
296
297     switch(content_->tag)
298         {
299     case OPS_PARSER_CMD_GET_SK_PASSPHRASE:
300         /*
301           Doing this so the test can be automated.
302           Will move this into separate stacked callback later
303         */
304         *(content->secret_key_passphrase.passphrase)=ops_malloc_passphrase(no_passphrase);
305         return OPS_KEEP_MEMORY;
306         break;
307        
308     default:
309         return callback_general(content_,cbinfo);
310         }
311    
312     return OPS_RELEASE_MEMORY;
313     }
314
315 ops_parse_cb_return_t
316 callback_literal_data(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo)
317     {
318     ops_parser_content_union_t* content=(ops_parser_content_union_t *)&content_->content;
319
320     OPS_USED(cbinfo);
321
322     //    ops_print_packet(content_);
323
324     // Read data from packet into static buffer
325     switch(content_->tag)
326         {
327     case OPS_PTAG_CT_LITERAL_DATA_BODY:
328         sz_literal_data=content->literal_data_body.length;
329         literal_data=ops_mallocz(sz_literal_data+1);
330         memcpy(literal_data,content->literal_data_body.data,sz_literal_data);
331         break;
332
333     case OPS_PTAG_CT_LITERAL_DATA_HEADER:
334         // ignore
335         break;
336
337     default:
338         return callback_general(content_,cbinfo);
339         }
340
341     return OPS_RELEASE_MEMORY;
342     }
343  
344 void reset_vars()
345     {
346     if (literal_data)
347         {
348         free (literal_data);
349         literal_data=NULL;
350         sz_literal_data=0;
351         }
352     }
Note: See TracBrowser for help on using the browser.