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