Fixed failure handling.
[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       ske->aborted) {
829     SILC_LOG_DEBUG(("Retry limit reached, packet was lost"));
830     ske->retry_count = 0;
831     ske->retry_timer = SILC_SKE_RETRY_MIN;
832     silc_free(ske->retrans.data);
833     ske->retrans.data = NULL;
834     ske->status = SILC_SKE_STATUS_TIMEOUT;
835     if (ske->responder)
836       silc_fsm_next(&ske->fsm, silc_ske_st_responder_failure);
837     else
838       silc_fsm_next(&ske->fsm, silc_ske_st_initiator_failure);
839     silc_fsm_continue_sync(&ske->fsm);
840     return;
841   }
842
843   SILC_LOG_DEBUG(("Retransmitting packet"));
844   silc_ske_packet_send(ske, ske->retrans.type, ske->retrans.flags,
845                        ske->retrans.data, ske->retrans.data_len);
846 }
847
848 /* Sends SILC packet.  Handles retransmissions with UDP streams. */
849
850 static SilcBool silc_ske_packet_send(SilcSKE ske,
851                                      SilcPacketType type,
852                                      SilcPacketFlags flags,
853                                      const unsigned char *data,
854                                      SilcUInt32 data_len)
855 {
856   SilcBool ret;
857
858   /* Send the packet */
859   ret = silc_packet_send(ske->stream, type, flags, data, data_len);
860
861   if (silc_packet_stream_is_udp(ske->stream) &&
862       type != SILC_PACKET_FAILURE) {
863     silc_free(ske->retrans.data);
864     ske->retrans.type = type;
865     ske->retrans.flags = flags;
866     ske->retrans.data = silc_memdup(data, data_len);
867     ske->retrans.data_len = data_len;
868     if (ske->retrans.data) {
869       SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
870                       ske->retry_timer));
871       silc_schedule_task_add_timeout(ske->schedule, silc_ske_packet_send_retry,
872                                      ske, ske->retry_timer, 0);
873     }
874     ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
875                         (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
876   }
877
878   return ret;
879 }
880
881
882 /******************************* Protocol API *******************************/
883
884 /* Allocates new SKE object. */
885
886 SilcSKE silc_ske_alloc(SilcRng rng, SilcSchedule schedule,
887                        SilcSKR repository, SilcPublicKey public_key,
888                        SilcPrivateKey private_key, void *context)
889 {
890   SilcSKE ske;
891
892   SILC_LOG_DEBUG(("Allocating new Key Exchange object"));
893
894   if (!rng || !schedule)
895     return NULL;
896
897   if (!public_key) {
898     SILC_LOG_ERROR(("Public key must be given to silc_ske_alloc"));
899     return NULL;
900   }
901
902   ske = silc_calloc(1, sizeof(*ske));
903   if (!ske)
904     return NULL;
905   ske->status = SILC_SKE_STATUS_OK;
906   ske->rng = rng;
907   ske->repository = repository;
908   ske->user_data = context;
909   ske->schedule = schedule;
910   ske->public_key = public_key;
911   ske->private_key = private_key;
912   ske->retry_timer = SILC_SKE_RETRY_MIN;
913
914   return ske;
915 }
916
917 /* Free's SKE object. */
918
919 void silc_ske_free(SilcSKE ske)
920 {
921   SILC_LOG_DEBUG(("Freeing Key Exchange object"));
922
923   if (!ske)
924     return;
925
926   if (ske->running) {
927     ske->freed = TRUE;
928     return;
929   }
930
931   /* Free start payload */
932   if (ske->start_payload)
933     silc_ske_payload_start_free(ske->start_payload);
934
935   /* Free KE payload */
936   if (ske->ke1_payload)
937     silc_ske_payload_ke_free(ske->ke1_payload);
938   if (ske->ke2_payload)
939     silc_ske_payload_ke_free(ske->ke2_payload);
940   silc_free(ske->remote_version);
941
942   /* Free rest */
943   if (ske->prop) {
944     if (ske->prop->group)
945       silc_ske_group_free(ske->prop->group);
946     if (ske->prop->cipher)
947       silc_cipher_free(ske->prop->cipher);
948     if (ske->prop->hash)
949       silc_hash_free(ske->prop->hash);
950     if (ske->prop->hmac)
951       silc_hmac_free(ske->prop->hmac);
952       silc_free(ske->prop);
953   }
954   if (ske->start_payload_copy)
955     silc_buffer_free(ske->start_payload_copy);
956   if (ske->x) {
957     silc_mp_uninit(ske->x);
958     silc_free(ske->x);
959   }
960   if (ske->KEY) {
961     silc_mp_uninit(ske->KEY);
962     silc_free(ske->KEY);
963   }
964   silc_free(ske->retrans.data);
965   silc_free(ske->hash);
966   silc_free(ske->callbacks);
967
968   memset(ske, 'F', sizeof(*ske));
969   silc_free(ske);
970 }
971
972 /* Return user context */
973
974 void *silc_ske_get_context(SilcSKE ske)
975 {
976   return ske->user_data;
977 }
978
979 /* Sets protocol callbacks */
980
981 void silc_ske_set_callbacks(SilcSKE ske,
982                             SilcSKEVerifyCb verify_key,
983                             SilcSKECompletionCb completed,
984                             void *context)
985 {
986   if (ske->callbacks)
987     silc_free(ske->callbacks);
988   ske->callbacks = silc_calloc(1, sizeof(*ske->callbacks));
989   if (!ske->callbacks)
990     return;
991   ske->callbacks->verify_key = verify_key;
992   ske->callbacks->completed = completed;
993   ske->callbacks->context = context;
994 }
995
996
997 /******************************** Initiator *********************************/
998
999 /* Start protocol.  Send our proposal */
1000
1001 SILC_FSM_STATE(silc_ske_st_initiator_start)
1002 {
1003   SilcSKE ske = fsm_context;
1004   SilcBuffer payload_buf;
1005   SilcStatus status;
1006
1007   SILC_LOG_DEBUG(("Start"));
1008
1009   if (ske->aborted) {
1010     /** Aborted */
1011     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1012     return SILC_FSM_CONTINUE;
1013   }
1014
1015   /* Encode the payload */
1016   status = silc_ske_payload_start_encode(ske, ske->start_payload,
1017                                          &payload_buf);
1018   if (status != SILC_SKE_STATUS_OK) {
1019     /** Error encoding Start Payload */
1020     ske->status = status;
1021     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1022     return SILC_FSM_CONTINUE;
1023   }
1024
1025   /* Save the the payload buffer for future use. It is later used to
1026      compute the HASH value. */
1027   ske->start_payload_copy = payload_buf;
1028
1029   /* Send the packet. */
1030   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1031                             silc_buffer_data(payload_buf),
1032                             silc_buffer_len(payload_buf))) {
1033     /** Error sending packet */
1034     SILC_LOG_DEBUG(("Error sending packet"));
1035     ske->status = SILC_SKE_STATUS_ERROR;
1036     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1037     return SILC_FSM_CONTINUE;
1038   }
1039
1040   /* XXX timeout */
1041
1042   /** Wait for responder proposal */
1043   SILC_LOG_DEBUG(("Waiting for reponder proposal"));
1044   silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
1045   return SILC_FSM_WAIT;
1046 }
1047
1048 /* Phase-1.  Receives responder's proposal */
1049
1050 SILC_FSM_STATE(silc_ske_st_initiator_phase1)
1051 {
1052   SilcSKE ske = fsm_context;
1053   SilcSKEStatus status;
1054   SilcSKEStartPayload payload;
1055   SilcSKESecurityProperties prop;
1056   SilcSKEDiffieHellmanGroup group = NULL;
1057   SilcBuffer packet_buf = &ske->packet->buffer;
1058   SilcUInt16 remote_port = 0;
1059   SilcID id;
1060   int coff = 0;
1061
1062   SILC_LOG_DEBUG(("Start"));
1063
1064   ske->retry_timer = SILC_SKE_RETRY_MIN;
1065   silc_schedule_task_del_by_context(ske->schedule, ske);
1066
1067   if (ske->aborted) {
1068     /** Aborted */
1069     silc_packet_free(ske->packet);
1070     ske->packet = NULL;
1071     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1072     return SILC_FSM_CONTINUE;
1073   }
1074
1075   /* See if received failure from remote */
1076   if (ske->packet->type == SILC_PACKET_FAILURE) {
1077     silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1078     return SILC_FSM_CONTINUE;
1079   }
1080
1081   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
1082     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1083     silc_packet_free(ske->packet);
1084     ske->packet = NULL;
1085     return SILC_FSM_WAIT;
1086   }
1087
1088   /* Decode the payload */
1089   status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
1090   if (status != SILC_SKE_STATUS_OK) {
1091     /** Error decoding Start Payload */
1092     silc_packet_free(ske->packet);
1093     ske->packet = NULL;
1094     ske->status = status;
1095     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1096     return SILC_FSM_CONTINUE;
1097   }
1098
1099   /* Get remote ID and set it to stream */
1100   if (ske->packet->src_id_len) {
1101     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
1102                    ske->packet->src_id_type,
1103                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1104                     (void *)&id.u.server_id : (void *)&id.u.client_id),
1105                    (ske->packet->src_id_type == SILC_ID_SERVER ?
1106                     sizeof(id.u.server_id) : sizeof(id.u.client_id)));
1107     silc_packet_set_ids(ske->stream, 0, NULL, ske->packet->src_id_type,
1108                         (ske->packet->src_id_type == SILC_ID_SERVER ?
1109                          (void *)&id.u.server_id : (void *)&id.u.client_id));
1110   }
1111
1112   silc_packet_free(ske->packet);
1113   ske->packet = NULL;
1114
1115   /* Check that the cookie is returned unmodified.  In case IV included
1116      flag and session port has been set, the first two bytes of cookie
1117      are the session port and we ignore them in this check. */
1118   if (payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED && ske->session_port) {
1119     /* Take remote port */
1120     SILC_GET16_MSB(remote_port, ske->start_payload->cookie);
1121     coff = 2;
1122   }
1123   if (memcmp(ske->start_payload->cookie + coff, payload->cookie + coff,
1124              SILC_SKE_COOKIE_LEN - coff)) {
1125     /** Invalid cookie */
1126     SILC_LOG_ERROR(("Invalid cookie, modified or unsupported feature"));
1127     ske->status = SILC_SKE_STATUS_INVALID_COOKIE;
1128     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1129     return SILC_FSM_CONTINUE;
1130   }
1131
1132   /* Check version string */
1133   ske->remote_version = silc_memdup(payload->version, payload->version_len);
1134   status = silc_ske_check_version(ske);
1135   if (status != SILC_SKE_STATUS_OK) {
1136     /** Version mismatch */
1137     ske->status = status;
1138     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1139     return SILC_FSM_CONTINUE;
1140   }
1141
1142   /* Free our KE Start Payload context, we don't need it anymore. */
1143   silc_ske_payload_start_free(ske->start_payload);
1144   ske->start_payload = NULL;
1145
1146   /* Take the selected security properties into use while doing
1147      the key exchange.  This is used only while doing the key
1148      exchange. */
1149   ske->prop = prop = silc_calloc(1, sizeof(*prop));
1150   if (!ske->prop)
1151     goto err;
1152   prop->flags = payload->flags;
1153   status = silc_ske_group_get_by_name(payload->ke_grp_list, &group);
1154   if (status != SILC_SKE_STATUS_OK)
1155     goto err;
1156
1157   prop->group = group;
1158   prop->remote_port = remote_port;
1159
1160   if (silc_pkcs_find_algorithm(payload->pkcs_alg_list, NULL) == NULL) {
1161     status = SILC_SKE_STATUS_UNKNOWN_PKCS;
1162     goto err;
1163   }
1164   if (silc_cipher_alloc(payload->enc_alg_list, &prop->cipher) == FALSE) {
1165     status = SILC_SKE_STATUS_UNKNOWN_CIPHER;
1166     goto err;
1167   }
1168   if (silc_hash_alloc(payload->hash_alg_list, &prop->hash) == FALSE) {
1169     status = SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION;
1170     goto err;
1171   }
1172   if (silc_hmac_alloc(payload->hmac_alg_list, NULL, &prop->hmac) == FALSE) {
1173     status = SILC_SKE_STATUS_UNKNOWN_HMAC;
1174     goto err;
1175   }
1176
1177   /* Save remote's KE Start Payload */
1178   ske->start_payload = payload;
1179
1180   /** Send KE Payload */
1181   silc_fsm_next(fsm, silc_ske_st_initiator_phase2);
1182   return SILC_FSM_CONTINUE;
1183
1184  err:
1185   if (payload)
1186     silc_ske_payload_start_free(payload);
1187   if (group)
1188     silc_ske_group_free(group);
1189   if (prop->cipher)
1190     silc_cipher_free(prop->cipher);
1191   if (prop->hash)
1192     silc_hash_free(prop->hash);
1193   if (prop->hmac)
1194     silc_hmac_free(prop->hmac);
1195   silc_free(prop);
1196   ske->prop = NULL;
1197
1198   if (status == SILC_SKE_STATUS_OK)
1199     status = SILC_SKE_STATUS_ERROR;
1200
1201   /** Error */
1202   ske->status = status;
1203   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1204   return SILC_FSM_CONTINUE;
1205 }
1206
1207 /* Phase-2.  Send KE payload */
1208
1209 SILC_FSM_STATE(silc_ske_st_initiator_phase2)
1210 {
1211   SilcSKE ske = fsm_context;
1212   SilcSKEStatus status;
1213   SilcBuffer payload_buf;
1214   SilcMPInt *x;
1215   SilcSKEKEPayload payload;
1216   SilcUInt32 pk_len;
1217
1218   SILC_LOG_DEBUG(("Start"));
1219
1220   /* Create the random number x, 1 < x < q. */
1221   x = silc_calloc(1, sizeof(*x));
1222   if (!x){
1223     /** Out of memory */
1224     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1225     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1226     return SILC_FSM_CONTINUE;
1227   }
1228   silc_mp_init(x);
1229   status =
1230     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
1231                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
1232                         x);
1233   if (status != SILC_SKE_STATUS_OK) {
1234     /** Error generating random number */
1235     silc_mp_uninit(x);
1236     silc_free(x);
1237     ske->status = status;
1238     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1239     return SILC_FSM_CONTINUE;
1240   }
1241
1242   /* Encode the result to Key Exchange Payload. */
1243
1244   payload = silc_calloc(1, sizeof(*payload));
1245   if (!payload) {
1246     /** Out of memory */
1247     silc_mp_uninit(x);
1248     silc_free(x);
1249     ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1250     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1251     return SILC_FSM_CONTINUE;
1252   }
1253   ske->ke1_payload = payload;
1254
1255   SILC_LOG_DEBUG(("Computing e = g ^ x mod p"));
1256
1257   /* Do the Diffie Hellman computation, e = g ^ x mod p */
1258   silc_mp_init(&payload->x);
1259   silc_mp_pow_mod(&payload->x, &ske->prop->group->generator, x,
1260                   &ske->prop->group->group);
1261
1262   /* Get public key */
1263   payload->pk_data = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
1264   if (!payload->pk_data) {
1265     /** Error encoding public key */
1266     silc_mp_uninit(x);
1267     silc_free(x);
1268     silc_mp_uninit(&payload->x);
1269     silc_free(payload);
1270     ske->ke1_payload = NULL;
1271     ske->status = SILC_SKE_STATUS_ERROR;
1272     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1273     return SILC_FSM_CONTINUE;
1274   }
1275   payload->pk_len = pk_len;
1276   payload->pk_type = silc_pkcs_get_type(ske->public_key);
1277
1278   /* Compute signature data if we are doing mutual authentication */
1279   if (ske->private_key &&
1280       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1281     unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1];
1282     SilcUInt32 hash_len, sign_len;
1283
1284     SILC_LOG_DEBUG(("We are doing mutual authentication"));
1285     SILC_LOG_DEBUG(("Computing HASH_i value"));
1286
1287     /* Compute the hash value */
1288     memset(hash, 0, sizeof(hash));
1289     silc_ske_make_hash(ske, hash, &hash_len, TRUE);
1290
1291     SILC_LOG_DEBUG(("Signing HASH_i value"));
1292
1293     /* Sign the hash value */
1294     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
1295                         sizeof(sign) - 1, &sign_len, NULL)) {
1296       /** Error computing signature */
1297       silc_mp_uninit(x);
1298       silc_free(x);
1299       silc_mp_uninit(&payload->x);
1300       silc_free(payload->pk_data);
1301       silc_free(payload);
1302       ske->ke1_payload = NULL;
1303       ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
1304       silc_fsm_next(fsm, silc_ske_st_initiator_error);
1305       return SILC_FSM_CONTINUE;
1306     }
1307     payload->sign_data = silc_memdup(sign, sign_len);
1308     if (payload->sign_data)
1309       payload->sign_len = sign_len;
1310     memset(sign, 0, sizeof(sign));
1311   }
1312
1313   status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
1314   if (status != SILC_SKE_STATUS_OK) {
1315     /** Error encoding KE payload */
1316     silc_mp_uninit(x);
1317     silc_free(x);
1318     silc_mp_uninit(&payload->x);
1319     silc_free(payload->pk_data);
1320     silc_free(payload->sign_data);
1321     silc_free(payload);
1322     ske->ke1_payload = NULL;
1323     ske->status = status;
1324     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1325     return SILC_FSM_CONTINUE;
1326   }
1327
1328   ske->x = x;
1329
1330   /* Check for backwards compatibility */
1331
1332   /* Send the packet. */
1333   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_1, 0,
1334                             silc_buffer_data(payload_buf),
1335                             silc_buffer_len(payload_buf))) {
1336     /** Error sending packet */
1337     SILC_LOG_DEBUG(("Error sending packet"));
1338     ske->status = SILC_SKE_STATUS_ERROR;
1339     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1340     return SILC_FSM_CONTINUE;
1341   }
1342
1343   silc_buffer_free(payload_buf);
1344
1345   /** Waiting responder's KE payload */
1346   silc_fsm_next(fsm, silc_ske_st_initiator_phase3);
1347   return SILC_FSM_WAIT;
1348 }
1349
1350 /* Phase-3.  Process responder's KE payload */
1351
1352 SILC_FSM_STATE(silc_ske_st_initiator_phase3)
1353 {
1354   SilcSKE ske = fsm_context;
1355   SilcSKEStatus status;
1356   SilcSKEKEPayload payload;
1357   SilcMPInt *KEY;
1358   SilcBuffer packet_buf = &ske->packet->buffer;
1359
1360   SILC_LOG_DEBUG(("Start"));
1361
1362   ske->retry_timer = SILC_SKE_RETRY_MIN;
1363   silc_schedule_task_del_by_context(ske->schedule, ske);
1364
1365   if (ske->aborted) {
1366     /** Aborted */
1367     silc_packet_free(ske->packet);
1368     ske->packet = NULL;
1369     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1370     return SILC_FSM_CONTINUE;
1371   }
1372
1373   /* See if received failure from remote */
1374   if (ske->packet->type == SILC_PACKET_FAILURE) {
1375     silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1376     return SILC_FSM_CONTINUE;
1377   }
1378
1379   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1380     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1381     silc_packet_free(ske->packet);
1382     ske->packet = NULL;
1383     return SILC_FSM_WAIT;
1384   }
1385
1386   /* Decode the payload */
1387   status = silc_ske_payload_ke_decode(ske, packet_buf, &payload);
1388   if (status != SILC_SKE_STATUS_OK) {
1389     /** Error decoding KE payload */
1390     silc_packet_free(ske->packet);
1391     ske->packet = NULL;
1392     ske->status = status;
1393     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1394     return SILC_FSM_CONTINUE;
1395   }
1396   silc_packet_free(ske->packet);
1397   ske->packet = NULL;
1398   ske->ke2_payload = payload;
1399
1400   if (!payload->pk_data && (ske->callbacks->verify_key || ske->repository)) {
1401     SILC_LOG_DEBUG(("Remote end did not send its public key (or certificate), "
1402                     "even though we require it"));
1403     ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1404     goto err;
1405   }
1406
1407   SILC_LOG_DEBUG(("Computing KEY = f ^ x mod p"));
1408
1409   /* Compute the shared secret key */
1410   KEY = silc_calloc(1, sizeof(*KEY));
1411   silc_mp_init(KEY);
1412   silc_mp_pow_mod(KEY, &payload->x, ske->x, &ske->prop->group->group);
1413   ske->KEY = KEY;
1414
1415   /* Decode the remote's public key */
1416   if (payload->pk_data &&
1417       !silc_pkcs_public_key_alloc(payload->pk_type,
1418                                   payload->pk_data, payload->pk_len,
1419                                   &ske->prop->public_key)) {
1420     SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1421     status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1422     goto err;
1423   }
1424
1425   if (ske->prop->public_key && (ske->callbacks->verify_key ||
1426                                 ske->repository)) {
1427     SILC_LOG_DEBUG(("Verifying public key"));
1428
1429     /** Waiting public key verification */
1430     silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1431
1432     /* If repository is provided, verify the key from there. */
1433     if (ske->repository) {
1434       SilcSKRFind find;
1435
1436       find = silc_skr_find_alloc();
1437       if (!find) {
1438         status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1439         goto err;
1440       }
1441       silc_skr_find_set_pkcs_type(find,
1442                                   silc_pkcs_get_type(ske->prop->public_key));
1443       silc_skr_find_set_public_key(find, ske->prop->public_key);
1444       silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
1445
1446       /* Find key from repository */
1447       SILC_FSM_CALL(silc_skr_find(ske->repository, find,
1448                                   silc_ske_skr_callback, ske));
1449     } else {
1450       /* Verify from application */
1451       SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
1452                                                ske->callbacks->context,
1453                                                silc_ske_pk_verified, NULL));
1454     }
1455     /* NOT REACHED */
1456   }
1457
1458   /** Process key material */
1459   silc_fsm_next(fsm, silc_ske_st_initiator_phase4);
1460   return SILC_FSM_CONTINUE;
1461
1462  err:
1463   silc_ske_payload_ke_free(payload);
1464   ske->ke2_payload = NULL;
1465
1466   silc_mp_uninit(ske->KEY);
1467   silc_free(ske->KEY);
1468   ske->KEY = NULL;
1469
1470   if (status == SILC_SKE_STATUS_OK)
1471     return SILC_SKE_STATUS_ERROR;
1472
1473   /** Error */
1474   ske->status = status;
1475   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1476   return SILC_FSM_CONTINUE;
1477 }
1478
1479 /* Process key material */
1480
1481 SILC_FSM_STATE(silc_ske_st_initiator_phase4)
1482 {
1483   SilcSKE ske = fsm_context;
1484   SilcSKEStatus status;
1485   SilcSKEKEPayload payload;
1486   unsigned char hash[SILC_HASH_MAXLEN];
1487   SilcUInt32 hash_len;
1488   int key_len, block_len;
1489
1490   if (ske->aborted) {
1491     /** Aborted */
1492     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1493     return SILC_FSM_CONTINUE;
1494   }
1495
1496   /* Check result of public key verification */
1497   if (ske->status != SILC_SKE_STATUS_OK) {
1498     /** Public key not verified */
1499     SILC_LOG_DEBUG(("Public key verification failed"));
1500     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1501     return SILC_FSM_CONTINUE;
1502   }
1503
1504   payload = ske->ke2_payload;
1505
1506   if (ske->prop->public_key) {
1507     SILC_LOG_DEBUG(("Public key is authentic"));
1508
1509     /* Compute the hash value */
1510     status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
1511     if (status != SILC_SKE_STATUS_OK)
1512       goto err;
1513
1514     SILC_LOG_DEBUG(("Verifying signature (HASH)"));
1515
1516     /* Verify signature */
1517     if (!silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
1518                           payload->sign_len, hash, hash_len, NULL)) {
1519       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
1520       status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
1521       goto err;
1522     }
1523
1524     SILC_LOG_DEBUG(("Signature is Ok"));
1525
1526     ske->hash = silc_memdup(hash, hash_len);
1527     ske->hash_len = hash_len;
1528     memset(hash, 'F', hash_len);
1529   }
1530
1531   ske->status = SILC_SKE_STATUS_OK;
1532
1533   /* Process key material */
1534   key_len = silc_cipher_get_key_len(ske->prop->cipher);
1535   block_len = silc_cipher_get_key_len(ske->prop->cipher);
1536   hash_len = silc_hash_len(ske->prop->hash);
1537   ske->keymat = silc_ske_process_key_material(ske, block_len,
1538                                               key_len, hash_len);
1539   if (!ske->keymat) {
1540     SILC_LOG_ERROR(("Error processing key material"));
1541     status = SILC_SKE_STATUS_ERROR;
1542     goto err;
1543   }
1544
1545   /* Send SUCCESS packet */
1546   SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
1547   if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
1548     /** Error sending packet */
1549     SILC_LOG_DEBUG(("Error sending packet"));
1550     ske->status = SILC_SKE_STATUS_ERROR;
1551     silc_fsm_next(fsm, silc_ske_st_initiator_error);
1552     return SILC_FSM_CONTINUE;
1553   }
1554
1555   /** Waiting completion */
1556   silc_fsm_next(fsm, silc_ske_st_initiator_end);
1557   return SILC_FSM_WAIT;
1558
1559  err:
1560   memset(hash, 'F', sizeof(hash));
1561   silc_ske_payload_ke_free(payload);
1562   ske->ke2_payload = NULL;
1563
1564   silc_mp_uninit(ske->KEY);
1565   silc_free(ske->KEY);
1566   ske->KEY = NULL;
1567
1568   if (ske->hash) {
1569     memset(ske->hash, 'F', hash_len);
1570     silc_free(ske->hash);
1571     ske->hash = NULL;
1572   }
1573
1574   if (status == SILC_SKE_STATUS_OK)
1575     status = SILC_SKE_STATUS_ERROR;
1576
1577   /** Error */
1578   ske->status = status;
1579   silc_fsm_next(fsm, silc_ske_st_initiator_error);
1580   return SILC_FSM_CONTINUE;
1581 }
1582
1583 /* Protocol completed */
1584
1585 SILC_FSM_STATE(silc_ske_st_initiator_end)
1586 {
1587   SilcSKE ske = fsm_context;
1588
1589   SILC_LOG_DEBUG(("Start"));
1590
1591   ske->retry_timer = SILC_SKE_RETRY_MIN;
1592   silc_schedule_task_del_by_context(ske->schedule, ske);
1593
1594   if (ske->aborted) {
1595     /** Aborted */
1596     silc_fsm_next(fsm, silc_ske_st_initiator_aborted);
1597     return SILC_FSM_CONTINUE;
1598   }
1599
1600   /* See if received failure from remote */
1601   if (ske->packet->type == SILC_PACKET_FAILURE) {
1602     silc_fsm_next(fsm, silc_ske_st_initiator_failure);
1603     return SILC_FSM_CONTINUE;
1604   }
1605
1606   if (ske->packet->type != SILC_PACKET_SUCCESS) {
1607     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1608     silc_packet_free(ske->packet);
1609     ske->packet = NULL;
1610     return SILC_FSM_WAIT;
1611   }
1612
1613   SILC_LOG_DEBUG(("Key exchange completed successfully"));
1614
1615   /* Call the completion callback */
1616   if (ske->callbacks->completed)
1617     ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
1618                               ske->rekey, ske->callbacks->context);
1619
1620   silc_packet_free(ske->packet);
1621   ske->packet = NULL;
1622   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1623   silc_schedule_task_del_by_context(ske->schedule, ske);
1624
1625   return SILC_FSM_FINISH;
1626 }
1627
1628 /* Aborted by application */
1629
1630 SILC_FSM_STATE(silc_ske_st_initiator_aborted)
1631 {
1632   SilcSKE ske = fsm_context;
1633   unsigned char data[4];
1634
1635   SILC_LOG_DEBUG(("Aborted by caller"));
1636
1637   /* Send FAILURE packet */
1638   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, data);
1639   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1640   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1641   silc_schedule_task_del_by_context(ske->schedule, ske);
1642
1643   return SILC_FSM_FINISH;
1644 }
1645
1646 /* Error occurred.  Send error to remote host */
1647
1648 SILC_FSM_STATE(silc_ske_st_initiator_error)
1649 {
1650   SilcSKE ske = fsm_context;
1651   SilcSKEStatus status;
1652   unsigned char data[4];
1653
1654   SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
1655                   silc_ske_map_status(ske->status), ske->status));
1656
1657   status = ske->status;
1658   if (status > SILC_SKE_STATUS_INVALID_COOKIE)
1659     status = SILC_SKE_STATUS_ERROR;
1660
1661   /* Send FAILURE packet */
1662   SILC_PUT32_MSB((SilcUInt32)status, data);
1663   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
1664
1665   /* Call the completion callback */
1666   if (!ske->aborted && ske->callbacks->completed)
1667     ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1668                               ske->callbacks->context);
1669
1670   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1671   silc_schedule_task_del_by_context(ske->schedule, ske);
1672
1673   return SILC_FSM_FINISH;
1674 }
1675
1676 /* Failure received from remote */
1677
1678 SILC_FSM_STATE(silc_ske_st_initiator_failure)
1679 {
1680   SilcSKE ske = fsm_context;
1681   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
1682
1683   SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
1684                   silc_ske_map_status(ske->status), ske->status));
1685
1686   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
1687     SILC_GET32_MSB(error, ske->packet->buffer.data);
1688     ske->status = error;
1689     silc_packet_free(ske->packet);
1690     ske->packet = NULL;
1691   }
1692
1693   /* Call the completion callback */
1694   if (!ske->aborted && ske->callbacks->completed)
1695     ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
1696                               ske->callbacks->context);
1697
1698   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
1699   silc_schedule_task_del_by_context(ske->schedule, ske);
1700
1701   return SILC_FSM_FINISH;
1702 }
1703
1704 /* FSM destructor */
1705
1706 static void silc_ske_initiator_finished(SilcFSM fsm, void *fsm_context,
1707                                         void *destructor_context)
1708 {
1709   SilcSKE ske = fsm_context;
1710
1711   ske->running = FALSE;
1712   if (ske->freed)
1713     silc_ske_free(ske);
1714 }
1715
1716 /* Starts the protocol as initiator */
1717
1718 SilcAsyncOperation
1719 silc_ske_initiator(SilcSKE ske,
1720                    SilcPacketStream stream,
1721                    SilcSKEParams params,
1722                    SilcSKEStartPayload start_payload)
1723 {
1724   SILC_LOG_DEBUG(("Start SKE as initiator"));
1725
1726   if (!ske || !stream || !params || !params->version)
1727     return NULL;
1728
1729   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
1730     return NULL;
1731
1732   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_initiator_finished, ske,
1733                      ske->schedule))
1734     return NULL;
1735
1736   if (params->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
1737     ske->session_port = params->session_port;
1738
1739   /* Generate security properties if not provided */
1740   if (!start_payload) {
1741     start_payload = silc_ske_assemble_security_properties(ske,
1742                                                           params->flags,
1743                                                           params->version);
1744     if (!start_payload)
1745       return NULL;
1746   }
1747
1748   ske->start_payload = start_payload;
1749   ske->version = params->version;
1750   ske->running = TRUE;
1751
1752   /* Link to packet stream to get key exchange packets */
1753   ske->stream = stream;
1754   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
1755                           SILC_PACKET_KEY_EXCHANGE,
1756                           SILC_PACKET_KEY_EXCHANGE_2,
1757                           SILC_PACKET_SUCCESS,
1758                           SILC_PACKET_FAILURE, -1);
1759
1760   /* Start SKE as initiator */
1761   silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
1762
1763   return &ske->op;
1764 }
1765
1766 /******************************** Responder *********************************/
1767
1768 /* Start protocol as responder.  Wait initiator's start payload */
1769
1770 SILC_FSM_STATE(silc_ske_st_responder_start)
1771 {
1772   SilcSKE ske = fsm_context;
1773
1774   SILC_LOG_DEBUG(("Start"));
1775
1776   if (ske->aborted) {
1777     /** Aborted */
1778     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1779     return SILC_FSM_CONTINUE;
1780   }
1781
1782   /* Start timeout */
1783   /* XXX */
1784
1785   /** Wait for initiator */
1786   silc_fsm_next(fsm, silc_ske_st_responder_phase1);
1787   return SILC_FSM_WAIT;
1788 }
1789
1790 /* Decode initiator's start payload.  Select the security properties from
1791    the initiator's start payload and send our reply start payload back. */
1792
1793 SILC_FSM_STATE(silc_ske_st_responder_phase1)
1794 {
1795   SilcSKE ske = fsm_context;
1796   SilcSKEStatus status;
1797   SilcSKEStartPayload remote_payload = NULL;
1798   SilcBuffer packet_buf = &ske->packet->buffer;
1799
1800   SILC_LOG_DEBUG(("Start"));
1801
1802   if (ske->aborted) {
1803     /** Aborted */
1804     silc_packet_free(ske->packet);
1805     ske->packet = NULL;
1806     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1807     return SILC_FSM_CONTINUE;
1808   }
1809
1810   /* See if received failure from remote */
1811   if (ske->packet->type == SILC_PACKET_FAILURE) {
1812     silc_fsm_next(fsm, silc_ske_st_responder_failure);
1813     return SILC_FSM_CONTINUE;
1814   }
1815
1816   /* Decode the payload */
1817   status = silc_ske_payload_start_decode(ske, packet_buf, &remote_payload);
1818   if (status != SILC_SKE_STATUS_OK) {
1819     /** Error decoding Start Payload */
1820     silc_packet_free(ske->packet);
1821     ske->packet = NULL;
1822     ske->status = status;
1823     silc_fsm_next(fsm, silc_ske_st_responder_error);
1824     return SILC_FSM_CONTINUE;
1825   }
1826
1827   /* Take a copy of the payload buffer for future use. It is used to
1828      compute the HASH value. */
1829   ske->start_payload_copy = silc_buffer_copy(packet_buf);
1830
1831   silc_packet_free(ske->packet);
1832   ske->packet = NULL;
1833
1834   /* Force the mutual authentication flag if we want to do it. */
1835   if (ske->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1836     SILC_LOG_DEBUG(("Force mutual authentication"));
1837     remote_payload->flags |= SILC_SKE_SP_FLAG_MUTUAL;
1838   }
1839
1840   /* Force PFS flag if we require it */
1841   if (ske->flags & SILC_SKE_SP_FLAG_PFS) {
1842     SILC_LOG_DEBUG(("Force PFS"));
1843     remote_payload->flags |= SILC_SKE_SP_FLAG_PFS;
1844   }
1845
1846   /* Disable IV Included flag if requested */
1847   if (remote_payload->flags & SILC_SKE_SP_FLAG_IV_INCLUDED &&
1848       !(ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)) {
1849     SILC_LOG_DEBUG(("We do not support IV Included flag"));
1850     remote_payload->flags &= ~SILC_SKE_SP_FLAG_IV_INCLUDED;
1851   }
1852
1853   /* Check and select security properties */
1854   status = silc_ske_select_security_properties(ske, remote_payload,
1855                                                &ske->prop);
1856   if (status != SILC_SKE_STATUS_OK) {
1857     /** Error selecting proposal */
1858     silc_ske_payload_start_free(remote_payload);
1859     ske->status = status;
1860     silc_fsm_next(fsm, silc_ske_st_responder_error);
1861     return SILC_FSM_CONTINUE;
1862   }
1863
1864   silc_ske_payload_start_free(remote_payload);
1865
1866   /* Encode our reply payload to send the selected security properties */
1867   status = silc_ske_payload_start_encode(ske, ske->start_payload,
1868                                          &packet_buf);
1869   if (status != SILC_SKE_STATUS_OK)
1870     goto err;
1871
1872   /* Send the packet. */
1873   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE, 0,
1874                             silc_buffer_data(packet_buf),
1875                             silc_buffer_len(packet_buf)))
1876     goto err;
1877
1878   silc_buffer_free(packet_buf);
1879
1880   /** Waiting initiator's KE payload */
1881   silc_fsm_next(fsm, silc_ske_st_responder_phase2);
1882   return SILC_FSM_WAIT;
1883
1884  err:
1885   if (ske->prop->group)
1886     silc_ske_group_free(ske->prop->group);
1887   if (ske->prop->cipher)
1888     silc_cipher_free(ske->prop->cipher);
1889   if (ske->prop->hash)
1890     silc_hash_free(ske->prop->hash);
1891   if (ske->prop->hmac)
1892     silc_hmac_free(ske->prop->hmac);
1893   silc_free(ske->prop);
1894   ske->prop = NULL;
1895
1896   if (status == SILC_SKE_STATUS_OK)
1897     status = SILC_SKE_STATUS_ERROR;
1898
1899   /** Error */
1900   ske->status = status;
1901   silc_fsm_next(fsm, silc_ske_st_responder_error);
1902   return SILC_FSM_CONTINUE;
1903 }
1904
1905 /* Phase-2.  Decode initiator's KE payload */
1906
1907 SILC_FSM_STATE(silc_ske_st_responder_phase2)
1908 {
1909   SilcSKE ske = fsm_context;
1910   SilcSKEStatus status;
1911   SilcSKEKEPayload recv_payload;
1912   SilcBuffer packet_buf = &ske->packet->buffer;
1913
1914   SILC_LOG_DEBUG(("Start"));
1915
1916   ske->retry_timer = SILC_SKE_RETRY_MIN;
1917   silc_schedule_task_del_by_context(ske->schedule, ske);
1918
1919   if (ske->aborted) {
1920     /** Aborted */
1921     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
1922     return SILC_FSM_CONTINUE;
1923   }
1924
1925   /* See if received failure from remote */
1926   if (ske->packet->type == SILC_PACKET_FAILURE) {
1927     silc_fsm_next(fsm, silc_ske_st_responder_failure);
1928     return SILC_FSM_CONTINUE;
1929   }
1930
1931   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
1932     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
1933     silc_packet_free(ske->packet);
1934     ske->packet = NULL;
1935     return SILC_FSM_WAIT;
1936   }
1937
1938   /* Decode Key Exchange Payload */
1939   status = silc_ske_payload_ke_decode(ske, packet_buf, &recv_payload);
1940   if (status != SILC_SKE_STATUS_OK) {
1941     /** Error decoding KE payload */
1942     silc_packet_free(ske->packet);
1943     ske->packet = NULL;
1944     ske->status = status;
1945     silc_fsm_next(fsm, silc_ske_st_responder_error);
1946     return SILC_FSM_CONTINUE;
1947   }
1948
1949   ske->ke1_payload = recv_payload;
1950
1951   silc_packet_free(ske->packet);
1952   ske->packet = NULL;
1953
1954   /* Verify the received public key and verify the signature if we are
1955      doing mutual authentication. */
1956   if (ske->start_payload &&
1957       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
1958
1959     SILC_LOG_DEBUG(("We are doing mutual authentication"));
1960
1961     if (!recv_payload->pk_data && (ske->callbacks->verify_key ||
1962                                    ske->repository)) {
1963       /** Public key not provided */
1964       SILC_LOG_ERROR(("Remote end did not send its public key (or "
1965                       "certificate), even though we require it"));
1966       ske->status = SILC_SKE_STATUS_PUBLIC_KEY_NOT_PROVIDED;
1967       silc_fsm_next(fsm, silc_ske_st_responder_error);
1968       return SILC_FSM_CONTINUE;
1969     }
1970
1971     /* Decode the remote's public key */
1972     if (recv_payload->pk_data &&
1973         !silc_pkcs_public_key_alloc(recv_payload->pk_type,
1974                                     recv_payload->pk_data,
1975                                     recv_payload->pk_len,
1976                                     &ske->prop->public_key)) {
1977       /** Error decoding public key */
1978       SILC_LOG_ERROR(("Unsupported/malformed public key received"));
1979       ske->status = SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY;
1980       silc_fsm_next(fsm, silc_ske_st_responder_error);
1981       return SILC_FSM_CONTINUE;
1982     }
1983
1984     if (ske->prop->public_key && (ske->callbacks->verify_key ||
1985                                   ske->repository)) {
1986       SILC_LOG_DEBUG(("Verifying public key"));
1987
1988       /** Waiting public key verification */
1989       silc_fsm_next(fsm, silc_ske_st_responder_phase4);
1990
1991       /* If repository is provided, verify the key from there. */
1992       if (ske->repository) {
1993         SilcSKRFind find;
1994
1995         find = silc_skr_find_alloc();
1996         if (!find) {
1997           ske->status = SILC_SKE_STATUS_OUT_OF_MEMORY;
1998           silc_fsm_next(fsm, silc_ske_st_responder_error);
1999           return SILC_FSM_CONTINUE;
2000         }
2001         silc_skr_find_set_pkcs_type(find,
2002                                     silc_pkcs_get_type(ske->prop->public_key));
2003         silc_skr_find_set_public_key(find, ske->prop->public_key);
2004         silc_skr_find_set_usage(find, SILC_SKR_USAGE_KEY_AGREEMENT);
2005
2006         /* Find key from repository */
2007         SILC_FSM_CALL(silc_skr_find(ske->repository, find,
2008                                     silc_ske_skr_callback, ske));
2009       } else {
2010         /* Verify from application */
2011         SILC_FSM_CALL(ske->callbacks->verify_key(ske, ske->prop->public_key,
2012                                                  ske->callbacks->context,
2013                                                  silc_ske_pk_verified, NULL));
2014       }
2015       /* NOT REACHED */
2016     }
2017   }
2018
2019   /** Generate KE2 payload */
2020   silc_fsm_next(fsm, silc_ske_st_responder_phase4);
2021   return SILC_FSM_CONTINUE;
2022 }
2023
2024 /* Phase-4. Generate KE2 payload */
2025
2026 SILC_FSM_STATE(silc_ske_st_responder_phase4)
2027 {
2028   SilcSKE ske = fsm_context;
2029   SilcSKEStatus status;
2030   SilcSKEKEPayload recv_payload, send_payload;
2031   SilcMPInt *x, *KEY;
2032
2033   if (ske->aborted) {
2034     /** Aborted */
2035     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2036     return SILC_FSM_CONTINUE;
2037   }
2038
2039   /* Check result of public key verification */
2040   if (ske->status != SILC_SKE_STATUS_OK) {
2041     /** Public key not verified */
2042     SILC_LOG_DEBUG(("Public key verification failed"));
2043     silc_fsm_next(fsm, silc_ske_st_initiator_error);
2044     return SILC_FSM_CONTINUE;
2045   }
2046
2047   recv_payload = ske->ke1_payload;
2048
2049   /* The public key verification was performed only if the Mutual
2050      Authentication flag is set. */
2051   if (ske->start_payload &&
2052       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
2053     unsigned char hash[SILC_HASH_MAXLEN];
2054     SilcUInt32 hash_len;
2055
2056     SILC_LOG_DEBUG(("Public key is authentic"));
2057
2058     /* Compute the hash value */
2059     status = silc_ske_make_hash(ske, hash, &hash_len, TRUE);
2060     if (status != SILC_SKE_STATUS_OK) {
2061       /** Error computing hash */
2062       ske->status = status;
2063       silc_fsm_next(fsm, silc_ske_st_responder_error);
2064       return SILC_FSM_CONTINUE;
2065     }
2066
2067     SILC_LOG_DEBUG(("Verifying signature (HASH_i)"));
2068
2069     /* Verify signature */
2070     if (!silc_pkcs_verify(ske->prop->public_key, recv_payload->sign_data,
2071                           recv_payload->sign_len, hash, hash_len, NULL)) {
2072       /** Incorrect signature */
2073       SILC_LOG_ERROR(("Signature verification failed, incorrect signature"));
2074       ske->status = SILC_SKE_STATUS_INCORRECT_SIGNATURE;
2075       silc_fsm_next(fsm, silc_ske_st_responder_error);
2076       return SILC_FSM_CONTINUE;
2077     }
2078
2079     SILC_LOG_DEBUG(("Signature is Ok"));
2080
2081     memset(hash, 'F', hash_len);
2082   }
2083
2084   /* Create the random number x, 1 < x < q. */
2085   x = silc_calloc(1, sizeof(*x));
2086   silc_mp_init(x);
2087   status =
2088     silc_ske_create_rnd(ske, &ske->prop->group->group_order,
2089                         silc_mp_sizeinbase(&ske->prop->group->group_order, 2),
2090                         x);
2091   if (status != SILC_SKE_STATUS_OK) {
2092     /** Error generating random number */
2093     silc_mp_uninit(x);
2094     silc_free(x);
2095     ske->status = status;
2096     silc_fsm_next(fsm, silc_ske_st_responder_error);
2097     return SILC_FSM_CONTINUE;
2098   }
2099
2100   /* Save the results for later processing */
2101   send_payload = silc_calloc(1, sizeof(*send_payload));
2102   ske->x = x;
2103   ske->ke2_payload = send_payload;
2104
2105   SILC_LOG_DEBUG(("Computing f = g ^ x mod p"));
2106
2107   /* Do the Diffie Hellman computation, f = g ^ x mod p */
2108   silc_mp_init(&send_payload->x);
2109   silc_mp_pow_mod(&send_payload->x, &ske->prop->group->generator, x,
2110                   &ske->prop->group->group);
2111
2112   SILC_LOG_DEBUG(("Computing KEY = e ^ x mod p"));
2113
2114   /* Compute the shared secret key */
2115   KEY = silc_calloc(1, sizeof(*KEY));
2116   silc_mp_init(KEY);
2117   silc_mp_pow_mod(KEY, &ske->ke1_payload->x, ske->x,
2118                   &ske->prop->group->group);
2119   ske->KEY = KEY;
2120
2121   /** Send KE2 payload */
2122   silc_fsm_next(fsm, silc_ske_st_responder_phase5);
2123   return SILC_FSM_CONTINUE;
2124 }
2125
2126 /* Phase-5.  Send KE2 payload */
2127
2128 SILC_FSM_STATE(silc_ske_st_responder_phase5)
2129 {
2130   SilcSKE ske = fsm_context;
2131   SilcSKEStatus status;
2132   SilcBuffer payload_buf;
2133   unsigned char hash[SILC_HASH_MAXLEN], sign[2048 + 1], *pk;
2134   SilcUInt32 hash_len, sign_len, pk_len;
2135
2136   SILC_LOG_DEBUG(("Start"));
2137
2138   if (ske->public_key && ske->private_key) {
2139     SILC_LOG_DEBUG(("Getting public key"));
2140
2141     /* Get the public key */
2142     pk = silc_pkcs_public_key_encode(ske->public_key, &pk_len);
2143     if (!pk) {
2144       /** Error encoding public key */
2145       status = SILC_SKE_STATUS_OUT_OF_MEMORY;
2146       silc_fsm_next(fsm, silc_ske_st_responder_error);
2147       return SILC_FSM_CONTINUE;
2148     }
2149     ske->ke2_payload->pk_data = pk;
2150     ske->ke2_payload->pk_len = pk_len;
2151
2152     SILC_LOG_DEBUG(("Computing HASH value"));
2153
2154     /* Compute the hash value */
2155     memset(hash, 0, sizeof(hash));
2156     status = silc_ske_make_hash(ske, hash, &hash_len, FALSE);
2157     if (status != SILC_SKE_STATUS_OK) {
2158       /** Error computing hash */
2159       ske->status = status;
2160       silc_fsm_next(fsm, silc_ske_st_responder_error);
2161       return SILC_FSM_CONTINUE;
2162     }
2163
2164     ske->hash = silc_memdup(hash, hash_len);
2165     ske->hash_len = hash_len;
2166
2167     SILC_LOG_DEBUG(("Signing HASH value"));
2168
2169     /* Sign the hash value */
2170     if (!silc_pkcs_sign(ske->private_key, hash, hash_len, sign,
2171                         sizeof(sign) - 1, &sign_len, NULL)) {
2172       /** Error computing signature */
2173       status = SILC_SKE_STATUS_SIGNATURE_ERROR;
2174       silc_fsm_next(fsm, silc_ske_st_responder_error);
2175       return SILC_FSM_CONTINUE;
2176     }
2177     ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
2178     ske->ke2_payload->sign_len = sign_len;
2179     memset(sign, 0, sizeof(sign));
2180   }
2181   ske->ke2_payload->pk_type = silc_pkcs_get_type(ske->public_key);
2182
2183   /* Encode the Key Exchange Payload */
2184   status = silc_ske_payload_ke_encode(ske, ske->ke2_payload,
2185                                       &payload_buf);
2186   if (status != SILC_SKE_STATUS_OK) {
2187     /** Error encoding KE payload */
2188     ske->status = status;
2189     silc_fsm_next(fsm, silc_ske_st_responder_error);
2190     return SILC_FSM_CONTINUE;
2191   }
2192
2193   /* Send the packet. */
2194   if (!silc_ske_packet_send(ske, SILC_PACKET_KEY_EXCHANGE_2, 0,
2195                             payload_buf->data, silc_buffer_len(payload_buf))) {
2196     SILC_LOG_DEBUG(("Error sending packet"));
2197     ske->status = SILC_SKE_STATUS_ERROR;
2198     silc_fsm_next(fsm, silc_ske_st_responder_error);
2199     return SILC_FSM_CONTINUE;
2200   }
2201
2202   silc_buffer_free(payload_buf);
2203
2204   /** Waiting completion */
2205   silc_fsm_next(fsm, silc_ske_st_responder_end);
2206   return SILC_FSM_WAIT;
2207 }
2208
2209 /* Protocol completed */
2210
2211 SILC_FSM_STATE(silc_ske_st_responder_end)
2212 {
2213   SilcSKE ske = fsm_context;
2214   unsigned char tmp[4];
2215   SilcUInt32 hash_len, key_len, block_len;
2216
2217   ske->retry_timer = SILC_SKE_RETRY_MIN;
2218   silc_schedule_task_del_by_context(ske->schedule, ske);
2219
2220   if (ske->aborted) {
2221     /** Aborted */
2222     silc_fsm_next(fsm, silc_ske_st_responder_aborted);
2223     return SILC_FSM_CONTINUE;
2224   }
2225
2226   /* Check the result of the protocol */
2227   if (ske->packet->type == SILC_PACKET_FAILURE) {
2228     silc_fsm_next(fsm, silc_ske_st_responder_failure);
2229     return SILC_FSM_CONTINUE;
2230   }
2231
2232   if (ske->packet->type != SILC_PACKET_SUCCESS) {
2233     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
2234     silc_packet_free(ske->packet);
2235     ske->packet = NULL;
2236     return SILC_FSM_WAIT;
2237   }
2238   silc_packet_free(ske->packet);
2239   ske->packet = NULL;
2240
2241   /* Process key material */
2242   key_len = silc_cipher_get_key_len(ske->prop->cipher);
2243   block_len = silc_cipher_get_key_len(ske->prop->cipher);
2244   hash_len = silc_hash_len(ske->prop->hash);
2245   ske->keymat = silc_ske_process_key_material(ske, block_len,
2246                                               key_len, hash_len);
2247   if (!ske->keymat) {
2248     /** Error processing key material */
2249     ske->status = SILC_SKE_STATUS_ERROR;
2250     silc_fsm_next(fsm, silc_ske_st_responder_error);
2251     return SILC_FSM_CONTINUE;
2252   }
2253
2254   /* Send SUCCESS packet */
2255   SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
2256   silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
2257
2258   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2259   silc_schedule_task_del_by_context(ske->schedule, ske);
2260
2261   /* Call the completion callback */
2262   if (ske->callbacks->completed)
2263     ske->callbacks->completed(ske, ske->status, ske->prop, ske->keymat,
2264                               ske->rekey, ske->callbacks->context);
2265
2266   return SILC_FSM_FINISH;
2267 }
2268
2269 /* Aborted by application */
2270
2271 SILC_FSM_STATE(silc_ske_st_responder_aborted)
2272 {
2273   SilcSKE ske = fsm_context;
2274   unsigned char tmp[4];
2275
2276   SILC_LOG_DEBUG(("Key exchange protocol aborted"));
2277
2278   /* Send FAILURE packet */
2279   SILC_PUT32_MSB(SILC_SKE_STATUS_ERROR, tmp);
2280   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2281
2282   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2283   silc_schedule_task_del_by_context(ske->schedule, ske);
2284
2285   return SILC_FSM_FINISH;
2286 }
2287
2288 /* Failure received from remote */
2289
2290 SILC_FSM_STATE(silc_ske_st_responder_failure)
2291 {
2292   SilcSKE ske = fsm_context;
2293   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
2294
2295   SILC_LOG_DEBUG(("Key exchange protocol failed"));
2296
2297   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
2298     SILC_GET32_MSB(error, ske->packet->buffer.data);
2299     ske->status = error;
2300     silc_packet_free(ske->packet);
2301     ske->packet = NULL;
2302   }
2303
2304   /* Call the completion callback */
2305   if (!ske->aborted && ske->callbacks->completed)
2306     ske->callbacks->completed(ske, ske->status, NULL, NULL, NULL,
2307                               ske->callbacks->context);
2308
2309   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2310   silc_schedule_task_del_by_context(ske->schedule, ske);
2311
2312   return SILC_FSM_FINISH;
2313 }
2314
2315 /* Error occurred */
2316
2317 SILC_FSM_STATE(silc_ske_st_responder_error)
2318 {
2319   SilcSKE ske = fsm_context;
2320   unsigned char tmp[4];
2321
2322   SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
2323                   ske->status, silc_ske_map_status(ske->status)));
2324
2325   /* Send FAILURE packet */
2326   if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
2327     ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
2328   SILC_PUT32_MSB(ske->status, tmp);
2329   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
2330   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
2331   silc_schedule_task_del_by_context(ske->schedule, ske);
2332
2333   return SILC_FSM_FINISH;
2334 }
2335
2336
2337 static void silc_ske_responder_finished(SilcFSM fsm, void *fsm_context,
2338                                         void *destructor_context)
2339 {
2340   SilcSKE ske = fsm_context;
2341
2342   ske->running = FALSE;
2343   if (ske->freed)
2344     silc_ske_free(ske);
2345 }
2346
2347 /* Starts the protocol as responder. */
2348
2349 SilcAsyncOperation
2350 silc_ske_responder(SilcSKE ske,
2351                    SilcPacketStream stream,
2352                    SilcSKEParams params)
2353 {
2354   SILC_LOG_DEBUG(("Start SKE as responder"));
2355
2356   if (!ske || !stream || !params || !params->version) {
2357     return NULL;
2358   }
2359
2360   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2361     return NULL;
2362
2363   if (!silc_fsm_init(&ske->fsm, ske, silc_ske_responder_finished, ske,
2364                      ske->schedule))
2365     return NULL;
2366
2367   ske->responder = TRUE;
2368   ske->flags = params->flags;
2369   if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
2370     ske->session_port = params->session_port;
2371   ske->version = strdup(params->version);
2372   if (!ske->version)
2373     return NULL;
2374   ske->running = TRUE;
2375
2376   /* Link to packet stream to get key exchange packets */
2377   ske->stream = stream;
2378   silc_packet_stream_link(ske->stream, &silc_ske_stream_cbs, ske, 1000000,
2379                           SILC_PACKET_KEY_EXCHANGE,
2380                           SILC_PACKET_KEY_EXCHANGE_1,
2381                           SILC_PACKET_SUCCESS,
2382                           SILC_PACKET_FAILURE, -1);
2383
2384   /* Start SKE as responder */
2385   silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
2386
2387   return &ske->op;
2388 }
2389
2390 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start);
2391
2392 SILC_FSM_STATE(silc_ske_st_rekey_initiator_start)
2393 {
2394   return SILC_FSM_FINISH;
2395 }
2396
2397 /* Starts rekey protocol as initiator */
2398
2399 SilcAsyncOperation
2400 silc_ske_rekey_initiator(SilcSKE ske,
2401                          SilcPacketStream stream,
2402                          SilcSKERekeyMaterial rekey)
2403 {
2404   SILC_LOG_DEBUG(("Start SKE rekey as initator"));
2405
2406   if (!ske || !stream || !rekey)
2407     return NULL;
2408
2409   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2410     return NULL;
2411
2412   if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2413     return NULL;
2414
2415   ske->rekey = rekey;
2416
2417   /* Link to packet stream to get key exchange packets */
2418   ske->stream = stream;
2419
2420   /* Start SKE rekey as initiator */
2421   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_initiator_start);
2422
2423   return &ske->op;
2424 }
2425
2426 SILC_FSM_STATE(silc_ske_st_rekey_responder_start);
2427
2428 SILC_FSM_STATE(silc_ske_st_rekey_responder_start)
2429 {
2430   return SILC_FSM_FINISH;
2431 }
2432
2433 /* Starts rekey protocol as responder */
2434
2435 SilcAsyncOperation
2436 silc_ske_rekey_responder(SilcSKE ske,
2437                          SilcPacketStream stream,
2438                          SilcBuffer ke_payload,
2439                          SilcSKERekeyMaterial rekey)
2440 {
2441   SILC_LOG_DEBUG(("Start SKE rekey as responder"));
2442
2443   if (!ske || !stream || !rekey)
2444     return NULL;
2445   if (rekey->pfs && !ke_payload)
2446     return NULL;
2447
2448   if (!silc_async_init(&ske->op, silc_ske_abort, NULL, ske))
2449     return NULL;
2450
2451   if (!silc_fsm_init(&ske->fsm, ske, NULL, NULL, ske->schedule))
2452     return NULL;
2453
2454   //  ske->packet_buf = ke_payload;
2455   ske->rekey = rekey;
2456
2457   /* Link to packet stream to get key exchange packets */
2458   ske->stream = stream;
2459
2460   /* Start SKE rekey as responder */
2461   silc_fsm_start(&ske->fsm, silc_ske_st_rekey_responder_start);
2462
2463   return &ske->op;
2464 }
2465
2466 /* Processes the provided key material `data' as the SILC protocol
2467    specification defines. */
2468
2469 SilcSKEKeyMaterial
2470 silc_ske_process_key_material_data(unsigned char *data,
2471                                    SilcUInt32 data_len,
2472                                    SilcUInt32 req_iv_len,
2473                                    SilcUInt32 req_enc_key_len,
2474                                    SilcUInt32 req_hmac_key_len,
2475                                    SilcHash hash)
2476 {
2477   SilcBuffer buf;
2478   unsigned char hashd[SILC_HASH_MAXLEN];
2479   SilcUInt32 hash_len = req_hmac_key_len;
2480   SilcUInt32 enc_key_len = req_enc_key_len / 8;
2481   SilcSKEKeyMaterial key;
2482
2483   SILC_LOG_DEBUG(("Start"));
2484
2485   if (!req_iv_len || !req_enc_key_len || !req_hmac_key_len)
2486     return NULL;
2487
2488   key = silc_calloc(1, sizeof(*key));
2489   if (!key)
2490     return NULL;
2491
2492   buf = silc_buffer_alloc_size(1 + data_len);
2493   if (!buf)
2494     return NULL;
2495   silc_buffer_format(buf,
2496                      SILC_STR_UI_CHAR(0),
2497                      SILC_STR_UI_XNSTRING(data, data_len),
2498                      SILC_STR_END);
2499
2500   /* Take IVs */
2501   memset(hashd, 0, sizeof(hashd));
2502   buf->data[0] = 0;
2503   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2504   key->send_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2505   memcpy(key->send_iv, hashd, req_iv_len);
2506   memset(hashd, 0, sizeof(hashd));
2507   buf->data[0] = 1;
2508   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2509   key->receive_iv = silc_calloc(req_iv_len, sizeof(unsigned char));
2510   memcpy(key->receive_iv, hashd, req_iv_len);
2511   key->iv_len = req_iv_len;
2512
2513   /* Take the encryption keys. If requested key size is more than
2514      the size of hash length we will distribute more key material
2515      as protocol defines. */
2516   buf->data[0] = 2;
2517   if (enc_key_len > hash_len) {
2518     SilcBuffer dist;
2519     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2520         k3[SILC_HASH_MAXLEN];
2521     unsigned char *dtmp;
2522
2523     /* XXX */
2524     if (enc_key_len > (3 * hash_len))
2525       return NULL;
2526
2527     /* Take first round */
2528     memset(k1, 0, sizeof(k1));
2529     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2530
2531     /* Take second round */
2532     dist = silc_buffer_alloc_size(data_len + hash_len);
2533     if (!dist)
2534       return NULL;
2535     silc_buffer_format(dist,
2536                        SILC_STR_UI_XNSTRING(data, data_len),
2537                        SILC_STR_UI_XNSTRING(k1, hash_len),
2538                        SILC_STR_END);
2539     memset(k2, 0, sizeof(k2));
2540     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2541
2542     /* Take third round */
2543     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2544     silc_buffer_pull_tail(dist, hash_len);
2545     silc_buffer_pull(dist, data_len + hash_len);
2546     silc_buffer_format(dist,
2547                        SILC_STR_UI_XNSTRING(k2, hash_len),
2548                        SILC_STR_END);
2549     silc_buffer_push(dist, data_len + hash_len);
2550     memset(k3, 0, sizeof(k3));
2551     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2552
2553     /* Then, save the keys */
2554     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2555     memcpy(dtmp, k1, hash_len);
2556     memcpy(dtmp + hash_len, k2, hash_len);
2557     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2558
2559     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2560     memcpy(key->send_enc_key, dtmp, enc_key_len);
2561     key->enc_key_len = req_enc_key_len;
2562
2563     memset(dtmp, 0, (3 * hash_len));
2564     memset(k1, 0, sizeof(k1));
2565     memset(k2, 0, sizeof(k2));
2566     memset(k3, 0, sizeof(k3));
2567     silc_free(dtmp);
2568     silc_buffer_clear(dist);
2569     silc_buffer_free(dist);
2570   } else {
2571     /* Take normal hash as key */
2572     memset(hashd, 0, sizeof(hashd));
2573     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2574     key->send_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2575     memcpy(key->send_enc_key, hashd, enc_key_len);
2576     key->enc_key_len = req_enc_key_len;
2577   }
2578
2579   buf->data[0] = 3;
2580   if (enc_key_len > hash_len) {
2581     SilcBuffer dist;
2582     unsigned char k1[SILC_HASH_MAXLEN], k2[SILC_HASH_MAXLEN],
2583         k3[SILC_HASH_MAXLEN];
2584     unsigned char *dtmp;
2585
2586     /* XXX */
2587     if (enc_key_len > (3 * hash_len))
2588       return NULL;
2589
2590     /* Take first round */
2591     memset(k1, 0, sizeof(k1));
2592     silc_hash_make(hash, buf->data, silc_buffer_len(buf), k1);
2593
2594     /* Take second round */
2595     dist = silc_buffer_alloc_size(data_len + hash_len);
2596     if (!dist)
2597       return NULL;
2598     silc_buffer_format(dist,
2599                        SILC_STR_UI_XNSTRING(data, data_len),
2600                        SILC_STR_UI_XNSTRING(k1, hash_len),
2601                        SILC_STR_END);
2602     memset(k2, 0, sizeof(k2));
2603     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k2);
2604
2605     /* Take third round */
2606     dist = silc_buffer_realloc(dist, data_len + hash_len + hash_len);
2607     silc_buffer_pull_tail(dist, hash_len);
2608     silc_buffer_pull(dist, data_len + hash_len);
2609     silc_buffer_format(dist,
2610                        SILC_STR_UI_XNSTRING(k2, hash_len),
2611                        SILC_STR_END);
2612     silc_buffer_push(dist, data_len + hash_len);
2613     memset(k3, 0, sizeof(k3));
2614     silc_hash_make(hash, dist->data, silc_buffer_len(dist), k3);
2615
2616     /* Then, save the keys */
2617     dtmp = silc_calloc((3 * hash_len), sizeof(unsigned char));
2618     memcpy(dtmp, k1, hash_len);
2619     memcpy(dtmp + hash_len, k2, hash_len);
2620     memcpy(dtmp + hash_len + hash_len, k3, hash_len);
2621
2622     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2623     memcpy(key->receive_enc_key, dtmp, enc_key_len);
2624     key->enc_key_len = req_enc_key_len;
2625
2626     memset(dtmp, 0, (3 * hash_len));
2627     memset(k1, 0, sizeof(k1));
2628     memset(k2, 0, sizeof(k2));
2629     memset(k3, 0, sizeof(k3));
2630     silc_free(dtmp);
2631     silc_buffer_clear(dist);
2632     silc_buffer_free(dist);
2633   } else {
2634     /* Take normal hash as key */
2635     memset(hashd, 0, sizeof(hashd));
2636     silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2637     key->receive_enc_key = silc_calloc(enc_key_len, sizeof(unsigned char));
2638     memcpy(key->receive_enc_key, hashd, enc_key_len);
2639     key->enc_key_len = req_enc_key_len;
2640   }
2641
2642   /* Take HMAC keys */
2643   memset(hashd, 0, sizeof(hashd));
2644   buf->data[0] = 4;
2645   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2646   key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2647   memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
2648   memset(hashd, 0, sizeof(hashd));
2649   buf->data[0] = 5;
2650   silc_hash_make(hash, buf->data, silc_buffer_len(buf), hashd);
2651   key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
2652   memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
2653   key->hmac_key_len = req_hmac_key_len;
2654   memset(hashd, 0, sizeof(hashd));
2655
2656   silc_buffer_clear(buf);
2657   silc_buffer_free(buf);
2658
2659   return key;
2660 }
2661
2662 /* Processes negotiated key material as protocol specifies. This returns
2663    the actual keys to be used in the SILC. */
2664
2665 SilcSKEKeyMaterial
2666 silc_ske_process_key_material(SilcSKE ske,
2667                               SilcUInt32 req_iv_len,
2668                               SilcUInt32 req_enc_key_len,
2669                               SilcUInt32 req_hmac_key_len)
2670 {
2671   SilcBuffer buf;
2672   unsigned char *tmpbuf;
2673   SilcUInt32 klen;
2674   SilcSKEKeyMaterial key;
2675
2676   /* Encode KEY to binary data */
2677   tmpbuf = silc_mp_mp2bin(ske->KEY, 0, &klen);
2678
2679   buf = silc_buffer_alloc_size(klen + ske->hash_len);
2680   if (!buf)
2681     return NULL;
2682   silc_buffer_format(buf,
2683                      SILC_STR_UI_XNSTRING(tmpbuf, klen),
2684                      SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
2685                      SILC_STR_END);
2686
2687   /* Process the key material */
2688   key = silc_ske_process_key_material_data(buf->data, silc_buffer_len(buf),
2689                                            req_iv_len, req_enc_key_len,
2690                                            req_hmac_key_len,
2691                                            ske->prop->hash);
2692
2693   memset(tmpbuf, 0, klen);
2694   silc_free(tmpbuf);
2695   silc_buffer_clear(buf);
2696   silc_buffer_free(buf);
2697
2698   return key;
2699 }
2700
2701 /* Free key material structure */
2702
2703 void silc_ske_free_key_material(SilcSKEKeyMaterial key)
2704 {
2705   if (!key)
2706     return;
2707
2708   if (key->send_iv)
2709     silc_free(key->send_iv);
2710   if (key->receive_iv)
2711     silc_free(key->receive_iv);
2712   if (key->send_enc_key) {
2713     memset(key->send_enc_key, 0, key->enc_key_len / 8);
2714     silc_free(key->send_enc_key);
2715   }
2716   if (key->receive_enc_key) {
2717     memset(key->receive_enc_key, 0, key->enc_key_len / 8);
2718     silc_free(key->receive_enc_key);
2719   }
2720   if (key->send_hmac_key) {
2721     memset(key->send_hmac_key, 0, key->hmac_key_len);
2722     silc_free(key->send_hmac_key);
2723   }
2724   if (key->receive_hmac_key) {
2725     memset(key->receive_hmac_key, 0, key->hmac_key_len);
2726     silc_free(key->receive_hmac_key);
2727   }
2728   silc_free(key);
2729 }
2730
2731 /* Set keys into use */
2732
2733 SilcBool silc_ske_set_keys(SilcSKE ske,
2734                            SilcSKEKeyMaterial keymat,
2735                            SilcSKESecurityProperties prop,
2736                            SilcCipher *ret_send_key,
2737                            SilcCipher *ret_receive_key,
2738                            SilcHmac *ret_hmac_send,
2739                            SilcHmac *ret_hmac_receive,
2740                            SilcHash *ret_hash)
2741 {
2742   /* Allocate ciphers to be used in the communication */
2743   if (ret_send_key) {
2744     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2745                            ret_send_key))
2746       return FALSE;
2747   }
2748   if (ret_receive_key) {
2749     if (!silc_cipher_alloc((char *)silc_cipher_get_name(prop->cipher),
2750                            ret_receive_key))
2751       return FALSE;
2752   }
2753
2754   /* Allocate HMACs */
2755   if (ret_hmac_send) {
2756     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2757                          ret_hmac_send))
2758       return FALSE;
2759   }
2760   if (ret_hmac_receive) {
2761     if (!silc_hmac_alloc((char *)silc_hmac_get_name(prop->hmac), NULL,
2762                          ret_hmac_receive))
2763       return FALSE;
2764   }
2765
2766   /* Set key material */
2767   if (ske->responder) {
2768     silc_cipher_set_key(*ret_send_key, keymat->receive_enc_key,
2769                         keymat->enc_key_len);
2770     silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
2771     silc_cipher_set_key(*ret_receive_key, keymat->send_enc_key,
2772                         keymat->enc_key_len);
2773     silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
2774     silc_hmac_set_key(*ret_hmac_send, keymat->receive_hmac_key,
2775                       keymat->hmac_key_len);
2776     silc_hmac_set_key(*ret_hmac_receive, keymat->send_hmac_key,
2777                       keymat->hmac_key_len);
2778   } else {
2779     silc_cipher_set_key(*ret_send_key, keymat->send_enc_key,
2780                         keymat->enc_key_len);
2781     silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
2782     silc_cipher_set_key(*ret_receive_key, keymat->receive_enc_key,
2783                         keymat->enc_key_len);
2784     silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
2785     silc_hmac_set_key(*ret_hmac_send, keymat->send_hmac_key,
2786                       keymat->hmac_key_len);
2787     silc_hmac_set_key(*ret_hmac_receive, keymat->receive_hmac_key,
2788                       keymat->hmac_key_len);
2789   }
2790
2791   /* Allocate hash */
2792   if (ret_hash) {
2793     if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
2794       return FALSE;
2795   }
2796
2797   return TRUE;
2798 }
2799
2800 const char *silc_ske_status_string[] =
2801 {
2802   /* Official */
2803   "Ok",
2804   "Unkown error occurred",
2805   "Bad payload in packet",
2806   "Unsupported group",
2807   "Unsupported cipher",
2808   "Unsupported PKCS",
2809   "Unsupported hash function",
2810   "Unsupported HMAC",
2811   "Unsupported public key (or certificate)",
2812   "Incorrect signature",
2813   "Bad or unsupported version",
2814   "Invalid cookie",
2815
2816   /* Other errors */
2817   "Remote did not provide public key",
2818   "Bad reserved field in packet",
2819   "Bad payload length in packet",
2820   "Error computing signature",
2821   "System out of memory",
2822
2823   NULL
2824 };
2825
2826 /* Maps status to readable string and returns the string. If string is not
2827    found and empty character string ("") is returned. */
2828
2829 const char *silc_ske_map_status(SilcSKEStatus status)
2830 {
2831   int i;
2832
2833   for (i = 0; silc_ske_status_string[i]; i++)
2834     if (status == i)
2835       return silc_ske_status_string[i];
2836
2837   return "";
2838 }
2839
2840 /* Parses remote host's version string. */
2841
2842 SilcBool silc_ske_parse_version(SilcSKE ske,
2843                                 SilcUInt32 *protocol_version,
2844                                 char **protocol_version_string,
2845                                 SilcUInt32 *software_version,
2846                                 char **software_version_string,
2847                                 char **vendor_version)
2848 {
2849   return silc_parse_version_string(ske->remote_version,
2850                                    protocol_version,
2851                                    protocol_version_string,
2852                                    software_version,
2853                                    software_version_string,
2854                                    vendor_version);
2855 }
2856
2857 /* Get security properties */
2858
2859 SilcSKESecurityProperties silc_ske_get_security_properties(SilcSKE ske)
2860 {
2861   return ske->prop;
2862 }
2863
2864 /* Get key material */
2865
2866 SilcSKEKeyMaterial silc_ske_get_key_material(SilcSKE ske)
2867 {
2868   return ske->keymat;
2869 }