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