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