Fixed totlen calculation.
[silc.git] / lib / silccore / tests / test_silcmessage.c
1 /* SILC Message Payload tests */
2
3 #include "silc.h"
4 #include "silcapputil.h"
5
6 SilcPublicKey public_key, pk2;
7 SilcPrivateKey private_key;
8 SilcCipher key;
9 SilcHash hash;
10 SilcHmac hmac;
11 SilcRng rng;
12
13 int main(int argc, char **argv)
14 {
15   SilcBool success = FALSE;
16   SilcMessagePayload message;
17   SilcBuffer buf;
18   const char *msg = "FOOBAR MESSAGE";
19   unsigned char *data, tmp[1023];
20   SilcUInt32 data_len;
21   SilcUInt16 flags;
22   int i, n;
23   SilcMessageSignedPayload sig;
24
25   if (argc > 1 && !strcmp(argv[1], "-d")) {
26     silc_log_debug(TRUE);
27     silc_log_debug_hexdump(TRUE);
28     silc_log_set_debug_string("*message*");
29   }
30
31   silc_cipher_register_default();
32   silc_hash_register_default();
33   silc_hmac_register_default();
34   silc_pkcs_register_default();
35
36   SILC_LOG_DEBUG(("Load keypair"));
37   if (!silc_load_key_pair("pubkey.pub", "privkey.prv", "",
38                           &public_key, &private_key)) {
39     SILC_LOG_DEBUG(("Create keypair"));
40     if (!silc_create_key_pair("rsa", 2048, "pubkey.pub", "privkey.prv",
41                               NULL, "", &public_key, &private_key, FALSE))
42       goto err;
43   }
44
45   SILC_LOG_DEBUG(("Alloc RNG"));
46   rng = silc_rng_alloc();
47   silc_rng_init(rng);
48
49   SILC_LOG_DEBUG(("Alloc AES"));
50   if (!silc_cipher_alloc("aes-128-cbc", &key))
51     goto err;
52
53   SILC_LOG_DEBUG(("Alloc SHA-256"));
54   if (!silc_hash_alloc("sha256", &hash))
55     goto err;
56
57   SILC_LOG_DEBUG(("Alloc HMAC"));
58   if (!silc_hmac_alloc("hmac-sha256-96", hash, &hmac))
59     goto err;
60
61   SILC_LOG_DEBUG(("Set static key: '1234567890123456'"));
62   if (!silc_cipher_set_key(key, "1234567890123456", 16 * 8))
63     goto err;
64   SILC_LOG_DEBUG(("Set HMAC key: '1234567890123456'"));
65   silc_hmac_set_key(hmac, "1234567890123456", 16);
66
67   /* Simple private message */
68   SILC_LOG_DEBUG(("Encoding private message len %d (static key)",
69                   strlen(msg)));
70   buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
71                                     SILC_MESSAGE_FLAG_UTF8 |
72                                     SILC_MESSAGE_FLAG_ACK,
73                                     msg, strlen(msg), TRUE, TRUE,
74                                     key, hmac, rng, NULL, NULL, NULL, NULL);
75   if (!buf)
76     goto err;
77   SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
78   SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
79   message = silc_message_payload_parse(silc_buffer_data(buf),
80                                        silc_buffer_len(buf), TRUE, TRUE,
81                                        key, hmac);
82   if (!message)
83     goto err;
84   flags = silc_message_get_flags(message);
85   SILC_LOG_DEBUG(("Flags: %x", flags));
86   if (!(flags & SILC_MESSAGE_FLAG_ACTION))
87     goto err;
88   if (!(flags & SILC_MESSAGE_FLAG_UTF8))
89     goto err;
90   if (!(flags & SILC_MESSAGE_FLAG_ACK))
91     goto err;
92   data = silc_message_get_data(message, &data_len);
93   SILC_LOG_HEXDUMP(("Data"), data, data_len);
94   if (data_len != strlen(msg) || memcmp(data, msg, strlen(msg)))
95     goto err;
96   SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
97                    silc_hmac_len(hmac));
98   silc_message_payload_free(message);
99
100   /* Simple private message */
101   n = 10;
102   SILC_LOG_DEBUG(("Encoding private message len %d (static key)", n));
103   buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
104                                     SILC_MESSAGE_FLAG_UTF8 |
105                                     SILC_MESSAGE_FLAG_ACK,
106                                     msg, n, TRUE, TRUE,
107                                     key, hmac, rng, NULL, NULL, NULL, buf);
108   if (!buf)
109     goto err;
110   SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
111   SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
112   message = silc_message_payload_parse(silc_buffer_data(buf),
113                                        silc_buffer_len(buf), TRUE, TRUE,
114                                        key, hmac);
115   if (!message)
116     goto err;
117   flags = silc_message_get_flags(message);
118   SILC_LOG_DEBUG(("Flags: %x", flags));
119   if (!(flags & SILC_MESSAGE_FLAG_ACTION))
120     goto err;
121   if (!(flags & SILC_MESSAGE_FLAG_UTF8))
122     goto err;
123   if (!(flags & SILC_MESSAGE_FLAG_ACK))
124     goto err;
125   data = silc_message_get_data(message, &data_len);
126   SILC_LOG_HEXDUMP(("Data"), data, data_len);
127   if (data_len != n || memcmp(data, msg, n))
128     goto err;
129   SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
130                    silc_hmac_len(hmac));
131   silc_message_payload_free(message);
132
133   /* Simple private message */
134   n = 1;
135   SILC_LOG_DEBUG(("Encoding private message len %d (static key)", n));
136   buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
137                                     SILC_MESSAGE_FLAG_UTF8 |
138                                     SILC_MESSAGE_FLAG_ACK,
139                                     msg, n, TRUE, TRUE,
140                                     key, hmac, rng, NULL, NULL, NULL, buf);
141   if (!buf)
142     goto err;
143   SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
144   SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
145   message = silc_message_payload_parse(silc_buffer_data(buf),
146                                        silc_buffer_len(buf), TRUE, TRUE,
147                                        key, hmac);
148   if (!message)
149     goto err;
150   flags = silc_message_get_flags(message);
151   SILC_LOG_DEBUG(("Flags: %x", flags));
152   if (!(flags & SILC_MESSAGE_FLAG_ACTION))
153     goto err;
154   if (!(flags & SILC_MESSAGE_FLAG_UTF8))
155     goto err;
156   if (!(flags & SILC_MESSAGE_FLAG_ACK))
157     goto err;
158   data = silc_message_get_data(message, &data_len);
159   SILC_LOG_HEXDUMP(("Data"), data, data_len);
160   if (data_len != n || memcmp(data, msg, n))
161     goto err;
162   SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
163                    silc_hmac_len(hmac));
164   silc_message_payload_free(message);
165
166   /* Simple private message */
167   for (i = 0; i < sizeof(tmp); i++)
168     tmp[i] = (32 + i) & 127;
169   SILC_LOG_DEBUG(("Encoding private message len %d (static key)",
170                   sizeof(tmp)));
171   buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
172                                     SILC_MESSAGE_FLAG_UTF8 |
173                                     SILC_MESSAGE_FLAG_ACK,
174                                     tmp, sizeof(tmp), TRUE, TRUE,
175                                     key, hmac, rng, NULL, NULL, NULL, buf);
176   if (!buf)
177     goto err;
178   SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
179   SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
180   message = silc_message_payload_parse(silc_buffer_data(buf),
181                                        silc_buffer_len(buf), TRUE, TRUE,
182                                        key, hmac);
183   if (!message)
184     goto err;
185   flags = silc_message_get_flags(message);
186   SILC_LOG_DEBUG(("Flags: %x", flags));
187   if (!(flags & SILC_MESSAGE_FLAG_ACTION))
188     goto err;
189   if (!(flags & SILC_MESSAGE_FLAG_UTF8))
190     goto err;
191   if (!(flags & SILC_MESSAGE_FLAG_ACK))
192     goto err;
193   data = silc_message_get_data(message, &data_len);
194   SILC_LOG_HEXDUMP(("Data"), data, data_len);
195   if (data_len != sizeof(tmp) || memcmp(data, tmp, sizeof(tmp)))
196     goto err;
197   SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
198                    silc_hmac_len(hmac));
199   silc_message_payload_free(message);
200
201   /* Digitally signed private message */
202   for (i = 0; i < sizeof(tmp); i++)
203     tmp[i] = (32 + i) & 127;
204   SILC_LOG_DEBUG(("Encoding private message len %d (static key) SIGNED",
205                   sizeof(tmp)));
206   buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
207                                     SILC_MESSAGE_FLAG_UTF8 |
208                                     SILC_MESSAGE_FLAG_ACK |
209                                     SILC_MESSAGE_FLAG_SIGNED,
210                                     tmp, sizeof(tmp), TRUE, TRUE,
211                                     key, hmac, rng,
212                                     public_key, private_key, hash, buf);
213   if (!buf)
214     goto err;
215   SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
216   SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
217   message = silc_message_payload_parse(silc_buffer_data(buf),
218                                        silc_buffer_len(buf), TRUE, TRUE,
219                                        key, hmac);
220   if (!message)
221     goto err;
222   flags = silc_message_get_flags(message);
223   SILC_LOG_DEBUG(("Flags: %x", flags));
224   if (!(flags & SILC_MESSAGE_FLAG_ACTION))
225     goto err;
226   if (!(flags & SILC_MESSAGE_FLAG_UTF8))
227     goto err;
228   if (!(flags & SILC_MESSAGE_FLAG_ACK))
229     goto err;
230   if (!(flags & SILC_MESSAGE_FLAG_SIGNED))
231     goto err;
232   data = silc_message_get_data(message, &data_len);
233   SILC_LOG_HEXDUMP(("Data"), data, data_len);
234   if (data_len != sizeof(tmp) || memcmp(data, tmp, sizeof(tmp)))
235     goto err;
236   SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
237                    silc_hmac_len(hmac));
238   SILC_LOG_DEBUG(("Get signature"));
239   sig = silc_message_get_signature(message);
240   if (!sig)
241     goto err;
242   SILC_LOG_DEBUG(("Verifying signature"));
243   if (silc_message_signed_verify(sig, message, public_key, hash) !=
244       SILC_AUTH_OK)
245     goto err;
246   SILC_LOG_DEBUG(("Signature Ok"));
247   SILC_LOG_DEBUG(("Get public key"));
248   pk2 = silc_message_signed_get_public_key(sig, NULL, NULL);
249   if (!pk2)
250     goto err;
251   SILC_LOG_DEBUG(("Verify public key"));
252   if (!silc_pkcs_public_key_compare(public_key, pk2))
253     goto err;
254   SILC_LOG_DEBUG(("Public key Ok"));
255   silc_pkcs_public_key_free(pk2);
256   silc_message_payload_free(message);
257
258   /* Digitally signed channel message */
259   for (i = 0; i < sizeof(tmp) / 2; i++)
260     tmp[i] = (32 + i) & 127;
261   SILC_LOG_DEBUG(("Encoding channel message len %d (static key) SIGNED",
262                   sizeof(tmp) / 2));
263   buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
264                                     SILC_MESSAGE_FLAG_UTF8 |
265                                     SILC_MESSAGE_FLAG_ACK |
266                                     SILC_MESSAGE_FLAG_SIGNED,
267                                     tmp, sizeof(tmp) / 2, TRUE, FALSE,
268                                     key, hmac, rng,
269                                     public_key, private_key, hash, buf);
270   if (!buf)
271     goto err;
272   SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
273   SILC_LOG_DEBUG(("Parsing channel messsage (static key)"));
274   message = silc_message_payload_parse(silc_buffer_data(buf),
275                                        silc_buffer_len(buf), FALSE, TRUE,
276                                        key, hmac);
277   if (!message)
278     goto err;
279   flags = silc_message_get_flags(message);
280   SILC_LOG_DEBUG(("Flags: %x", flags));
281   if (!(flags & SILC_MESSAGE_FLAG_ACTION))
282     goto err;
283   if (!(flags & SILC_MESSAGE_FLAG_UTF8))
284     goto err;
285   if (!(flags & SILC_MESSAGE_FLAG_ACK))
286     goto err;
287   if (!(flags & SILC_MESSAGE_FLAG_SIGNED))
288     goto err;
289   data = silc_message_get_data(message, &data_len);
290   SILC_LOG_HEXDUMP(("Data"), data, data_len);
291   if (data_len != sizeof(tmp) / 2 || memcmp(data, tmp, sizeof(tmp) / 2))
292     goto err;
293   SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
294                    silc_hmac_len(hmac));
295   SILC_LOG_DEBUG(("Get signature"));
296   sig = silc_message_get_signature(message);
297   if (!sig)
298     goto err;
299   SILC_LOG_DEBUG(("Verifying signature"));
300   if (silc_message_signed_verify(sig, message, public_key, hash) !=
301       SILC_AUTH_OK)
302     goto err;
303   SILC_LOG_DEBUG(("Signature Ok"));
304   SILC_LOG_DEBUG(("Get public key"));
305   pk2 = silc_message_signed_get_public_key(sig, NULL, NULL);
306   if (!pk2)
307     goto err;
308   SILC_LOG_DEBUG(("Verify public key"));
309   if (!silc_pkcs_public_key_compare(public_key, pk2))
310     goto err;
311   SILC_LOG_DEBUG(("Public key Ok"));
312   silc_pkcs_public_key_free(pk2);
313   silc_message_payload_free(message);
314
315   /* Digitally signed private message (no encryption) */
316   for (i = 0; i < sizeof(tmp) / 2; i++)
317     tmp[i] = (32 + i) & 127;
318   SILC_LOG_DEBUG(("Encoding private message len %d SIGNED",
319                   sizeof(tmp) / 2));
320   buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
321                                     SILC_MESSAGE_FLAG_UTF8 |
322                                     SILC_MESSAGE_FLAG_ACK |
323                                     SILC_MESSAGE_FLAG_SIGNED,
324                                     tmp, sizeof(tmp) / 2, FALSE, TRUE,
325                                     NULL, NULL, rng,
326                                     public_key, private_key, hash, buf);
327   if (!buf)
328     goto err;
329   SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
330   SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
331   message = silc_message_payload_parse(silc_buffer_data(buf),
332                                        silc_buffer_len(buf), TRUE, FALSE,
333                                        NULL, NULL);
334   if (!message)
335     goto err;
336   flags = silc_message_get_flags(message);
337   SILC_LOG_DEBUG(("Flags: %x", flags));
338   if (!(flags & SILC_MESSAGE_FLAG_ACTION))
339     goto err;
340   if (!(flags & SILC_MESSAGE_FLAG_UTF8))
341     goto err;
342   if (!(flags & SILC_MESSAGE_FLAG_ACK))
343     goto err;
344   if (!(flags & SILC_MESSAGE_FLAG_SIGNED))
345     goto err;
346   data = silc_message_get_data(message, &data_len);
347   SILC_LOG_HEXDUMP(("Data"), data, data_len);
348   if (data_len != sizeof(tmp) / 2 || memcmp(data, tmp, sizeof(tmp) / 2))
349     goto err;
350   SILC_LOG_DEBUG(("Get signature"));
351   sig = silc_message_get_signature(message);
352   if (!sig)
353     goto err;
354   SILC_LOG_DEBUG(("Verifying signature"));
355   if (silc_message_signed_verify(sig, message, public_key, hash) !=
356       SILC_AUTH_OK)
357     goto err;
358   SILC_LOG_DEBUG(("Signature Ok"));
359   SILC_LOG_DEBUG(("Get public key"));
360   pk2 = silc_message_signed_get_public_key(sig, NULL, NULL);
361   if (!pk2)
362     goto err;
363   SILC_LOG_DEBUG(("Verify public key"));
364   if (!silc_pkcs_public_key_compare(public_key, pk2))
365     goto err;
366   SILC_LOG_DEBUG(("Public key Ok"));
367   silc_pkcs_public_key_free(pk2);
368   silc_message_payload_free(message);
369
370
371   success = TRUE;
372   SILC_LOG_DEBUG(("Cleanup"));
373   silc_pkcs_public_key_free(public_key);
374   silc_pkcs_private_key_free(private_key);
375   silc_cipher_free(key);
376   silc_hash_free(hash);
377   silc_rng_free(rng);
378
379  err:
380   silc_cipher_unregister_all();
381   silc_hash_unregister_all();
382   silc_hmac_unregister_all();
383   silc_pkcs_unregister_all();
384
385   SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
386   fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");
387
388   return success;
389 }