root/openpgpsdk/trunk/tests/test_rsa_keys.c

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

Added some extra error detection.
All tests pass.

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/keyring.h"
25 #include "openpgpsdk/crypto.h"
26 #include "openpgpsdk/packet.h"
27 #include "openpgpsdk/validate.h"
28 #include "openpgpsdk/readerwriter.h"
29 #include "../src/lib/keyring_local.h"
30
31 #include "tests.h"
32
33 //static int debug=0;
34
35 int init_suite_rsa_keys(void)
36     {
37     return 0;
38     }
39
40 int clean_suite_rsa_keys(void)
41     {
42     return 0;
43     }
44
45 static void test_rsa_keys_generate_keypair(void)
46     {
47     ops_keydata_t* keydata=ops_keydata_new();
48     CU_ASSERT(ops_rsa_generate_keypair(1024,65537,keydata)==ops_true);
49     ops_keydata_free(keydata);
50     }
51
52 static void test_rsa_keys_selfsign_keypair(void)
53     {
54     ops_user_id_t uid;
55     uid.user_id=(unsigned char *)"Test User <test@nowhere.com>";
56
57     ops_keydata_t* keydata=NULL;
58
59     keydata=ops_rsa_create_selfsigned_keypair(1024,17,&uid);
60
61     CU_ASSERT(keydata != NULL);
62
63     ops_keydata_free(keydata);
64     }
65
66 static ops_parse_cb_return_t
67 cb_get_passphrase(const ops_parser_content_t *content_,ops_parse_cb_info_t *cbinfo __attribute__((unused)))
68     {
69     const ops_parser_content_union_t *content=&content_->content;
70     //    validate_key_cb_arg_t *arg=ops_parse_cb_get_arg(cbinfo);
71     //    ops_error_t **errors=ops_parse_cb_get_errors(cbinfo);
72
73     switch(content_->tag)
74         {
75     case OPS_PARSER_CMD_GET_SK_PASSPHRASE:
76         /*
77           Doing this so the test can be automated.
78         */
79         *(content->secret_key_passphrase.passphrase)=ops_malloc_passphrase("hello");
80         return OPS_KEEP_MEMORY;
81         break;
82
83     default:
84         break;
85         }
86
87     return OPS_RELEASE_MEMORY;
88     }
89
90 static void verify_keypair(ops_boolean_t armoured)
91     {
92     ops_user_id_t uid;
93     ops_keydata_t* keydata=NULL;
94     ops_create_info_t* cinfo=NULL;
95     ops_validate_result_t* result=NULL;
96     ops_keyring_t pub_keyring;
97     ops_keyring_t sec_keyring;
98     const ops_public_key_t* pub_key=NULL;
99     const ops_secret_key_t* sec_key=NULL;
100     const char* pp="hello";
101     const unsigned char *passphrase=(unsigned char *)pp;
102     const size_t pplen=strlen(pp);
103     char filename[MAXBUF+1];
104     int fd=0;
105     char *suffix = armoured ? "asc" : "ops";
106     char cmd[MAXBUF+1];
107     int rtn=0;
108     ops_boolean_t overwrite=ops_true;
109
110     memset(&pub_keyring, '\0', sizeof pub_keyring);
111     memset(&sec_keyring, '\0', sizeof sec_keyring);
112
113     uid.user_id=(unsigned char *)"Test User 2<test2@nowhere.com>";
114
115     keydata=ops_rsa_create_selfsigned_keypair(1024,65537,&uid);
116     pub_key=ops_get_public_key_from_data(keydata);
117     sec_key=ops_get_secret_key_from_data(keydata);
118
119     CU_ASSERT(keydata != NULL);
120
121     /*
122      * pub key
123      */
124
125     snprintf(filename,MAXBUF,"%s/%s.%s",dir,"ops_transferable_public_key",suffix);
126     fd=ops_setup_file_write(&cinfo, filename,overwrite);
127     ops_write_transferable_public_key(keydata,armoured,cinfo);
128     ops_teardown_file_write(cinfo,fd);
129
130     /*
131      * Validate public key with OPS
132      */
133
134     // generate keyring from this file
135     ops_keyring_read_from_file(&pub_keyring, armoured, filename);
136
137     // validate keyring
138
139     result=ops_mallocz(sizeof(*result));
140
141     ops_validate_all_signatures(result, &pub_keyring, NULL);
142     CU_ASSERT(result->valid_count==1);
143     CU_ASSERT(result->invalid_count==0);
144     CU_ASSERT(result->unknown_signer_count==0);
145
146     ops_validate_result_free(result);
147
148     // Validate public key with GPG
149
150     snprintf(cmd, sizeof cmd, "cat %s | %s --import --no-allow-non-selfsigned-uid", filename, gpgcmd);
151     rtn=system(cmd);
152     CU_ASSERT(rtn==0);
153
154     /*
155      * sec key
156      */
157    
158     result=ops_mallocz(sizeof(*result));
159
160     snprintf(filename,MAXBUF,"%s/%s.%s",dir,"ops_transferable_secret_key",suffix);
161     fd=ops_setup_file_write(&cinfo, filename,overwrite);
162     ops_write_transferable_secret_key(keydata,passphrase,pplen,armoured,cinfo);
163     ops_teardown_file_write(cinfo,fd);
164
165     // generate keyring from this file
166     ops_keyring_read_from_file(&sec_keyring, armoured, filename);
167
168     // validate keyring
169
170     result=ops_mallocz(sizeof(*result));
171
172     ops_validate_all_signatures(result, &sec_keyring, cb_get_passphrase);
173     CU_ASSERT(result->valid_count==1);
174     CU_ASSERT(result->invalid_count==0);
175     CU_ASSERT(result->unknown_signer_count==0);
176
177     ops_validate_result_free(result);
178
179     // validate with GPG
180     snprintf(cmd, sizeof cmd, "cat %s | %s --import --no-allow-non-selfsigned-uid", filename, gpgcmd);
181     rtn=system(cmd);
182     CU_ASSERT(rtn==0);
183
184     // cleanup
185     ops_keydata_free(keydata);
186     }
187
188 static void test_rsa_keys_verify_keypair(void)
189     {
190     ops_boolean_t armoured=ops_false;
191     verify_keypair(armoured);
192     }
193
194 static void test_rsa_keys_read_from_file(void)
195     {
196     ops_keyring_t keyring;
197     ops_boolean_t armoured=ops_false;
198     char filename[MAXBUF+1];
199     snprintf(filename,MAXBUF,"%s/%s", dir, "pubring.gpg");
200
201     memset(&keyring, '\0', sizeof keyring);
202
203     ops_keyring_read_from_file(&keyring, armoured, filename);
204     ops_keyring_free(&keyring);
205     }
206
207 static void test_rsa_keys_verify_armoured_keypair(void)
208     {
209     ops_boolean_t armoured=ops_true;
210     verify_keypair(armoured);
211     }
212
213 static void test_rsa_keys_verify_keypair_fail(void)
214     {
215     ops_user_id_t uid1, uid2;
216     ops_keydata_t* keydata=NULL;
217     const ops_keydata_t* keydata1;
218     const ops_keydata_t* keydata2;
219     const ops_keydata_t* keydata3;
220     ops_create_info_t* cinfo=NULL;
221     ops_validate_result_t* result=NULL;
222     ops_keyring_t keyring1;
223     ops_keyring_t keyring2;
224     ops_keyring_t keyring3;
225     char filename[MAXBUF+1];
226     int fd=0;
227     ops_boolean_t armour=ops_true;
228     char* name1="First User<user1@nowhere.com>";
229     uid1.user_id=(unsigned char *)name1;
230     char* name2="Second<user2@nowhere.com>";
231     uid2.user_id=(unsigned char *)name2;
232     char cmd[MAXBUF+1];
233     int rtn=0;
234     ops_boolean_t overwrite=ops_true;
235
236     memset(&keyring1, '\0', sizeof keyring1);
237     memset(&keyring2, '\0', sizeof keyring2);
238     memset(&keyring3, '\0', sizeof keyring3);
239
240     /*
241      * Create keys and keyrings
242      * Keyring 1: contains good self-signed key 1
243      * Keyring 2: contains good self-signed key 2
244      * Keyring 3: contains self-signed key 3 with bad sig
245      *
246      * Use armoured keys
247      */
248
249     // Keyring 1
250     keydata=ops_rsa_create_selfsigned_keypair(1024,65537,&uid1);
251     CU_ASSERT(keydata != NULL);
252     snprintf(filename,MAXBUF,"%s/%s",dir,"transferable_public_key_1");
253     fd=ops_setup_file_write(&cinfo, filename,overwrite);
254     ops_write_transferable_public_key(keydata,armour,cinfo);
255     ops_teardown_file_write(cinfo,fd);
256     ops_keyring_read_from_file(&keyring1, armour, filename);
257
258     // Keyring 2
259     keydata=ops_rsa_create_selfsigned_keypair(1024,65537,&uid2);
260     CU_ASSERT(keydata2 != NULL);
261     snprintf(filename,MAXBUF,"%s/%s",dir,"transferable_public_key_2");
262     fd=ops_setup_file_write(&cinfo, filename,overwrite);
263     ops_write_transferable_public_key(keydata,armour,cinfo);
264     ops_teardown_file_write(cinfo,fd);
265     ops_keyring_read_from_file(&keyring2, armour, filename);
266
267     // Keyring 3
268     assert(keydata->nsigs==1); // keydata is the key used in keyring2
269     sigpacket_t *sig=&keydata->sigs[0];
270     int target=sig->packet->length/2;
271     unsigned orig=sig->packet->raw[target];
272     // change a byte somewhere near the middle
273     sig->packet->raw[target] = ~orig;
274     assert(orig != sig->packet->raw[target]);
275
276     snprintf(filename,MAXBUF,"%s/%s",dir,"transferable_public_key_3_bad");
277     fd=ops_setup_file_write(&cinfo, filename, overwrite);
278     ops_write_transferable_public_key(keydata,armour,cinfo);
279     ops_teardown_file_write(cinfo,fd);
280     ops_keyring_read_from_file(&keyring3, armour, filename);
281
282     /*
283      * Test: Validate key against keyring without this key in it.
284      * should fail as unknown
285      */
286     result=ops_mallocz(sizeof(*result));
287     keydata1=ops_keyring_find_key_by_userid(&keyring1, name1);
288     assert(keydata1);
289
290     ops_validate_key_signatures(result, keydata1, &keyring2, NULL);
291
292     CU_ASSERT(result->valid_count==0);
293     CU_ASSERT(result->invalid_count==0);
294     CU_ASSERT(result->unknown_signer_count==1);
295     ops_validate_result_free(result);
296
297     /*
298      * Test: Check correct behaviour if signature is bad
299      * Change signature on key to be incorrect.
300      * Then validate key against keyring with this key on it.
301      * Should fail as invalid.
302      */
303
304     result=ops_mallocz(sizeof(ops_validate_result_t));
305     keydata3=ops_keyring_find_key_by_userid(&keyring3, name2);
306     assert(keydata3);
307
308     ops_validate_key_signatures(result, keydata3, &keyring3, NULL);
309
310     CU_ASSERT(result->valid_count==0);
311     CU_ASSERT(result->invalid_count==1);
312     CU_ASSERT(result->unknown_signer_count==0);
313     ops_validate_result_free(result);
314
315     // validate with GPG - should fail
316     snprintf(cmd, sizeof cmd, "cat %s | %s --import --no-allow-non-selfsigned-uid", filename, gpgcmd);
317     rtn=system(cmd);
318     CU_ASSERT(rtn!=0);
319
320     /*
321      * cleanup
322      */
323     ops_keydata_free(keydata);
324     /*
325       ops_keydata_free(keydata1);
326     ops_keydata_free(keydata2);
327     ops_keydata_free(keydata3);
328     */
329     }
330
331 static void test_rsa_keys_todo(void)
332     {
333     /*
334      * Key expiry and revocation checking can be done at the
335      * application level by checking the set of valid keys returned.
336      */
337
338     // expired
339     //CU_FAIL("Test TODO: Check for key expiry");
340
341     // revoked
342     //CU_FAIL("Test TODO: Check for key revocation");
343     }
344
345 CU_pSuite suite_rsa_keys()
346     {
347     CU_pSuite suite=NULL;
348
349     // add suite
350     suite=CU_add_suite("RSA Keys Suite", init_suite_rsa_keys, clean_suite_rsa_keys);
351     if (!suite)
352         return NULL;
353
354     // add tests to suite
355
356     if (NULL == CU_add_test(suite, "Generate key pair", test_rsa_keys_generate_keypair))
357         return NULL;
358
359     if (NULL == CU_add_test(suite, "Self-sign key pair", test_rsa_keys_selfsign_keypair))
360         return NULL;
361
362     if (NULL == CU_add_test(suite, "Verify self-signed key pair", test_rsa_keys_verify_keypair))
363         return NULL;
364
365     if (NULL == CU_add_test(suite, "Verify self-signed key pair (armoured)", test_rsa_keys_verify_armoured_keypair))
366         return NULL;
367
368     if (NULL == CU_add_test(suite, "Verify self-signed key pair fails", test_rsa_keys_verify_keypair_fail))
369         return NULL;
370
371     if (NULL == CU_add_test(suite, "Read keyring from file", test_rsa_keys_read_from_file))
372         return NULL;
373
374     if (NULL == CU_add_test(suite, "TODO", test_rsa_keys_todo))
375         return NULL;
376
377     // return
378     return suite;
379     }
380
381 // EOF
382
Note: See TracBrowser for help on using the browser.