Added SILC Server library.
[silc.git] / lib / silccrypt / tests / test_silcpkcs.c
1 /* Tests API in silcpkcs.h */
2 #include "silc.h"
3
4 int key_len = 2048;
5 const unsigned char p[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f";
6 int p_len = 32;
7
8 int test()
9 {
10   SilcBool success = FALSE;
11   SilcPKCS pkcs;
12   unsigned char *pk, *prv;
13   char *identifier;
14   SilcUInt32 pk_len = 0, prv_len = 0;
15   SilcPublicKey pubkey, pubkey2;
16   SilcPublicKeyIdentifier ident;
17   SilcPrivateKey privkey;
18   SilcBuffer buf;
19   unsigned char d[4096], d2[4096];
20   SilcUInt32 dlen, d2len;
21   SilcHash sha1;
22
23   SILC_LOG_DEBUG(("Registering PKCSs"));
24   if (!silc_pkcs_register_default()) {
25     SILC_LOG_DEBUG(("Registering PKCSs failed"));
26     goto err;
27   }
28   SILC_LOG_DEBUG(("Supported PKCS: %s", silc_pkcs_get_supported()));
29
30
31   SILC_LOG_DEBUG(("Allocate rsa PKCS"));
32   if (!silc_pkcs_is_supported("rsa")) {
33     SILC_LOG_DEBUG(("rsa PKCS not supported"));
34     goto err;
35   }
36   if (!silc_pkcs_alloc("rsa", &pkcs)) {
37     SILC_LOG_DEBUG(("Allocate rsa PKCS failed"));
38     goto err;
39   }
40
41
42   SILC_LOG_DEBUG(("Generating new key pair"));
43   if (!silc_pkcs_generate_key(pkcs, key_len, NULL)) {
44     SILC_LOG_DEBUG(("Generating new key pair failed"));
45     goto err;
46   }
47
48
49   SILC_LOG_DEBUG(("Key length: %d", silc_pkcs_get_key_len(pkcs)));
50   if (silc_pkcs_get_key_len(pkcs) != key_len) {
51     SILC_LOG_DEBUG(("Bad key length: %d != %d",
52                     silc_pkcs_get_key_len(pkcs), key_len));
53     goto err;
54   }
55   SILC_LOG_DEBUG(("PKCS name: %s", silc_pkcs_get_name(pkcs)));
56
57   SILC_LOG_DEBUG(("------"));
58   SILC_LOG_DEBUG(("------ Testing Public Key Routines"));
59   SILC_LOG_DEBUG(("------"));
60
61   SILC_LOG_DEBUG(("Get public key from PKCS"));
62   pk = silc_pkcs_get_public_key(pkcs, &pk_len);
63   if (!pk || !pk_len) {
64     SILC_LOG_DEBUG(("Getting public key failed"));
65     goto err;
66   }
67   SILC_LOG_DEBUG(("Making new public key identifier"));
68   identifier = silc_pkcs_encode_identifier("foo", "bar", "foo bar",
69                                            "foo@bar.com", "bar", "BB");
70   if (!identifier) {
71     SILC_LOG_DEBUG(("Making new public key identifier failed"));
72     goto err;
73   }
74   SILC_LOG_DEBUG(("Decoding public key identifier"));
75   ident = silc_pkcs_decode_identifier(identifier);
76   if (!ident) {
77     SILC_LOG_DEBUG(("Decoding public key identifier failed"));
78     goto err;
79   }
80   SILC_LOG_DEBUG(("Allocating SilcPublicKey"));
81   pubkey = silc_pkcs_public_key_alloc("rsa", identifier, pk, pk_len);
82   if (!pubkey) {
83     SILC_LOG_DEBUG(("Allocating SilcPublicKey failed"));
84     goto err;
85   }
86   silc_free(pk);
87   SILC_LOG_DEBUG(("Encode SilcPublicKey data"));
88   pk = silc_pkcs_public_key_encode(pubkey, &pk_len);
89   if (!pk) {
90     SILC_LOG_DEBUG(("Encode SilcPublicKey data failed"));
91     goto err;
92   }
93   SILC_LOG_DEBUG(("Decode public key to SilcPublicKey"));
94   if (!silc_pkcs_public_key_decode(pk, pk_len, &pubkey)) {
95     SILC_LOG_DEBUG(("Decode public key to SilcPublicKey failed"));
96     goto err;
97   }
98   SILC_LOG_DEBUG(("Save public key to publickey.pub"));
99   unlink("publickey.pub");
100   if (!silc_pkcs_save_public_key("publickey.pub", pubkey,
101                                  SILC_PKCS_FILE_PEM)) {
102     SILC_LOG_DEBUG(("Save public key to publickey.pub failed"));
103     goto err;
104   }
105   SILC_LOG_DEBUG(("Copying public key"));
106   pubkey2 = silc_pkcs_public_key_copy(pubkey);
107   if (!pubkey2) {
108     SILC_LOG_DEBUG(("Copying public key failed"));
109     goto err;
110   }
111   silc_pkcs_public_key_free(pubkey);
112   SILC_LOG_DEBUG(("Load public key"));
113   if (!silc_pkcs_load_public_key("publickey.pub", &pubkey,
114                                  SILC_PKCS_FILE_PEM)) {
115     SILC_LOG_DEBUG(("Load public key failed"));
116     goto err;
117   }
118   SILC_LOG_DEBUG(("Comparing copied and loaded public keys"));
119   if (!silc_pkcs_public_key_compare(pubkey, pubkey2)) {
120     SILC_LOG_DEBUG(("Comparing copied and loaded public keys failed"));
121     goto err;
122   }
123   SILC_LOG_DEBUG(("Match"));
124   SILC_LOG_DEBUG(("Set public key to PKCS"));
125   if (!silc_pkcs_public_key_set(pkcs, pubkey)) {
126     SILC_LOG_DEBUG(("Set public key to PKCS"));
127     goto err;
128   }
129   SILC_LOG_DEBUG(("Encoding public key payload"));
130   buf = silc_pkcs_public_key_payload_encode(pubkey);
131   if (!buf) {
132     SILC_LOG_DEBUG(("Encoding public key payload failed"));
133     goto err;
134   }
135   silc_pkcs_public_key_free(pubkey2);
136   SILC_LOG_DEBUG(("Decoding public key payload"));
137   if (!silc_pkcs_public_key_payload_decode(buf->data, buf->len, &pubkey2)) {
138     SILC_LOG_DEBUG(("Decoding public key payload failed"));
139     goto err;
140   }
141   SILC_LOG_DEBUG(("Comparing decoded and original public keys"));
142   if (!silc_pkcs_public_key_compare(pubkey2, pubkey)) {
143     SILC_LOG_DEBUG(("Comparing decoded and original public keys failed"));
144     goto err;
145   }
146   SILC_LOG_DEBUG(("Match"));
147   SILC_LOG_DEBUG(("Dumping public key identifier"));
148   silc_show_public_key("publickey.pub");
149   unlink("publickey.pub");
150   silc_free(pk);
151   silc_free(identifier);
152   silc_pkcs_free_identifier(ident);
153   silc_pkcs_public_key_free(pubkey);
154   silc_pkcs_public_key_free(pubkey2);
155
156
157   SILC_LOG_DEBUG(("------"));
158   SILC_LOG_DEBUG(("------ Testing Private Key Routines"));
159   SILC_LOG_DEBUG(("------"));
160
161   SILC_LOG_DEBUG(("Get private key from PKCS"));
162   prv = silc_pkcs_get_private_key(pkcs, &prv_len);
163   if (!prv || !prv_len) {
164     SILC_LOG_DEBUG(("Getting private key failed"));
165     goto err;
166   }
167   SILC_LOG_DEBUG(("Allocating SilcPrivateKey"));
168   privkey = silc_pkcs_private_key_alloc("rsa", prv, prv_len);
169   if (!privkey) {
170     SILC_LOG_DEBUG(("Allocating SilcPrivateKey failed"));
171     goto err;
172   }
173   silc_free(prv);
174   SILC_LOG_DEBUG(("Encode SilcPrivateKey data"));
175   prv = silc_pkcs_private_key_encode(privkey, &prv_len);
176   if (!prv) {
177     SILC_LOG_DEBUG(("Encode SilcPrivateKey data failed"));
178     goto err;
179   }
180   SILC_LOG_DEBUG(("Decode private key to SilcPrivateKey"));
181   if (!silc_pkcs_private_key_decode(prv, prv_len, &privkey)) {
182     SILC_LOG_DEBUG(("Decode private key to SilcPrivateKey failed"));
183     goto err;
184   }
185   SILC_LOG_DEBUG(("Save private key to privkey.prv"));
186   unlink("privkey.prv");
187   if (!silc_pkcs_save_private_key("privkey.prv", privkey,
188                                   "foobar", 6,
189                                   SILC_PKCS_FILE_BIN)) {
190     SILC_LOG_DEBUG(("Save private key to priv.pub failed"));
191     goto err;
192   }
193   silc_pkcs_private_key_free(privkey);
194   SILC_LOG_DEBUG(("Load private key"));
195   if (!silc_pkcs_load_private_key("privkey.prv", &privkey, "foobar", 6,
196                                   SILC_PKCS_FILE_BIN)) {
197     SILC_LOG_DEBUG(("Load private key failed"));
198     goto err;
199   }
200   SILC_LOG_DEBUG(("Set private key to PKCS"));
201   if (!silc_pkcs_private_key_set(pkcs, privkey)) {
202     SILC_LOG_DEBUG(("Set private key to PKCS"));
203     goto err;
204   }
205   unlink("privkey.prv");
206   silc_free(prv);
207   silc_pkcs_private_key_free(privkey);
208
209
210   SILC_LOG_DEBUG(("------"));
211   SILC_LOG_DEBUG(("------ Testing Public Key Cryptography Operations"));
212   SILC_LOG_DEBUG(("------"));
213
214   memset(d, 0, sizeof(d));
215   memset(d2, 0, sizeof(d2));
216
217   SILC_LOG_DEBUG(("Encrypting data"));
218   if (!silc_pkcs_encrypt(pkcs, (unsigned char *)p, p_len, d, &dlen)) {
219     SILC_LOG_DEBUG(("Encrypting data failed"));
220     goto err;
221   }
222   SILC_LOG_DEBUG(("Decrypting data"));
223   if (!silc_pkcs_decrypt(pkcs, d, dlen, d2, &d2len)) {
224     SILC_LOG_DEBUG(("Decrypting data failed"));
225     goto err;
226   }
227   SILC_LOG_HEXDUMP(("Plaintext"), p, p_len);
228   SILC_LOG_HEXDUMP(("Ciphertext"), d, dlen);
229   SILC_LOG_HEXDUMP(("Decrypted"), d2, d2len);
230   if (memcmp(p, d2, p_len)) {
231     SILC_LOG_DEBUG(("Decryption failed"));
232     goto err;
233   }
234   SILC_LOG_DEBUG(("Decryption successful"));
235   memset(d, 0, sizeof(d));
236   memset(d2, 0, sizeof(d2));
237
238   SILC_LOG_DEBUG(("Signing data"));
239   if (!silc_pkcs_sign(pkcs, (unsigned char *)p, p_len, d, &dlen)) {
240     SILC_LOG_DEBUG(("Signing data failed"));
241     goto err;
242   }
243   SILC_LOG_HEXDUMP(("Data"), p, p_len);
244   SILC_LOG_HEXDUMP(("signature"), d, dlen);
245   SILC_LOG_DEBUG(("Verifying data"));
246   if (!silc_pkcs_verify(pkcs, d, dlen, (unsigned char *)p, p_len)) {
247     SILC_LOG_DEBUG(("Verifying data failed"));
248     goto err;
249   }
250   SILC_LOG_DEBUG(("Verification successful"));
251
252   silc_hash_alloc("sha1", &sha1);
253   SILC_LOG_DEBUG(("Signing data with hash"));
254   if (!silc_pkcs_sign_with_hash(pkcs, sha1, (unsigned char *)p, p_len,
255                                 d, &dlen)) {
256     SILC_LOG_DEBUG(("Signing data with hash failed"));
257     goto err;
258   }
259   SILC_LOG_HEXDUMP(("Data"), p, p_len);
260   SILC_LOG_HEXDUMP(("signature"), d, dlen);
261   SILC_LOG_DEBUG(("Verifying data with hash"));
262   if (!silc_pkcs_verify_with_hash(pkcs, sha1, d, dlen,
263                                   (unsigned char *)p, p_len)) {
264     SILC_LOG_DEBUG(("Verifying data with hash failed"));
265     goto err;
266   }
267   SILC_LOG_DEBUG(("Verification with hash successful"));
268   silc_hash_free(sha1);
269
270   silc_pkcs_free(pkcs);
271   success = TRUE;
272
273  err:
274   SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
275   fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");
276
277   return success;
278 }
279
280 int main(int argc, char **argv)
281 {
282   int success;
283   int i;
284
285   if (argc > 1 && !strcmp(argv[1], "-d")) {
286     silc_log_debug(TRUE);
287     silc_log_debug_hexdump(TRUE);
288     silc_log_set_debug_string("*crypt*,*pkcs*,*rsa*,*primegen*");
289   }
290   silc_hash_register_default();
291   silc_hmac_register_default();
292   silc_cipher_register_default();
293   silc_rng_global_init(NULL);
294
295   success = test();
296
297   for (i = 0; i < 100; i++) {
298     success = test();
299     if (!success)
300       break;
301   }
302
303   silc_pkcs_unregister_all();
304   silc_hash_unregister_all();
305   silc_hmac_unregister_all();
306   silc_cipher_unregister_all();
307
308   return success;
309 }