Added SILC Server library.
[silc.git] / lib / silcske / silcske.c
1 /*
2
3   silcske.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2000 - 2005 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19 /* $Id$ */
20
21 #include "silc.h"
22 #include "silcske.h"
23 #include "groups_internal.h"
24
25 /************************** Types and definitions ***************************/
26
27 /* Structure to hold all SKE callbacks. */
28 struct SilcSKECallbacksStruct {
29   SilcSKEVerifyCb verify_key;
30   SilcSKECompletionCb completed;
31   void *context;
32 };
33
34
35 /************************ Static utility functions **************************/
36
37 SilcSKEKeyMaterial
38 silc_ske_process_key_material_data(unsigned char *data,
39                                    SilcUInt32 data_len,
40                                    SilcUInt32 req_iv_len,
41                                    SilcUInt32 req_enc_key_len,
42                                    SilcUInt32 req_hmac_key_len,
43                                    SilcHash hash);
44 SilcSKEKeyMaterial
45 silc_ske_process_key_material(SilcSKE ske,
46                               SilcUInt32 req_iv_len,
47                               SilcUInt32 req_enc_key_len,
48                               SilcUInt32 req_hmac_key_len);
49
50
51 /* Packet callback */
52
53 static SilcBool silc_ske_packet_receive(SilcPacketEngine engine,
54                                         SilcPacketStream stream,
55                                         SilcPacket packet,
56                                         void *callback_context,
57                                         void *app_context)
58 {
59   SilcSKE ske = callback_context;
60   ske->packet = packet;
61   silc_fsm_continue(&ske->fsm);
62   return TRUE;
63 }
64
65 /* Packet stream callbacks */
66 static SilcPacketCallbacks silc_ske_stream_cbs =
67 {
68   silc_ske_packet_receive, NULL, NULL
69 };
70
71 /* Aborts SKE protocol */
72
73 static void silc_ske_abort(SilcAsyncOperation op, void *context)
74 {
75   SilcSKE ske = context;
76   ske->aborted = TRUE;
77 }
78
79 /* Public key verification completion callback */
80
81 static void silc_ske_pk_verified(SilcSKE ske, SilcSKEStatus status,
82                                  void *completion_context)
83 {
84   ske->status = status;
85   SILC_FSM_CALL_CONTINUE(&ske->fsm);
86 }
87
88 /* Checks remote and local versions */
89
90 static SilcSKEStatus silc_ske_check_version(SilcSKE ske)
91 {
92   SilcUInt32 l_protocol_version = 0, r_protocol_version = 0;
93
94   if (!ske->remote_version || !ske->version)
95     return SILC_SKE_STATUS_BAD_VERSION;
96
97   if (!silc_parse_version_string(ske->remote_version, &r_protocol_version,
98                                  NULL, NULL, NULL, NULL))
99     return SILC_SKE_STATUS_BAD_VERSION;
100
101   if (!silc_parse_version_string(ske->version, &l_protocol_version,
102                                  NULL, NULL, NULL, NULL))
103     return SILC_SKE_STATUS_BAD_VERSION;
104
105   /* If remote is too new, don't connect */
106   if (l_protocol_version < r_protocol_version)
107     return SILC_SKE_STATUS_BAD_VERSION;
108
109   return SILC_SKE_STATUS_OK;
110 }
111
112 /* Selects the supported security properties from the initiator's Key
113    Exchange Start Payload. */
114
115 static SilcSKEStatus
116 silc_ske_select_security_properties(SilcSKE ske,
117                                     SilcSKEStartPayload payload,
118                                     SilcSKEStartPayload remote_payload)
119 {
120   SilcSKEStatus status;
121   SilcSKEStartPayload rp;
122   char *cp;
123   int len;
124
125   SILC_LOG_DEBUG(("Parsing KE Start Payload"));
126
127   rp = remote_payload;
128
129   /* Check version string */
130   ske->remote_version = silc_memdup(rp->version, rp->version_len);
131   status = silc_ske_check_version(ske);
132   if (status != SILC_SKE_STATUS_OK) {
133     ske->status = status;
134     return status;
135   }
136
137   /* Flags are returned unchanged. */
138   payload->flags = rp->flags;
139
140   /* Take cookie, we must return it to sender unmodified. */
141   payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
142   if (!payload->cookie) {
143     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
144     return status;
145   }
146   payload->cookie_len = SILC_SKE_COOKIE_LEN;
147   memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
148
149   /* Put our version to our reply */
150   payload->version = strdup(ske->version);
151   if (!payload->version) {
152     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
153     return status;
154   }
155   payload->version_len = strlen(ske->version);
156
157   /* Get supported Key Exchange groups */
158   cp = rp->ke_grp_list;
159   if (cp && strchr(cp, ',')) {
160     while(cp) {
161       char *item;
162
163       len = strcspn(cp, ",");
164       item = silc_calloc(len + 1, sizeof(char));
165       if (!item) {
166         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
167         return status;
168       }
169       memcpy(item, cp, len);
170
171       SILC_LOG_DEBUG(("Proposed KE group `%s'", item));
172
173       if (silc_ske_group_get_by_name(item, NULL) == SILC_SKE_STATUS_OK) {
174         SILC_LOG_DEBUG(("Found KE group `%s'", item));
175
176         payload->ke_grp_len = len;
177         payload->ke_grp_list = item;
178         break;
179       }
180
181       cp += len;
182       if (strlen(cp) == 0)
183         cp = NULL;
184       else
185         cp++;
186
187       if (item)
188         silc_free(item);
189     }
190
191     if (!payload->ke_grp_len && !payload->ke_grp_list) {
192       SILC_LOG_DEBUG(("Could not find supported KE group"));
193       silc_free(payload);
194       return SILC_SKE_STATUS_UNKNOWN_GROUP;
195     }
196   } else {
197
198     if (!rp->ke_grp_len) {
199       SILC_LOG_DEBUG(("KE group not defined in payload"));
200       silc_free(payload);
201       return SILC_SKE_STATUS_BAD_PAYLOAD;
202     }
203
204     SILC_LOG_DEBUG(("Proposed KE group `%s'", rp->ke_grp_list));
205     SILC_LOG_DEBUG(("Found KE group `%s'", rp->ke_grp_list));
206
207     payload->ke_grp_len = rp->ke_grp_len;
208     payload->ke_grp_list = strdup(rp->ke_grp_list);
209   }
210
211   /* Get supported PKCS algorithms */
212   cp = rp->pkcs_alg_list;
213   if (cp && strchr(cp, ',')) {
214     while(cp) {
215       char *item;
216
217       len = strcspn(cp, ",");
218       item = silc_calloc(len + 1, sizeof(char));
219       if (!item) {
220         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
221         return status;
222       }
223       memcpy(item, cp, len);
224
225       SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", item));
226
227       if (silc_pkcs_is_supported(item) == TRUE) {
228         SILC_LOG_DEBUG(("Found PKCS alg `%s'", item));
229
230         payload->pkcs_alg_len = len;
231         payload->pkcs_alg_list = item;
232         break;
233       }
234
235       cp += len;
236       if (strlen(cp) == 0)
237         cp = NULL;
238       else
239         cp++;
240
241       if (item)
242         silc_free(item);
243     }
244
245     if (!payload->pkcs_alg_len && !payload->pkcs_alg_list) {
246       SILC_LOG_DEBUG(("Could not find supported PKCS alg"));
247       silc_free(payload->ke_grp_list);
248       silc_free(payload);
249       return SILC_SKE_STATUS_UNKNOWN_PKCS;
250     }
251   } else {
252
253     if (!rp->pkcs_alg_len) {
254       SILC_LOG_DEBUG(("PKCS alg not defined in payload"));
255       silc_free(payload->ke_grp_list);
256       silc_free(payload);
257       return SILC_SKE_STATUS_BAD_PAYLOAD;
258     }
259
260     SILC_LOG_DEBUG(("Proposed PKCS alg `%s'", rp->pkcs_alg_list));
261     SILC_LOG_DEBUG(("Found PKCS alg `%s'", rp->pkcs_alg_list));
262
263     payload->pkcs_alg_len = rp->pkcs_alg_len;
264     payload->pkcs_alg_list = strdup(rp->pkcs_alg_list);
265   }
266
267   /* Get supported encryption algorithms */
268   cp = rp->enc_alg_list;
269   if (cp && strchr(cp, ',')) {
270     while(cp) {
271       char *item;
272
273       len = strcspn(cp, ",");
274       item = silc_calloc(len + 1, sizeof(char));
275       if (!item) {
276         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
277         return status;
278       }
279       memcpy(item, cp, len);
280
281       SILC_LOG_DEBUG(("Proposed encryption alg `%s'", item));
282
283       if (silc_cipher_is_supported(item) == TRUE) {
284         SILC_LOG_DEBUG(("Found encryption alg `%s'", item));
285
286         payload->enc_alg_len = len;
287         payload->enc_alg_list = item;
288         break;
289       }
290
291       cp += len;
292       if (strlen(cp) == 0)
293         cp = NULL;
294       else
295         cp++;
296
297       if (item)
298         silc_free(item);
299     }
300
301     if (!payload->enc_alg_len && !payload->enc_alg_list) {
302       SILC_LOG_DEBUG(("Could not find supported encryption alg"));
303       silc_free(payload->ke_grp_list);
304       silc_free(payload->pkcs_alg_list);
305       silc_free(payload);
306       return SILC_SKE_STATUS_UNKNOWN_CIPHER;
307     }
308   } else {
309
310     if (!rp->enc_alg_len) {
311       SILC_LOG_DEBUG(("Encryption alg not defined in payload"));
312       silc_free(payload->ke_grp_list);
313       silc_free(payload->pkcs_alg_list);
314       silc_free(payload);
315       return SILC_SKE_STATUS_BAD_PAYLOAD;
316     }
317
318     SILC_LOG_DEBUG(("Proposed encryption alg `%s' and selected it",
319                     rp->enc_alg_list));
320
321     payload->enc_alg_len = rp->enc_alg_len;
322     payload->enc_alg_list = strdup(rp->enc_alg_list);
323   }
324
325   /* Get supported hash algorithms */
326   cp = rp->hash_alg_list;
327   if (cp && strchr(cp, ',')) {
328     while(cp) {
329       char *item;
330
331       len = strcspn(cp, ",");
332       item = silc_calloc(len + 1, sizeof(char));
333       if (!item) {
334         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
335         return status;
336       }
337       memcpy(item, cp, len);
338
339       SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
340
341       if (silc_hash_is_supported(item) == TRUE) {
342         SILC_LOG_DEBUG(("Found hash alg `%s'", item));
343
344         payload->hash_alg_len = len;
345         payload->hash_alg_list = item;
346         break;
347       }
348
349       cp += len;
350       if (strlen(cp) == 0)
351         cp = NULL;
352       else
353         cp++;
354
355       if (item)
356         silc_free(item);
357     }
358
359     if (!payload->hash_alg_len && !payload->hash_alg_list) {
360       SILC_LOG_DEBUG(("Could not find supported hash alg"));
361       silc_free(payload->ke_grp_list);
362       silc_free(payload->pkcs_alg_list);
363       silc_free(payload->enc_alg_list);
364       silc_free(payload);
365       return SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
366     }
367   } else {
368
369     if (!rp->hash_alg_len) {
370       SILC_LOG_DEBUG(("Hash alg not defined in payload"));
371       silc_free(payload->ke_grp_list);
372       silc_free(payload->pkcs_alg_list);
373       silc_free(payload->enc_alg_list);
374       silc_free(payload);
375       return SILC_SKE_STATUS_BAD_PAYLOAD;
376     }
377
378     SILC_LOG_DEBUG(("Proposed hash alg `%s' and selected it",
379                     rp->hash_alg_list));
380
381     payload->hash_alg_len = rp->hash_alg_len;
382     payload->hash_alg_list = strdup(rp->hash_alg_list);
383   }
384
385   /* Get supported HMACs */
386   cp = rp->hmac_alg_list;
387   if (cp && strchr(cp, ',')) {
388     while(cp) {
389       char *item;
390
391       len = strcspn(cp, ",");
392       item = silc_calloc(len + 1, sizeof(char));
393       if (!item) {
394         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
395         return status;
396       }
397       memcpy(item, cp, len);
398
399       SILC_LOG_DEBUG(("Proposed HMAC `%s'", item));
400
401       if (silc_hmac_is_supported(item) == TRUE) {
402         SILC_LOG_DEBUG(("Found HMAC `%s'", item));
403
404         payload->hmac_alg_len = len;
405         payload->hmac_alg_list = item;
406         break;
407       }
408
409       cp += len;
410       if (strlen(cp) == 0)
411         cp = NULL;
412       else
413         cp++;
414
415       if (item)
416         silc_free(item);
417     }
418
419     if (!payload->hmac_alg_len && !payload->hmac_alg_list) {
420       SILC_LOG_DEBUG(("Could not find supported HMAC"));
421       silc_free(payload->ke_grp_list);
422       silc_free(payload->pkcs_alg_list);
423       silc_free(payload->enc_alg_list);
424       silc_free(payload->hash_alg_list);
425       silc_free(payload);
426       return SILC_SKE_STATUS_UNKNOWN_HMAC;
427     }
428   } else {
429
430     if (!rp->hmac_alg_len) {
431       SILC_LOG_DEBUG(("HMAC not defined in payload"));
432       silc_free(payload->ke_grp_list);
433       silc_free(payload->pkcs_alg_list);
434       silc_free(payload->enc_alg_list);
435       silc_free(payload->hash_alg_list);
436       silc_free(payload);
437       return SILC_SKE_STATUS_BAD_PAYLOAD;
438     }
439
440     SILC_LOG_DEBUG(("Proposed HMAC `%s' and selected it",
441                     rp->hmac_alg_list));
442
443     payload->hmac_alg_len = rp->hmac_alg_len;
444     payload->hmac_alg_list = strdup(rp->hmac_alg_list);
445   }
446
447   /* Get supported compression algorithms */
448   cp = rp->comp_alg_list;
449   if (cp && strchr(cp, ',')) {
450     while(cp) {
451       char *item;
452
453       len = strcspn(cp, ",");
454       item = silc_calloc(len + 1, sizeof(char));
455       if (!item) {
456         ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
457         return status;
458       }
459       memcpy(item, cp, len);
460
461       SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
462
463 #if 1
464       if (!strcmp(item, "none")) {
465         SILC_LOG_DEBUG(("Found Compression `%s'", item));
466         payload->comp_alg_len = len;
467         payload->comp_alg_list = item;
468         break;
469       }
470 #else
471       if (silc_hmac_is_supported(item) == TRUE) {
472         SILC_LOG_DEBUG(("Found Compression `%s'", item));
473         payload->comp_alg_len = len;
474         payload->comp_alg_list = item;
475         break;
476       }
477 #endif
478
479       cp += len;
480       if (strlen(cp) == 0)
481         cp = NULL;
482       else
483         cp++;
484
485       if (item)
486         silc_free(item);
487     }
488   }
489
490   payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
491     2 + payload->version_len +
492     2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len +
493     2 + payload->enc_alg_len + 2 + payload->hash_alg_len +
494     2 + payload->hmac_alg_len + 2 + payload->comp_alg_len;
495
496   return SILC_SKE_STATUS_OK;
497 }
498
499 /* Creates random number such that 1 < rnd < n and at most length
500    of len bits. The rnd sent as argument must be initialized. */
501
502 static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
503                                          SilcUInt32 len,
504                                          SilcMPInt *rnd)
505 {
506   SilcSKEStatus status = SILC_SKE_STATUS_OK;
507   unsigned char *string;
508   SilcUInt32 l;
509
510   if (!len)
511     return SILC_SKE_STATUS_ERROR;
512
513   SILC_LOG_DEBUG(("Creating random number"));
514
515   l = ((len - 1) / 8);
516
517   /* Get the random number as string */
518   string = silc_rng_get_rn_data(ske->rng, l);
519   if (!string)
520     return SILC_SKE_STATUS_OUT_OF_MEMORY;
521
522   /* Decode the string into a MP integer */
523   silc_mp_bin2mp(string, l, rnd);
524   silc_mp_mod_2exp(rnd, rnd, len);
525
526   /* Checks */
527   if (silc_mp_cmp_ui(rnd, 1) < 0)
528     status = SILC_SKE_STATUS_ERROR;
529   if (silc_mp_cmp(rnd, n) >= 0)
530     status = SILC_SKE_STATUS_ERROR;
531
532   memset(string, 'F', l);
533   silc_free(string);
534
535   return status;
536 }
537
538 /* Creates a hash value HASH as defined in the SKE protocol. If the
539    `initiator' is TRUE then this function is used to create the HASH_i
540    hash value defined in the protocol. If it is FALSE then this is used
541    to create the HASH value defined by the protocol. */
542
543 static SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
544                                         unsigned char *return_hash,
545                                         SilcUInt32 *return_hash_len,
546                                         int initiator)
547 {
548   SilcSKEStatus status = SILC_SKE_STATUS_OK;
549   SilcBuffer buf;
550   unsigned char *e, *f, *KEY;
551   SilcUInt32 e_len, f_len, KEY_len;
552   int ret;
553
554   SILC_LOG_DEBUG(("Start"));
555
556   if (initiator == FALSE) {
557     e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
558     f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
559     KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
560
561     /* Format the buffer used to compute the hash value */
562     buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
563                                  ske->ke2_payload->pk_len +
564                                  ske->ke1_payload->pk_len +
565                                  e_len + f_len + KEY_len);
566     if (!buf)
567       return SILC_SKE_STATUS_OUT_OF_MEMORY;
568
569     /* Initiator is not required to send its public key */
570     if (!ske->ke1_payload->pk_data) {
571       ret =
572         silc_buffer_format(buf,
573                            SILC_STR_UI_XNSTRING(
574                                    ske->start_payload_copy->data,
575                                    silc_buffer_len(ske->start_payload_copy)),
576                            SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
577                                                 ske->ke2_payload->pk_len),
578                            SILC_STR_UI_XNSTRING(e, e_len),
579                            SILC_STR_UI_XNSTRING(f, f_len),
580                            SILC_STR_UI_XNSTRING(KEY, KEY_len),
581                            SILC_STR_END);
582     } else {
583       ret =
584         silc_buffer_format(buf,
585                            SILC_STR_UI_XNSTRING(
586                                    ske->start_payload_copy->data,
587                                    silc_buffer_len(ske->start_payload_copy)),
588                            SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data,
589                                                 ske->ke2_payload->pk_len),
590                            SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
591                                                 ske->ke1_payload->pk_len),
592                            SILC_STR_UI_XNSTRING(e, e_len),
593                            SILC_STR_UI_XNSTRING(f, f_len),
594                            SILC_STR_UI_XNSTRING(KEY, KEY_len),
595                            SILC_STR_END);
596     }
597     if (ret == -1) {
598       silc_buffer_free(buf);
599       memset(e, 0, e_len);
600       memset(f, 0, f_len);
601       memset(KEY, 0, KEY_len);
602       silc_free(e);
603       silc_free(f);
604       silc_free(KEY);
605       return SILC_SKE_STATUS_ERROR;
606     }
607
608     memset(e, 0, e_len);
609     memset(f, 0, f_len);
610     memset(KEY, 0, KEY_len);
611     silc_free(e);
612     silc_free(f);
613     silc_free(KEY);
614   } else {
615     e = silc_mp_mp2bin(&ske->ke1_payload->x, 0, &e_len);
616
617     buf = silc_buffer_alloc_size(silc_buffer_len(ske->start_payload_copy) +
618                                  ske->ke1_payload->pk_len + e_len);
619     if (!buf)
620       return SILC_SKE_STATUS_OUT_OF_MEMORY;
621
622     /* Format the buffer used to compute the hash value */
623     ret =
624       silc_buffer_format(buf,
625                          SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
626                                      silc_buffer_len(ske->start_payload_copy)),
627                          SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data,
628                                               ske->ke1_payload->pk_len),
629                          SILC_STR_UI_XNSTRING(e, e_len),
630                          SILC_STR_END);
631     if (ret == -1) {
632       silc_buffer_free(buf);
633       memset(e, 0, e_len);
634       silc_free(e);
635       return SILC_SKE_STATUS_ERROR;
636     }
637
638     memset(e, 0, e_len);
639     silc_free(e);
640   }
641
642   /* Make the hash */
643   silc_hash_make(ske->prop->hash, buf->data, silc_buffer_len(buf),
644                  return_hash);
645   *return_hash_len = silc_hash_len(ske->prop->hash);
646
647   if (initiator == FALSE) {
648     SILC_LOG_HEXDUMP(("HASH"), return_hash, *return_hash_len);
649   } else {
650     SILC_LOG_HEXDUMP(("HASH_i"), return_hash, *return_hash_len);
651   }
652
653   silc_buffer_free(buf);
654
655   return status;
656 }
657
658
659 /******************************* Protocol API *******************************/
660
661 /* Allocates new SKE object. */
662
663 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
664                        SilcPublicKey public_key, SilcPrivateKey private_key,
665                        void *context)
666 {
667   SilcSKE ske;
668
669   SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
670
671   if (!rng || !schedule)
672     return NULL;
673
674   ske = silc_calloc(1, sizeof(*ske));
675   if (!ske)
676     return NULL;
677   ske->status = SILC_SKE_STATUS_OK;
678   ske->rng = rng;
679   ske->user_data = context;
680   ske->schedule = schedule;
681   ske->public_key = public_key;
682   ske->private_key = private_key;
683   ske->pk_type = SILC_SKE_PK_TYPE_SILC;
684
685   return ske;
686 }
687
688 /* Free's SKE object. */
689
690 void silc_ske_free(SilcSKE ske)
691 {
692   SILC_LOG_DEBUG(("Freeing Key Exchange object"));
693
694   if (ske) {
695     /* Free start payload */
696     if (ske->start_payload)
697       silc_ske_payload_start_free(ske->start_payload);
698
699     /* Free KE payload */
700     if (ske->ke1_payload)
701       silc_ske_payload_ke_free(ske->ke1_payload);
702     if (ske->ke2_payload)
703       silc_ske_payload_ke_free(ske->ke2_payload);
704     silc_free(ske->remote_version);
705
706     /* Free rest */
707     if (ske->prop) {
708       if (ske->prop->group)
709         silc_ske_group_free(ske->prop->group);
710       if (ske->prop->pkcs)
711         silc_pkcs_free(ske->prop->pkcs);
712       if (ske->prop->cipher)
713         silc_cipher_free(ske->prop->cipher);
714       if (ske->prop->hash)
715         silc_hash_free(ske->prop->hash);
716       if (ske->prop->hmac)
717         silc_hmac_free(ske->prop->hmac);
718       silc_free(ske->prop);
719     }
720     if (ske->start_payload_copy)
721       silc_buffer_free(ske->start_payload_copy);
722     if (ske->x) {
723       silc_mp_uninit(ske->x);
724       silc_free(ske->x);
725     }
726     if (ske->KEY) {
727       silc_mp_uninit(ske->KEY);
728       silc_free(ske->KEY);
729     }
730     silc_free(ske->hash);
731     silc_free(ske->callbacks);
732
733     memset(ske, 'F', sizeof(*ske));
734     silc_free(ske);
735   }
736 }
737
738 /* Return user context */
739
740 void *silc_ske_get_context(SilcSKE ske)
741 {
742   return ske->user_data;
743 }
744
745 /* Sets protocol callbacks */
746
747 void silc_ske_set_callbacks(SilcSKE ske,
748                             SilcSKEVerifyCb verify_key,
749                             SilcSKECompletionCb completed,
750                             void *context)
751 {
752   if (ske->callbacks)
753     silc_free(ske->callbacks);
754   ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
755   if (!ske->callbacks)
756     return;
757   ske->callbacks->verify_key = verify_key;
758   ske->callbacks->completed = completed;
759   ske->callbacks->context = context;
760 }
761
762
763 /******************************** Initiator *********************************/
764
765 /* Initiator state machine */
766 SILC_FSM_STATE(silc_ske_st_initiator_start);
767 SILC_FSM_STATE(silc_ske_st_initiator_phase1);
768 SILC_FSM_STATE(silc_ske_st_initiator_phase2);
769 SILC_FSM_STATE(silc_ske_st_initiator_phase3);
770 SILC_FSM_STATE(silc_ske_st_initiator_phase4);
771 SILC_FSM_STATE(silc_ske_st_initiator_end);
772 SILC_FSM_STATE(silc_ske_st_initiator_aborted);
773 SILC_FSM_STATE(silc_ske_st_initiator_error);
774
775 /* Start protocol.  Send our proposal */
776
777 SILC_FSM_STATE(silc_ske_st_initiator_start)
778 {
779   SilcSKE ske = fsm_context;
780   SilcBuffer payload_buf;
781   SilcStatus status;
782
783   SILC_LOG_DEBUG(("Start"));
784
785   if (ske->aborted) {
786     /** Aborted */
787     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
788     return SILC_FSM_CONTINUE;
789   }
790
791   /* Encode the payload */
792   status = silc_ske_payload_start_encode(ske, ske->start_payload,
793                                          &payload_buf);
794   if (status != SILC_SKE_STATUS_OK) {
795     /** Error encoding Start Payload */
796     ske->status = status;
797     silc_fsm_next(fsm, silc_ske_st_initiator_error);
798     return SILC_FSM_CONTINUE;
799   }
800
801   /* Save the the payload buffer for future use. It is later used to
802      compute the HASH value. */
803   ske->start_payload_copy = payload_buf;
804
805   /* Send the packet */
806   /* XXX */
807
808   /** Wait for responder proposal */
809   SILC_LOG_DEBUG(("Waiting for reponder proposal"));
810   silc_fsm_next(ske, silc_ske_st_initiator_phase1);
811   return SILC_FSM_WAIT;
812 }
813
814 /* Phase-1.  Receives responder's proposal */
815
816 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
817 {
818   SilcSKE ske = fsm_context;
819   SilcSKEStatus status;
820   SilcSKEStartPayload payload;
821   SilcSKESecurityProperties prop;
822   SilcSKEDiffieHellmanGroup group;
823   SilcBuffer packet_buf = &ske->packet->buffer;
824
825   SILC_LOG_DEBUG(("Start"));
826
827   if (ske->aborted) {
828     /** Aborted */
829     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
830     return SILC_FSM_CONTINUE;
831   }
832
833   /* Decode the payload */
834   status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
835   if (status != SILC_SKE_STATUS_OK) {
836     /** Error decoding Start Payload */
837     ske->status = status;
838     silc_fsm_next(fsm, silc_ske_st_initiator_error);
839     return SILC_FSM_CONTINUE;
840   }
841
842   /* Check that the cookie is returned unmodified */
843   if (memcmp(ske->start_payload->cookie, payload->cookie,
844              ske->start_payload->cookie_len)) {
845     /** Invalid cookie */
846     SILC_LOG_ERROR(("Responder modified our cookie and it must not do it"));
847     ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
848     silc_fsm_next(fsm, silc_ske_st_initiator_error);
849     return SILC_FSM_CONTINUE;
850   }
851
852   /* Check version string */
853   ske->remote_version = silc_memdup(payload->version, payload->version_len);
854   status = silc_ske_check_version(ske);
855   if (status != SILC_SKE_STATUS_OK) {
856     /** Version mismatch */
857     ske->status = status;
858     silc_fsm_next(fsm, silc_ske_st_initiator_error);
859     return SILC_FSM_CONTINUE;
860   }
861
862   /* Free our KE Start Payload context, we don't need it anymore. */
863   silc_ske_payload_start_free(ske->start_payload);
864   ske->start_payload = NULL;
865
866   /* Take the selected security properties into use while doing
867      the key exchange.  This is used only while doing the key
868      exchange. */
869   ske->prop = prop = silc_calloc(1, sizeof(*prop));
870   if (!ske->prop)
871     goto err;
872   prop->flags = payload->flags;
873   status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
874   if (status != SILC_SKE_STATUS_OK)
875     goto err;
876
877   prop->group = group;
878
879   if (silc_pkcs_alloc(payload->pkcs_alg_list, ske->pk_type,
880                       &prop->pkcs) == FALSE) {
881     status = SILC_SKE_STATUS_UNKNOWN_PKCS;
882     goto err;
883   }
884   if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
885     status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
886     goto err;
887   }
888   if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
889     status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
890     goto err;
891   }
892   if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
893     status = SILC_SKE_STATUS_UNKNOWN_HMAC;
894     goto err;
895   }
896
897   /* Save remote's KE Start Payload */
898   ske->start_payload = payload;
899
900   /** Send KE Payload */
901   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
902   return SILC_FSM_CONTINUE;
903
904  err:
905   if (payload)
906     silc_ske_payload_start_free(payload);
907
908   silc_ske_group_free(group);
909
910   if (prop->pkcs)
911     silc_pkcs_free(prop->pkcs);
912   if (prop->cipher)
913     silc_cipher_free(prop->cipher);
914   if (prop->hash)
915     silc_hash_free(prop->hash);
916   if (prop->hmac)
917     silc_hmac_free(prop->hmac);
918   silc_free(prop);
919   ske->prop = NULL;
920
921   if (status == SILC_SKE_STATUS_OK)
922     status = SILC_SKE_STATUS_ERROR;
923
924   /** Error */
925   ske->status = status;
926   silc_fsm_next(fsm, silc_ske_st_initiator_error);
927   return SILC_FSM_CONTINUE;
928 }
929
930 /* Phase-2.  Send KE payload */
931
932 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
933 {
934   SilcSKE ske = fsm_context;
935   SilcSKEStatus status;
936   SilcBuffer payload_buf;
937   SilcMPInt *x;
938   SilcSKEKEPayload payload;
939   SilcUInt32 pk_len;
940
941   SILC_LOG_DEBUG(("Start"));
942
943   /* Create the random number x, 1 < x < q. */
944   x = silc_calloc(1, sizeof(*x));
945   if (!x){
946     /** Out of memory */
947     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
948     silc_fsm_next(fsm, silc_ske_st_initiator_error);
949     return SILC_FSM_CONTINUE;
950   }
951   silc_mp_init(x);
952   status =
953     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
954                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
955                         x);
956   if (status != SILC_SKE_STATUS_OK) {
957     /** Error generating random number */
958     silc_mp_uninit(x);
959     silc_free(x);
960     ske->status = status;
961     silc_fsm_next(fsm, silc_ske_st_initiator_error);
962     return SILC_FSM_CONTINUE;
963   }
964
965   /* Encode the result to Key Exchange Payload. */
966
967   payload = silc_calloc(1, sizeof(*payload));
968   if (!payload) {
969     /** Out of memory */
970     silc_mp_uninit(x);
971     silc_free(x);
972     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
973     silc_fsm_next(fsm, silc_ske_st_initiator_error);
974     return SILC_FSM_CONTINUE;
975   }
976   ske->ke1_payload = payload;
977
978   SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
979
980   /* Do the Diffie Hellman computation, e = g ^ x mod p */
981   silc_mp_init(&payload->x);
982   silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
983                   &ske->prop->group->group);
984
985   /* Get public key */
986   if (ske->public_key) {
987     payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
988     if (!payload->pk_data) {
989       /** Error encoding public key */
990       silc_mp_uninit(x);
991       silc_free(x);
992       silc_mp_uninit(&payload->x);
993       silc_free(payload);
994       ske->ke1_payload = NULL;
995       ske->status = SILC_SKE_STATUS_ERROR;
996       silc_fsm_next(fsm, silc_ske_st_initiator_error);
997       return SILC_FSM_CONTINUE;
998     }
999     payload->pk_len = pk_len;
1000   }
1001   payload->pk_type = ske->pk_type;
1002
1003   /* Compute signature data if we are doing mutual authentication */
1004   if (ske->private_key &&
1005       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1006     unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1007     SilcUInt32 hash_len, sign_len;
1008
1009     SILC_LOG_DEBUG(("We are doing mutual authentication"));
1010     SILC_LOG_DEBUG(("Computing HASH_i value"));
1011
1012     /* Compute the hash value */
1013     memset(hash, 0, sizeof(hash));
1014     silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1015
1016     SILC_LOG_DEBUG(("Signing HASH_i value"));
1017
1018     /* Sign the hash value */
1019     silc_pkcs_private_key_data_set(ske->prop->pkcs, ske->private_key->prv,
1020                                    ske->private_key->prv_len);
1021     if (silc_pkcs_get_key_len(ske->prop->pkcs) / 8 > sizeof(sign) - 1 ||
1022         !silc_pkcs_sign(ske->prop->pkcs, hash, hash_len, sign, &sign_len)) {
1023       /** Error computing signature */
1024       silc_mp_uninit(x);
1025       silc_free(x);
1026       silc_mp_uninit(&payload->x);
1027       silc_free(payload->pk_data);
1028       silc_free(payload);
1029       ske->ke1_payload = NULL;
1030       ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1031       silc_fsm_next(fsm, silc_ske_st_initiator_error);
1032       return SILC_FSM_CONTINUE;
1033     }
1034     payload->sign_data = silc_memdup(sign, sign_len);
1035     payload->sign_len = sign_len;
1036     memset(sign, 0, sizeof(sign));
1037   }
1038
1039   status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1040   if (status != SILC_SKE_STATUS_OK) {
1041     /** Error encoding KE payload */
1042     silc_mp_uninit(x);
1043     silc_free(x);
1044     silc_mp_uninit(&payload->x);
1045     silc_free(payload->pk_data);
1046     silc_free(payload->sign_data);
1047     silc_free(payload);
1048     ske->ke1_payload = NULL;
1049     ske->status = status;
1050     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1051     return SILC_FSM_CONTINUE;
1052   }
1053
1054   ske->x = x;
1055
1056   /* Send the packet. */
1057   /* XXX */
1058
1059   silc_buffer_free(payload_buf);
1060
1061   /** Waiting responder's KE payload */
1062   silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1063   return SILC_FSM_WAIT;
1064 }
1065
1066 /* Phase-3.  Process responder's KE payload */
1067
1068 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1069 {
1070   SilcSKE ske = fsm_context;
1071   SilcSKEStatus status;
1072   SilcSKEKEPayload payload;
1073   SilcMPInt *KEY;
1074   SilcBuffer packet_buf = &ske->packet->buffer;
1075
1076   SILC_LOG_DEBUG(("Start"));
1077
1078   if (ske->aborted) {
1079     /** Aborted */
1080     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1081     return SILC_FSM_CONTINUE;
1082   }
1083
1084   /* Decode the payload */
1085   status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1086   if (status != SILC_SKE_STATUS_OK) {
1087     /** Error decoding KE payload */
1088     ske->status = status;
1089     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1090     return SILC_FSM_CONTINUE;
1091   }
1092   ske->ke2_payload = payload;
1093
1094   if (!payload->pk_data && ske->callbacks->verify_key) {
1095     SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1096                     "even though we require it"));
1097     ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1098     goto err;
1099   }
1100
1101   SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1102
1103   /* Compute the shared secret key */
1104   KEY = silc_calloc(1, sizeof(*KEY));
1105   silc_mp_init(KEY);
1106   silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1107   ske->KEY = KEY;
1108
1109   if (payload->pk_data && ske->callbacks->verify_key) {
1110     SILC_LOG_DEBUG(("Verifying public key"));
1111
1112     /** Waiting public key verification */
1113     silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1114     SILC_FSM_CALL(ske->callbacks->verify_key(ske, payload->pk_data,
1115                                              payload->pk_len,
1116                                              payload->pk_type,
1117                                              ske->callbacks->context,
1118                                              silc_ske_pk_verified, NULL));
1119     /* NOT REACHED */
1120   }
1121
1122   /** Process key material */
1123   silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1124   return SILC_FSM_CONTINUE;
1125
1126  err:
1127   silc_ske_payload_ke_free(payload);
1128   ske->ke2_payload = NULL;
1129
1130   silc_mp_uninit(ske->KEY);
1131   silc_free(ske->KEY);
1132   ske->KEY = NULL;
1133
1134   if (status == SILC_SKE_STATUS_OK)
1135     return SILC_SKE_STATUS_ERROR;
1136
1137   /** Error */
1138   ske->status = status;
1139   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1140   return SILC_FSM_CONTINUE;
1141 }
1142
1143 /* Process key material */
1144
1145 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1146 {
1147   SilcSKE ske = fsm_context;
1148   SilcSKEStatus status;
1149   SilcSKEKEPayload payload;
1150   unsigned char hash[SILC_HASH_MAXLEN];
1151   SilcUInt32 hash_len;
1152   SilcPublicKey public_key = NULL;
1153   int key_len, block_len;
1154
1155   if (ske->aborted) {
1156     /** Aborted */
1157     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1158     return SILC_FSM_CONTINUE;
1159   }
1160
1161   /* Check result of public key verification */
1162   if (ske->status != SILC_SKE_STATUS_OK) {
1163     /** Public key not verified */
1164     SILC_LOG_DEBUG(("Public key verification failed"));
1165     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1166     return SILC_FSM_CONTINUE;
1167   }
1168
1169   payload = ske->ke2_payload;
1170
1171   if (payload->pk_data) {
1172     /* Decode the public key */
1173     if (!silc_pkcs_public_key_decode(payload->pk_data, payload->pk_len,
1174                                      &public_key)) {
1175       SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1176       status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1177       goto err;
1178     }
1179
1180     SILC_LOG_DEBUG(("Public key is authentic"));
1181
1182     /* Compute the hash value */
1183     status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1184     if (status != SILC_SKE_STATUS_OK)
1185       goto err;
1186
1187     ske->hash = silc_memdup(hash, hash_len);
1188     ske->hash_len = hash_len;
1189
1190     SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1191
1192     /* Verify signature */
1193     silc_pkcs_public_key_set(ske->prop->pkcs, public_key);
1194     if (silc_pkcs_verify(ske->prop->pkcs, payload->sign_data,
1195                          payload->sign_len, hash, hash_len) == FALSE) {
1196       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1197       status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1198       goto err;
1199     }
1200
1201     SILC_LOG_DEBUG(("Signature is Ok"));
1202
1203     silc_pkcs_public_key_free(public_key);
1204     memset(hash, 'F', hash_len);
1205   }
1206
1207   ske->status = SILC_SKE_STATUS_OK;
1208
1209   /* Process key material */
1210   key_len = silc_cipher_get_key_len(ske->prop->cipher);
1211   block_len = silc_cipher_get_key_len(ske->prop->cipher);
1212   hash_len = silc_hash_len(ske->prop->hash);
1213   ske->keymat = silc_ske_process_key_material(ske, block_len,
1214                                               key_len, hash_len);
1215   if (!ske->keymat) {
1216     SILC_LOG_ERROR(("Error processing key material"));
1217     status = SILC_SKE_STATUS_ERROR;
1218     goto err;
1219   }
1220
1221   /* Send SUCCESS packet */
1222   /* XXX */
1223
1224   /** Waiting completion */
1225   silc_fsm_next(fsm, silc_ske_st_initiator_end);
1226   return SILC_FSM_WAIT;
1227
1228  err:
1229   memset(hash, 'F', sizeof(hash));
1230   silc_ske_payload_ke_free(payload);
1231   ske->ke2_payload = NULL;
1232
1233   silc_mp_uninit(ske->KEY);
1234   silc_free(ske->KEY);
1235   ske->KEY = NULL;
1236
1237   if (public_key)
1238     silc_pkcs_public_key_free(public_key);
1239
1240   if (ske->hash) {
1241     memset(ske->hash, 'F', hash_len);
1242     silc_free(ske->hash);
1243     ske->hash = NULL;
1244   }
1245
1246   if (status == SILC_SKE_STATUS_OK)
1247     status = SILC_SKE_STATUS_ERROR;
1248
1249   /** Error */
1250   ske->status = status;
1251   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1252   return SILC_FSM_CONTINUE;
1253 }
1254
1255 /* Protocol completed */
1256
1257 SILC_FSM_STATE(silc_ske_st_initiator_end)
1258 {
1259   SilcSKE ske = fsm_context;
1260
1261   if (ske->aborted) {
1262     /** Aborted */
1263     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1264     return SILC_FSM_CONTINUE;
1265   }
1266
1267   /* Call the completion callback */
1268   if (ske->callbacks->completed)
1269     ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL, NULL);
1270
1271   return SILC_FSM_FINISH;
1272 }
1273
1274 /* Aborted by application */
1275
1276 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1277 {
1278
1279   return SILC_FSM_FINISH;
1280 }
1281
1282 /* Error occurred */
1283
1284 SILC_FSM_STATE(silc_ske_st_initiator_error)
1285 {
1286
1287   return SILC_FSM_FINISH;
1288 }
1289
1290
1291 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1292                                         void *destructor_context)
1293 {
1294
1295 }
1296
1297 /* Starts the protocol as initiator */
1298
1299 SilcAsyncOperation
1300 silc_ske_initiator(SilcSKE ske,
1301                    SilcPacketStream stream,
1302                    SilcSKEStartPayload start_payload)
1303 {
1304   SILC_LOG_DEBUG(("Start SKE as initiator"));
1305
1306   if (!ske || !stream || !start_payload)
1307     return NULL;
1308
1309   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1310     return NULL;
1311
1312   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1313                      ske->schedule))
1314     return NULL;
1315
1316   ske->start_payload = start_payload;
1317
1318   /* Link to packet stream to get key exchange packets */
1319   ske->stream = stream;
1320   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1321                           SILC_PACKET_KEY_EXCHANGE,
1322                           SILC_PACKET_KEY_EXCHANGE_2,
1323                           SILC_PACKET_SUCCESS,
1324                           SILC_PACKET_FAILURE, -1);
1325
1326   /* Start SKE as initiator */
1327   silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1328
1329   return &ske->op;
1330 }
1331
1332
1333 /******************************** Responder *********************************/
1334
1335 SILC_FSM_STATE(silc_ske_st_responder_start);
1336 SILC_FSM_STATE(silc_ske_st_responder_phase1);
1337 SILC_FSM_STATE(silc_ske_st_responder_phase2);
1338 SILC_FSM_STATE(silc_ske_st_responder_phase3);
1339 SILC_FSM_STATE(silc_ske_st_responder_phase4);
1340 SILC_FSM_STATE(silc_ske_st_responder_phase5);
1341 SILC_FSM_STATE(silc_ske_st_responder_end);
1342 SILC_FSM_STATE(silc_ske_st_responder_aborted);
1343 SILC_FSM_STATE(silc_ske_st_responder_failure);
1344 SILC_FSM_STATE(silc_ske_st_responder_error);
1345
1346 /* Start protocol as responder.  Wait initiator's start payload */
1347
1348 SILC_FSM_STATE(silc_ske_st_responder_start)
1349 {
1350   SilcSKE ske = fsm_context;
1351
1352   SILC_LOG_DEBUG(("Start"));
1353
1354   if (ske->aborted) {
1355     /** Aborted */
1356     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1357     return SILC_FSM_CONTINUE;
1358   }
1359
1360   /* Start timeout */
1361   /* XXX */
1362
1363   /** Wait for initiator */
1364   silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1365   return SILC_FSM_WAIT;
1366 }
1367
1368 /* Decode initiator's start payload */
1369
1370 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1371 {
1372   SilcSKE ske = fsm_context;
1373   SilcSKEStatus status;
1374   SilcSKEStartPayload remote_payload = NULL, payload = NULL;
1375   SilcBuffer packet_buf = &ske->packet->buffer;
1376
1377   SILC_LOG_DEBUG(("Start"));
1378
1379   if (ske->aborted) {
1380     /** Aborted */
1381     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1382     return SILC_FSM_CONTINUE;
1383   }
1384
1385   /* See if received failure from remote */
1386   if (ske->packet->type == SILC_PACKET_FAILURE) {
1387     silc_fsm_next(fsm, silc_ske_st_responder_failure);
1388     return SILC_FSM_CONTINUE;
1389   }
1390
1391   /* Decode the payload */
1392   status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1393   if (status != SILC_SKE_STATUS_OK) {
1394     /** Error decoding Start Payload */
1395     silc_packet_free(ske->packet);
1396     ske->status = status;
1397     silc_fsm_next(fsm, silc_ske_st_responder_error);
1398     return SILC_FSM_CONTINUE;
1399   }
1400
1401   /* Take a copy of the payload buffer for future use. It is used to
1402      compute the HASH value. */
1403   ske->start_payload_copy = silc_buffer_copy(packet_buf);
1404
1405   silc_packet_free(ske->packet);
1406
1407   /* Force the mutual authentication flag if we want to do it. */
1408   if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1409     SILC_LOG_DEBUG(("Force mutual authentication"));
1410     remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1411   }
1412
1413   /* Force PFS flag if we require it */
1414   if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1415     SILC_LOG_DEBUG(("Force PFS"));
1416     remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1417   }
1418
1419   /* Disable IV Included flag if requested */
1420   if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1421       !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1422     SILC_LOG_DEBUG(("We do not support IV Included flag"));
1423     remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1424   }
1425
1426   /* Parse and select the security properties from the payload */
1427   payload = silc_calloc(1, sizeof(*payload));
1428   status = silc_ske_select_security_properties(ske, payload, remote_payload);
1429   if (status != SILC_SKE_STATUS_OK) {
1430     /** Error selecting proposal */
1431     if (remote_payload)
1432       silc_ske_payload_start_free(remote_payload);
1433     silc_free(payload);
1434     ske->status = status;
1435     silc_fsm_next(fsm, silc_ske_st_responder_error);
1436     return SILC_FSM_CONTINUE;
1437   }
1438
1439   ske->start_payload = payload;
1440
1441   silc_ske_payload_start_free(remote_payload);
1442
1443   /** Send proposal to initiator */
1444   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1445   return SILC_FSM_CONTINUE;
1446 }
1447
1448 /* Phase-2.  Send Start Payload */
1449
1450 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1451 {
1452   SilcSKE ske = fsm_context;
1453   SilcSKEStatus status;
1454   SilcBuffer payload_buf;
1455   SilcSKESecurityProperties prop;
1456   SilcSKEDiffieHellmanGroup group = NULL;
1457
1458   SILC_LOG_DEBUG(("Start"));
1459
1460   /* Allocate security properties from the payload. These are allocated
1461      only for this negotiation and will be free'd after KE is over. */
1462   ske->prop = prop = silc_calloc(1, sizeof(*prop));
1463   if (!ske->prop) {
1464     status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1465     goto err;
1466   }
1467   prop->flags = ske->start_payload->flags;
1468   status = silc_ske_group_get_by_name(ske->start_payload->ke_grp_list,
1469                                       &group);
1470   if (status != SILC_SKE_STATUS_OK)
1471     goto err;
1472
1473   prop->group = group;
1474
1475   /* XXX these shouldn't be allocated before we know the remote's
1476      public key type.  It's unnecessary to allocate these because the
1477      select_security_properties has succeeded already. */
1478   if (silc_pkcs_alloc(ske->start_payload->pkcs_alg_list,
1479                       SILC_PKCS_SILC, &prop->pkcs) == FALSE) {
1480     status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1481     goto err;
1482   }
1483   if (silc_cipher_alloc(ske->start_payload->enc_alg_list,
1484                         &prop->cipher) == FALSE) {
1485     status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1486     goto err;
1487   }
1488   if (silc_hash_alloc(ske->start_payload->hash_alg_list,
1489                       &prop->hash) == FALSE) {
1490     status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1491     goto err;
1492   }
1493   if (silc_hmac_alloc(ske->start_payload->hmac_alg_list, NULL,
1494                       &prop->hmac) == FALSE) {
1495     status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1496     goto err;
1497   }
1498
1499   /* Encode the payload */
1500   status = silc_ske_payload_start_encode(ske, ske->start_payload,
1501                                          &payload_buf);
1502   if (status != SILC_SKE_STATUS_OK)
1503     goto err;
1504
1505   /* Send the packet. */
1506   if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE, 0,
1507                         payload_buf->data, silc_buffer_len(payload_buf)))
1508     goto err;
1509
1510   silc_buffer_free(payload_buf);
1511
1512   /** Waiting initiator's KE payload */
1513   silc_fsm_next(fsm, silc_ske_st_responder_phase3);
1514   return SILC_FSM_WAIT;
1515
1516  err:
1517   if (group)
1518     silc_ske_group_free(group);
1519
1520   if (prop->pkcs)
1521     silc_pkcs_free(prop->pkcs);
1522   if (prop->cipher)
1523     silc_cipher_free(prop->cipher);
1524   if (prop->hash)
1525     silc_hash_free(prop->hash);
1526   if (prop->hmac)
1527     silc_hmac_free(prop->hmac);
1528   silc_free(prop);
1529   ske->prop = NULL;
1530
1531   if (status == SILC_SKE_STATUS_OK)
1532     status = SILC_SKE_STATUS_ERROR;
1533
1534   /** Error */
1535   ske->status = status;
1536   silc_fsm_next(fsm, silc_ske_st_responder_error);
1537   return SILC_FSM_CONTINUE;
1538 }
1539
1540 /* Phase-3.  Decode initiator's KE payload */
1541
1542 SILC_FSM_STATE(silc_ske_st_responder_phase3)
1543 {
1544   SilcSKE ske = fsm_context;
1545   SilcSKEStatus status;
1546   SilcSKEKEPayload recv_payload;
1547   SilcBuffer packet_buf = &ske->packet->buffer;
1548
1549   SILC_LOG_DEBUG(("Start"));
1550
1551   if (ske->aborted) {
1552     /** Aborted */
1553     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1554     return SILC_FSM_CONTINUE;
1555   }
1556
1557   /* See if received failure from remote */
1558   if (ske->packet->type == SILC_PACKET_FAILURE) {
1559     silc_fsm_next(fsm, silc_ske_st_responder_failure);
1560     return SILC_FSM_CONTINUE;
1561   }
1562
1563   /* Decode Key Exchange Payload */
1564   status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1565   if (status != SILC_SKE_STATUS_OK) {
1566     /** Error decoding KE payload */
1567     silc_packet_free(ske->packet);
1568     ske->status = status;
1569     silc_fsm_next(fsm, silc_ske_st_responder_error);
1570     return SILC_FSM_CONTINUE;
1571   }
1572
1573   ske->ke1_payload = recv_payload;
1574
1575   silc_packet_free(ske->packet);
1576
1577   /* Verify the received public key and verify the signature if we are
1578      doing mutual authentication. */
1579   if (ske->start_payload &&
1580       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1581
1582     SILC_LOG_DEBUG(("We are doing mutual authentication"));
1583
1584     if (!recv_payload->pk_data && ske->callbacks->verify_key) {
1585       /** Public key not provided */
1586       SILC_LOG_ERROR(("Remote end did not send its public key (or "
1587                       "certificate), even though we require it"));
1588       ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1589       silc_fsm_next(fsm, silc_ske_st_responder_error);
1590       return SILC_FSM_CONTINUE;
1591     }
1592
1593     if (recv_payload->pk_data && ske->callbacks->verify_key) {
1594       SILC_LOG_DEBUG(("Verifying public key"));
1595
1596       /** Waiting public key verification */
1597       silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1598       SILC_FSM_CALL(ske->callbacks->verify_key(ske, recv_payload->pk_data,
1599                                                recv_payload->pk_len,
1600                                                recv_payload->pk_type,
1601                                                ske->callbacks->context,
1602                                                silc_ske_pk_verified, NULL));
1603       /* NOT REACHED */
1604     }
1605   }
1606
1607   /** Generate KE2 payload */
1608   silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1609   return SILC_FSM_CONTINUE;
1610 }
1611
1612 /* Phase-4. Generate KE2 payload */
1613
1614 SILC_FSM_STATE(silc_ske_st_responder_phase4)
1615 {
1616   SilcSKE ske = fsm_context;
1617   SilcSKEStatus status;
1618   SilcSKEKEPayload recv_payload, send_payload;
1619   SilcMPInt *x, *KEY;
1620
1621   if (ske->aborted) {
1622     /** Aborted */
1623     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1624     return SILC_FSM_CONTINUE;
1625   }
1626
1627   /* Check result of public key verification */
1628   if (ske->status != SILC_SKE_STATUS_OK) {
1629     /** Public key not verified */
1630     SILC_LOG_DEBUG(("Public key verification failed"));
1631     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1632     return SILC_FSM_CONTINUE;
1633   }
1634
1635   recv_payload = ske->ke1_payload;
1636
1637   /* The public key verification was performed only if the Mutual
1638      Authentication flag is set. */
1639   if (ske->start_payload &&
1640       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1641     SilcPublicKey public_key = NULL;
1642     unsigned char hash[SILC_HASH_MAXLEN];
1643     SilcUInt32 hash_len;
1644
1645     /* Decode the public key */
1646     if (!silc_pkcs_public_key_decode(recv_payload->pk_data,
1647                                      recv_payload->pk_len,
1648                                      &public_key)) {
1649       /** Error decoding public key */
1650       SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1651       ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1652       silc_fsm_next(fsm, silc_ske_st_responder_error);
1653       return SILC_FSM_CONTINUE;
1654     }
1655
1656     SILC_LOG_DEBUG(("Public key is authentic"));
1657
1658     /* Compute the hash value */
1659     status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1660     if (status != SILC_SKE_STATUS_OK) {
1661       /** Error computing hash */
1662       ske->status = status;
1663       silc_fsm_next(fsm, silc_ske_st_responder_error);
1664       return SILC_FSM_CONTINUE;
1665     }
1666
1667     SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
1668
1669     /* Verify signature */
1670     silc_pkcs_public_key_set(ske->prop->pkcs, public_key);
1671     if (silc_pkcs_verify(ske->prop->pkcs, recv_payload->sign_data,
1672                          recv_payload->sign_len, hash, hash_len) == FALSE) {
1673       /** Incorrect signature */
1674       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1675       ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1676       silc_fsm_next(fsm, silc_ske_st_responder_error);
1677       return SILC_FSM_CONTINUE;
1678     }
1679
1680     SILC_LOG_DEBUG(("Signature is Ok"));
1681
1682     silc_pkcs_public_key_free(public_key);
1683     memset(hash, 'F', hash_len);
1684   }
1685
1686   /* Create the random number x, 1 < x < q. */
1687   x = silc_calloc(1, sizeof(*x));
1688   silc_mp_init(x);
1689   status =
1690     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1691                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1692                         x);
1693   if (status != SILC_SKE_STATUS_OK) {
1694     /** Error generating random number */
1695     silc_mp_uninit(x);
1696     silc_free(x);
1697     ske->status = status;
1698     silc_fsm_next(fsm, silc_ske_st_responder_error);
1699     return SILC_FSM_CONTINUE;
1700   }
1701
1702   /* Save the results for later processing */
1703   send_payload = silc_calloc(1, sizeof(*send_payload));
1704   ske->x = x;
1705   ske->ke2_payload = send_payload;
1706
1707   SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
1708
1709   /* Do the Diffie Hellman computation, f = g ^ x mod p */
1710   silc_mp_init(&send_payload->x);
1711   silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
1712                   &ske->prop->group->group);
1713
1714   SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
1715
1716   /* Compute the shared secret key */
1717   KEY = silc_calloc(1, sizeof(*KEY));
1718   silc_mp_init(KEY);
1719   silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
1720                   &ske->prop->group->group);
1721   ske->KEY = KEY;
1722
1723   /** Send KE2 payload */
1724   silc_fsm_next(fsm, silc_ske_st_responder_phase5);
1725   return SILC_FSM_CONTINUE;
1726 }
1727
1728 /* Phase-5.  Send KE2 payload */
1729
1730 SILC_FSM_STATE(silc_ske_st_responder_phase5)
1731 {
1732   SilcSKE ske = fsm_context;
1733   SilcSKEStatus status;
1734   SilcBuffer payload_buf;
1735   unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
1736   SilcUInt32 hash_len, sign_len, pk_len;
1737
1738   SILC_LOG_DEBUG(("Start"));
1739
1740   if (ske->public_key && ske->private_key) {
1741     SILC_LOG_DEBUG(("Getting public key"));
1742
1743     /* Get the public key */
1744     pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1745     if (!pk) {
1746       /** Error encoding public key */
1747       status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1748       silc_fsm_next(fsm, silc_ske_st_responder_error);
1749       return SILC_FSM_CONTINUE;
1750     }
1751     ske->ke2_payload->pk_data = pk;
1752     ske->ke2_payload->pk_len = pk_len;
1753
1754     SILC_LOG_DEBUG(("Computing HASH value"));
1755
1756     /* Compute the hash value */
1757     memset(hash, 0, sizeof(hash));
1758     status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1759     if (status != SILC_SKE_STATUS_OK) {
1760       /** Error computing hash */
1761       ske->status = status;
1762       silc_fsm_next(fsm, silc_ske_st_responder_error);
1763       return SILC_FSM_CONTINUE;
1764     }
1765
1766     ske->hash = silc_memdup(hash, hash_len);
1767     ske->hash_len = hash_len;
1768
1769     SILC_LOG_DEBUG(("Signing HASH value"));
1770
1771     /* Sign the hash value */
1772     silc_pkcs_private_key_data_set(ske->prop->pkcs, ske->private_key->prv,
1773                                    ske->private_key->prv_len);
1774     if (silc_pkcs_get_key_len(ske->prop->pkcs) / 8 > sizeof(sign) - 1 ||
1775         !silc_pkcs_sign(ske->prop->pkcs, hash, hash_len, sign, &sign_len)) {
1776       /** Error computing signature */
1777       status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1778       silc_fsm_next(fsm, silc_ske_st_responder_error);
1779       return SILC_FSM_CONTINUE;
1780     }
1781     ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
1782     ske->ke2_payload->sign_len = sign_len;
1783     memset(sign, 0, sizeof(sign));
1784   }
1785   ske->ke2_payload->pk_type = ske->pk_type;
1786
1787   /* Encode the Key Exchange Payload */
1788   status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
1789                                       &payload_buf);
1790   if (status != SILC_SKE_STATUS_OK) {
1791     /** Error encoding KE payload */
1792     ske->status = status;
1793     silc_fsm_next(fsm, silc_ske_st_responder_error);
1794     return SILC_FSM_CONTINUE;
1795   }
1796
1797   /* Send the packet. */
1798   if (!silc_packet_send(ske->stream, SILC_PACKET_KEY_EXCHANGE_2, 0,
1799                         payload_buf->data, silc_buffer_len(payload_buf))) {
1800     ske->status = SILC_SKE_STATUS_ERROR;
1801     silc_fsm_next(fsm, silc_ske_st_responder_error);
1802     return SILC_FSM_CONTINUE;
1803   }
1804
1805   silc_buffer_free(payload_buf);
1806
1807   /** Waiting completion */
1808   silc_fsm_next(fsm, silc_ske_st_responder_end);
1809   return SILC_FSM_WAIT;
1810 }
1811
1812 /* Protocol completed */
1813
1814 SILC_FSM_STATE(silc_ske_st_responder_end)
1815 {
1816   SilcSKE ske = fsm_context;
1817   unsigned char tmp[4];
1818   SilcUInt32 hash_len, key_len, block_len;
1819
1820   if (ske->aborted) {
1821     /** Aborted */
1822     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1823     return SILC_FSM_CONTINUE;
1824   }
1825
1826   /* Check the result of the protocol */
1827   if (ske->packet->type == SILC_PACKET_FAILURE) {
1828     silc_fsm_next(fsm, silc_ske_st_responder_failure);
1829     return SILC_FSM_CONTINUE;
1830   }
1831   silc_packet_free(ske->packet);
1832
1833   /* Process key material */
1834   key_len = silc_cipher_get_key_len(ske->prop->cipher);
1835   block_len = silc_cipher_get_key_len(ske->prop->cipher);
1836   hash_len = silc_hash_len(ske->prop->hash);
1837   ske->keymat = silc_ske_process_key_material(ske, block_len,
1838                                               key_len, hash_len);
1839   if (!ske->keymat) {
1840     /** Error processing key material */
1841     ske->status = SILC_SKE_STATUS_ERROR;
1842     silc_fsm_next(fsm, silc_ske_st_responder_error);
1843     return SILC_FSM_CONTINUE;
1844   }
1845
1846   /* Send SUCCESS packet */
1847   SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
1848   silc_packet_send(ske->stream, SILC_PACKET_SUCCESS, 0, tmp, 4);
1849
1850   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1851
1852   /* Call the completion callback */
1853   if (ske->callbacks->completed)
1854     ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1855                               ske->rekey, ske->callbacks->context);
1856
1857   return SILC_FSM_FINISH;
1858 }
1859
1860 /* Aborted by application */
1861
1862 SILC_FSM_STATE(silc_ske_st_responder_aborted)
1863 {
1864   SilcSKE ske = fsm_context;
1865   unsigned char tmp[4];
1866
1867   SILC_LOG_DEBUG(("Key exchange protocol aborted"));
1868
1869   /* Send FAILURE packet */
1870   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
1871   silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
1872
1873   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1874
1875   return SILC_FSM_FINISH;
1876 }
1877
1878 /* Failure received from remote */
1879
1880 SILC_FSM_STATE(silc_ske_st_responder_failure)
1881 {
1882   SilcSKE ske = fsm_context;
1883   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1884
1885   SILC_LOG_DEBUG(("Key exchange protocol failed"));
1886
1887   if (silc_buffer_len(&ske->packet->buffer) == 4)
1888     SILC_GET32_MSB(error, ske->packet->buffer.data);
1889   ske->status = error;
1890
1891   /* Call the completion callback */
1892   if (ske->callbacks->completed)
1893     ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1894                               ske->callbacks->context);
1895
1896   silc_packet_free(ske->packet);
1897   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1898
1899   return SILC_FSM_FINISH;
1900 }
1901
1902 /* Error occurred */
1903
1904 SILC_FSM_STATE(silc_ske_st_responder_error)
1905 {
1906   SilcSKE ske = fsm_context;
1907   unsigned char tmp[4];
1908
1909   SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
1910                   ske->status, silc_ske_map_status(ske->status)));
1911
1912   /* Send FAILURE packet */
1913   if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
1914     ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
1915   SILC_PUT32_MSB(ske->status, tmp);
1916   silc_packet_send(ske->stream, SILC_PACKET_FAILURE, 0, tmp, 4);
1917
1918   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1919
1920   return SILC_FSM_FINISH;
1921 }
1922
1923
1924 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
1925                                         void *destructor_context)
1926 {
1927
1928 }
1929
1930 /* Starts the protocol as responder. */
1931
1932 SilcAsyncOperation
1933 silc_ske_responder(SilcSKE ske,
1934                    SilcPacketStream stream,
1935                    const char *version,
1936                    SilcSKESecurityPropertyFlag flags)
1937 {
1938   SILC_LOG_DEBUG(("Start SKE as responder"));
1939
1940   if (!ske || !stream || !version) {
1941     return NULL;
1942   }
1943
1944   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1945     return NULL;
1946
1947   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
1948                      ske->schedule))
1949     return NULL;
1950
1951   ske->flags = flags;
1952   ske->version = strdup(version);
1953   if (!ske->version)
1954     return NULL;
1955   ske->responder = TRUE;
1956
1957   /* Link to packet stream to get key exchange packets */
1958   ske->stream = stream;
1959   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1960                           SILC_PACKET_KEY_EXCHANGE,
1961                           SILC_PACKET_KEY_EXCHANGE_1,
1962                           SILC_PACKET_SUCCESS,
1963                           SILC_PACKET_FAILURE, -1);
1964
1965   /* Start SKE as responder */
1966   silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
1967
1968   return &ske->op;
1969 }
1970
1971 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
1972
1973 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
1974 {
1975   return SILC_FSM_FINISH;
1976 }
1977
1978 /* Starts rekey protocol as initiator */
1979
1980 SilcAsyncOperation
1981 silc_ske_rekey_initiator(SilcSKE ske,
1982                          SilcPacketStream stream,
1983                          SilcSKERekeyMaterial rekey)
1984 {
1985   SILC_LOG_DEBUG(("Start SKE rekey as initator"));
1986
1987   if (!ske || !stream || !rekey)
1988     return NULL;
1989
1990   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1991     return NULL;
1992
1993   if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
1994     return NULL;
1995
1996   ske->rekey = rekey;
1997
1998   /* Link to packet stream to get key exchange packets */
1999   ske->stream = stream;
2000
2001   /* Start SKE rekey as initiator */
2002   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2003
2004   return &ske->op;
2005 }
2006
2007 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2008
2009 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2010 {
2011   return SILC_FSM_FINISH;
2012 }
2013
2014 /* Starts rekey protocol as responder */
2015
2016 SilcAsyncOperation
2017 silc_ske_rekey_responder(SilcSKE ske,
2018                          SilcPacketStream stream,
2019                          SilcBuffer ke_payload,
2020                          SilcSKERekeyMaterial rekey)
2021 {
2022   SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2023
2024   if (!ske || !stream || !rekey)
2025     return NULL;
2026   if (rekey->pfs && !ke_payload)
2027     return NULL;
2028
2029   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2030     return NULL;
2031
2032   if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2033     return NULL;
2034
2035   //  ske->packet_buf = ke_payload;
2036   ske->rekey = rekey;
2037
2038   /* Link to packet stream to get key exchange packets */
2039   ske->stream = stream;
2040
2041   /* Start SKE rekey as responder */
2042   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2043
2044   return &ske->op;
2045 }
2046
2047 /* Assembles security properties */
2048
2049 SilcSKEStartPayload
2050 silc_ske_assemble_security_properties(SilcSKE ske,
2051                                       SilcSKESecurityPropertyFlag flags,
2052                                       const char *version)
2053 {
2054   SilcSKEStartPayload rp;
2055   int i;
2056
2057   SILC_LOG_DEBUG(("Assembling KE Start Payload"));
2058
2059   rp = silc_calloc(1, sizeof(*rp));
2060
2061   /* Set flags */
2062   rp->flags = (unsigned char)flags;
2063
2064   /* Set random cookie */
2065   rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
2066   for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
2067     rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
2068   rp->cookie_len = SILC_SKE_COOKIE_LEN;
2069
2070   /* Put version */
2071   rp->version = strdup(version);
2072   rp->version_len = strlen(version);
2073
2074   /* Get supported Key Exhange groups */
2075   rp->ke_grp_list = silc_ske_get_supported_groups();
2076   rp->ke_grp_len = strlen(rp->ke_grp_list);
2077
2078   /* Get supported PKCS algorithms */
2079   rp->pkcs_alg_list = silc_pkcs_get_supported();
2080   rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
2081
2082   /* Get supported encryption algorithms */
2083   rp->enc_alg_list = silc_cipher_get_supported();
2084   rp->enc_alg_len = strlen(rp->enc_alg_list);
2085
2086   /* Get supported hash algorithms */
2087   rp->hash_alg_list = silc_hash_get_supported();
2088   rp->hash_alg_len = strlen(rp->hash_alg_list);
2089
2090   /* Get supported HMACs */
2091   rp->hmac_alg_list = silc_hmac_get_supported();
2092   rp->hmac_alg_len = strlen(rp->hmac_alg_list);
2093
2094   /* XXX */
2095   /* Get supported compression algorithms */
2096   rp->comp_alg_list = strdup("none");
2097   rp->comp_alg_len = strlen("none");
2098
2099   rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
2100     2 + rp->version_len +
2101     2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len +
2102     2 + rp->enc_alg_len + 2 + rp->hash_alg_len +
2103     2 + rp->hmac_alg_len + 2 + rp->comp_alg_len;
2104
2105   return rp;
2106 }
2107
2108 /* Processes the provided key material `data' as the SILC protocol
2109    specification defines. */
2110
2111 SilcSKEKeyMaterial
2112 silc_ske_process_key_material_data(unsigned char *data,
2113                                    SilcUInt32 data_len,
2114                                    SilcUInt32 req_iv_len,
2115                                    SilcUInt32 req_enc_key_len,
2116                                    SilcUInt32 req_hmac_key_len,
2117                                    SilcHash hash)
2118 {
2119   SilcBuffer buf;
2120   unsigned char hashd[SILC_HASH_MAXLEN];
2121   SilcUInt32 hash_len = req_hmac_key_len;
2122   SilcUInt32 enc_key_len = req_enc_key_len / 8;
2123   SilcSKEKeyMaterial key;
2124
2125   SILC_LOG_DEBUG(("Start"));
2126
2127   if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2128     return NULL;
2129
2130   key = silc_calloc(1, sizeof(*key));
2131   if (!key)
2132     return NULL;
2133
2134   buf = silc_buffer_alloc_size(1 + data_len);
2135   if (!buf)
2136     return NULL;
2137   silc_buffer_format(buf,
2138                      SILC_STR_UI_CHAR(0),
2139                      SILC_STR_UI_XNSTRING(data, data_len),
2140                      SILC_STR_END);
2141
2142   /* Take IVs */
2143   memset(hashd, 0, sizeof(hashd));
2144   buf->data[0] = 0;
2145   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2146   key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2147   memcpy(key->send_iv, hashd, req_iv_len);
2148   memset(hashd, 0, sizeof(hashd));
2149   buf->data[0] = 1;
2150   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2151   key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2152   memcpy(key->receive_iv, hashd, req_iv_len);
2153   key->iv_len = req_iv_len;
2154
2155   /* Take the encryption keys. If requested key size is more than
2156      the size of hash length we will distribute more key material
2157      as protocol defines. */
2158   buf->data[0] = 2;
2159   if (enc_key_len > hash_len) {
2160     SilcBuffer dist;
2161     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2162         k3[SILC_HASH_MAXLEN];
2163     unsigned char *dtmp;
2164
2165     /* XXX */
2166     if (enc_key_len > (3 * hash_len))
2167       return NULL;
2168
2169     /* Take first round */
2170     memset(k1, 0, sizeof(k1));
2171     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2172
2173     /* Take second round */
2174     dist = silc_buffer_alloc_size(data_len + hash_len);
2175     if (!dist)
2176       return NULL;
2177     silc_buffer_format(dist,
2178                        SILC_STR_UI_XNSTRING(data, data_len),
2179                        SILC_STR_UI_XNSTRING(k1, hash_len),
2180                        SILC_STR_END);
2181     memset(k2, 0, sizeof(k2));
2182     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2183
2184     /* Take third round */
2185     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2186     silc_buffer_pull_tail(dist, hash_len);
2187     silc_buffer_pull(dist, data_len + hash_len);
2188     silc_buffer_format(dist,
2189                        SILC_STR_UI_XNSTRING(k2, hash_len),
2190                        SILC_STR_END);
2191     silc_buffer_push(dist, data_len + hash_len);
2192     memset(k3, 0, sizeof(k3));
2193     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2194
2195     /* Then, save the keys */
2196     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2197     memcpy(dtmp, k1, hash_len);
2198     memcpy(dtmp + hash_len, k2, hash_len);
2199     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2200
2201     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2202     memcpy(key->send_enc_key, dtmp, enc_key_len);
2203     key->enc_key_len = req_enc_key_len;
2204
2205     memset(dtmp, 0, (3 * hash_len));
2206     memset(k1, 0, sizeof(k1));
2207     memset(k2, 0, sizeof(k2));
2208     memset(k3, 0, sizeof(k3));
2209     silc_free(dtmp);
2210     silc_buffer_clear(dist);
2211     silc_buffer_free(dist);
2212   } else {
2213     /* Take normal hash as key */
2214     memset(hashd, 0, sizeof(hashd));
2215     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2216     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2217     memcpy(key->send_enc_key, hashd, enc_key_len);
2218     key->enc_key_len = req_enc_key_len;
2219   }
2220
2221   buf->data[0] = 3;
2222   if (enc_key_len > hash_len) {
2223     SilcBuffer dist;
2224     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2225         k3[SILC_HASH_MAXLEN];
2226     unsigned char *dtmp;
2227
2228     /* XXX */
2229     if (enc_key_len > (3 * hash_len))
2230       return NULL;
2231
2232     /* Take first round */
2233     memset(k1, 0, sizeof(k1));
2234     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2235
2236     /* Take second round */
2237     dist = silc_buffer_alloc_size(data_len + hash_len);
2238     if (!dist)
2239       return NULL;
2240     silc_buffer_format(dist,
2241                        SILC_STR_UI_XNSTRING(data, data_len),
2242                        SILC_STR_UI_XNSTRING(k1, hash_len),
2243                        SILC_STR_END);
2244     memset(k2, 0, sizeof(k2));
2245     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2246
2247     /* Take third round */
2248     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2249     silc_buffer_pull_tail(dist, hash_len);
2250     silc_buffer_pull(dist, data_len + hash_len);
2251     silc_buffer_format(dist,
2252                        SILC_STR_UI_XNSTRING(k2, hash_len),
2253                        SILC_STR_END);
2254     silc_buffer_push(dist, data_len + hash_len);
2255     memset(k3, 0, sizeof(k3));
2256     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2257
2258     /* Then, save the keys */
2259     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2260     memcpy(dtmp, k1, hash_len);
2261     memcpy(dtmp + hash_len, k2, hash_len);
2262     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2263
2264     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2265     memcpy(key->receive_enc_key, dtmp, enc_key_len);
2266     key->enc_key_len = req_enc_key_len;
2267
2268     memset(dtmp, 0, (3 * hash_len));
2269     memset(k1, 0, sizeof(k1));
2270     memset(k2, 0, sizeof(k2));
2271     memset(k3, 0, sizeof(k3));
2272     silc_free(dtmp);
2273     silc_buffer_clear(dist);
2274     silc_buffer_free(dist);
2275   } else {
2276     /* Take normal hash as key */
2277     memset(hashd, 0, sizeof(hashd));
2278     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2279     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2280     memcpy(key->receive_enc_key, hashd, enc_key_len);
2281     key->enc_key_len = req_enc_key_len;
2282   }
2283
2284   /* Take HMAC keys */
2285   memset(hashd, 0, sizeof(hashd));
2286   buf->data[0] = 4;
2287   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2288   key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2289   memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2290   memset(hashd, 0, sizeof(hashd));
2291   buf->data[0] = 5;
2292   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2293   key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2294   memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2295   key->hmac_key_len = req_hmac_key_len;
2296   memset(hashd, 0, sizeof(hashd));
2297
2298   silc_buffer_clear(buf);
2299   silc_buffer_free(buf);
2300
2301   return key;
2302 }
2303
2304 /* Processes negotiated key material as protocol specifies. This returns
2305    the actual keys to be used in the SILC. */
2306
2307 SilcSKEKeyMaterial
2308 silc_ske_process_key_material(SilcSKE ske,
2309                               SilcUInt32 req_iv_len,
2310                               SilcUInt32 req_enc_key_len,
2311                               SilcUInt32 req_hmac_key_len)
2312 {
2313   SilcBuffer buf;
2314   unsigned char *tmpbuf;
2315   SilcUInt32 klen;
2316   SilcSKEKeyMaterial key;
2317
2318   /* Encode KEY to binary data */
2319   tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2320
2321   buf = silc_buffer_alloc_size(klen + ske->hash_len);
2322   if (!buf)
2323     return NULL;
2324   silc_buffer_format(buf,
2325                      SILC_STR_UI_XNSTRING(tmpbuf, klen),
2326                      SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2327                      SILC_STR_END);
2328
2329   /* Process the key material */
2330   key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2331                                            req_iv_len, req_enc_key_len,
2332                                            req_hmac_key_len,
2333                                            ske->prop->hash);
2334
2335   memset(tmpbuf, 0, klen);
2336   silc_free(tmpbuf);
2337   silc_buffer_clear(buf);
2338   silc_buffer_free(buf);
2339
2340   return key;
2341 }
2342
2343 /* Free key material structure */
2344
2345 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2346 {
2347   if (!key)
2348     return;
2349
2350   if (key->send_iv)
2351     silc_free(key->send_iv);
2352   if (key->receive_iv)
2353     silc_free(key->receive_iv);
2354   if (key->send_enc_key) {
2355     memset(key->send_enc_key, 0, key->enc_key_len / 8);
2356     silc_free(key->send_enc_key);
2357   }
2358   if (key->receive_enc_key) {
2359     memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2360     silc_free(key->receive_enc_key);
2361   }
2362   if (key->send_hmac_key) {
2363     memset(key->send_hmac_key, 0, key->hmac_key_len);
2364     silc_free(key->send_hmac_key);
2365   }
2366   if (key->receive_hmac_key) {
2367     memset(key->receive_hmac_key, 0, key->hmac_key_len);
2368     silc_free(key->receive_hmac_key);
2369   }
2370   silc_free(key);
2371 }
2372
2373 /* Set keys into use */
2374
2375 SilcBool silc_ske_set_keys(SilcSKE ske,
2376                            SilcSKEKeyMaterial keymat,
2377                            SilcSKESecurityProperties prop,
2378                            SilcCipher *ret_send_key,
2379                            SilcCipher *ret_receive_key,
2380                            SilcHmac *ret_hmac_send,
2381                            SilcHmac *ret_hmac_receive,
2382                            SilcHash *ret_hash)
2383 {
2384   /* Allocate ciphers to be used in the communication */
2385   if (ret_send_key) {
2386     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2387                            ret_send_key))
2388       return FALSE;
2389   }
2390   if (ret_receive_key) {
2391     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2392                            ret_receive_key))
2393       return FALSE;
2394   }
2395
2396   /* Allocate HMACs */
2397   if (ret_hmac_send) {
2398     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2399                          ret_hmac_send))
2400       return FALSE;
2401   }
2402   if (ret_hmac_receive) {
2403     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2404                          ret_hmac_receive))
2405       return FALSE;
2406   }
2407
2408   /* Set key material */
2409   if (ske->responder) {
2410     silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2411                         keymat->enc_key_len);
2412     silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2413     silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2414                         keymat->enc_key_len);
2415     silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2416     silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2417                       keymat->hmac_key_len);
2418     silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2419                       keymat->hmac_key_len);
2420   } else {
2421     silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2422                         keymat->enc_key_len);
2423     silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2424     silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2425                         keymat->enc_key_len);
2426     silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2427     silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2428                       keymat->hmac_key_len);
2429     silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2430                       keymat->hmac_key_len);
2431   }
2432
2433   /* Allocate hash */
2434   if (ret_hash) {
2435     if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2436       return FALSE;
2437   }
2438
2439   SILC_LOG_INFO(("Security properties: %s %s %s %s",
2440                  ret_send_key ? silc_cipher_get_name(*ret_send_key) : "??",
2441                  ret_hmac_send ? silc_hmac_get_name(*ret_hmac_send) : "??",
2442                  ret_hash ? silc_hash_get_name(*ret_hash) : "??",
2443                  ske->prop->flags & SILC_SKE_SP_FLAG_PFS ? "PFS" : ""));
2444
2445   return TRUE;
2446 }
2447
2448 const char *silc_ske_status_string[] =
2449 {
2450   /* Official */
2451   "Ok",
2452   "Unkown error occurred",
2453   "Bad payload in packet",
2454   "Unsupported group",
2455   "Unsupported cipher",
2456   "Unsupported PKCS",
2457   "Unsupported hash function",
2458   "Unsupported HMAC",
2459   "Unsupported public key (or certificate)",
2460   "Incorrect signature",
2461   "Bad or unsupported version",
2462   "Invalid cookie",
2463
2464   /* Other errors */
2465   "Remote did not provide public key",
2466   "Bad reserved field in packet",
2467   "Bad payload length in packet",
2468   "Error computing signature",
2469   "System out of memory",
2470
2471   NULL
2472 };
2473
2474 /* Maps status to readable string and returns the string. If string is not
2475    found and empty character string ("") is returned. */
2476
2477 const char *silc_ske_map_status(SilcSKEStatus status)
2478 {
2479   int i;
2480
2481   for (i = 0; silc_ske_status_string[i]; i++)
2482     if (status == i)
2483       return silc_ske_status_string[i];
2484
2485   return "";
2486 }
2487
2488 /* Parses remote host's version string. */
2489
2490 SilcBool silc_ske_parse_version(SilcSKE ske,
2491                                 SilcUInt32 *protocol_version,
2492                                 char **protocol_version_string,
2493                                 SilcUInt32 *software_version,
2494                                 char **software_version_string,
2495                                 char **vendor_version)
2496 {
2497   return silc_parse_version_string(ske->remote_version,
2498                                    protocol_version,
2499                                    protocol_version_string,
2500                                    software_version,
2501                                    software_version_string,
2502                                    vendor_version);
2503 }