updates.
[silc.git] / lib / silcclient / protocol.c
1 /*
2
3   protocol.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2001 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; either version 2 of the License, or
12   (at your option) any later version.
13   
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19 */
20 /*
21  * Client side of the protocols.
22  */
23 /* $Id$ */
24
25 #include "clientlibincludes.h"
26 #include "client_internal.h"
27
28 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
29 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
30 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
31
32 /*
33  * Key Exhange protocol functions
34  */
35
36 /* Function that is called when SKE protocol sends packets to network. */
37
38 void silc_client_protocol_ke_send_packet(SilcSKE ske,
39                                          SilcBuffer packet,
40                                          SilcPacketType type,
41                                          void *context)
42 {
43   SilcProtocol protocol = (SilcProtocol)context;
44   SilcClientKEInternalContext *ctx = 
45     (SilcClientKEInternalContext *)protocol->context;
46   SilcClient client = (SilcClient)ctx->client;
47
48   /* Send the packet immediately */
49   silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
50                           packet->data, packet->len, TRUE);
51 }
52
53 /* Public key verification callback. Called by the application. */
54
55 typedef struct {
56   SilcSKE ske;
57   SilcSKEVerifyCbCompletion completion;
58   void *completion_context;
59 } *VerifyKeyContext;
60
61 static void silc_client_verify_key_cb(bool success, void *context)
62 {
63   VerifyKeyContext verify = (VerifyKeyContext)context;
64
65   SILC_LOG_DEBUG(("Start"));
66
67   /* Call the completion callback back to the SKE */
68   verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK : 
69                      SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY, 
70                      verify->completion_context);
71
72   silc_free(verify);
73 }
74
75 /* Callback that is called when we have received KE payload from
76    responder. We try to verify the public key now. */
77
78 void silc_client_protocol_ke_verify_key(SilcSKE ske,
79                                         unsigned char *pk_data,
80                                         uint32 pk_len,
81                                         SilcSKEPKType pk_type,
82                                         void *context,
83                                         SilcSKEVerifyCbCompletion completion,
84                                         void *completion_context)
85 {
86   SilcProtocol protocol = (SilcProtocol)context;
87   SilcClientKEInternalContext *ctx = 
88     (SilcClientKEInternalContext *)protocol->context;
89   SilcClient client = (SilcClient)ctx->client;
90   VerifyKeyContext verify;
91
92   SILC_LOG_DEBUG(("Start"));
93
94   verify = silc_calloc(1, sizeof(*verify));
95   verify->ske = ske;
96   verify->completion = completion;
97   verify->completion_context = completion_context;
98
99   /* Verify public key from user. */
100   client->internal->ops->verify_public_key(client, ctx->sock->user_data, 
101                                            ctx->sock->type,
102                                            pk_data, pk_len, pk_type,
103                                            silc_client_verify_key_cb, verify);
104 }
105
106 /* Sets the negotiated key material into use for particular connection. */
107
108 void silc_client_protocol_ke_set_keys(SilcSKE ske,
109                                       SilcSocketConnection sock,
110                                       SilcSKEKeyMaterial *keymat,
111                                       SilcCipher cipher,
112                                       SilcPKCS pkcs,
113                                       SilcHash hash,
114                                       SilcHmac hmac,
115                                       SilcSKEDiffieHellmanGroup group,
116                                       bool is_responder)
117 {
118   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
119
120   SILC_LOG_DEBUG(("Setting new keys into use"));
121
122   /* Allocate cipher to be used in the communication */
123   silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
124   silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
125   silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_send);
126   silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_receive);
127
128   if (is_responder == TRUE) {
129     silc_cipher_set_key(conn->send_key, keymat->receive_enc_key, 
130                         keymat->enc_key_len);
131     silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
132     silc_cipher_set_key(conn->receive_key, keymat->send_enc_key, 
133                         keymat->enc_key_len);
134     silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
135     silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key, 
136                       keymat->hmac_key_len);
137     silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key, 
138                       keymat->hmac_key_len);
139   } else {
140     silc_cipher_set_key(conn->send_key, keymat->send_enc_key, 
141                         keymat->enc_key_len);
142     silc_cipher_set_iv(conn->send_key, keymat->send_iv);
143     silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key, 
144                         keymat->enc_key_len);
145     silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
146     silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key, 
147                       keymat->hmac_key_len);
148     silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key, 
149                       keymat->hmac_key_len);
150   }
151
152   /* Rekey stuff */
153   conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
154   conn->rekey->send_enc_key = 
155     silc_calloc(keymat->enc_key_len / 8,
156                 sizeof(*conn->rekey->send_enc_key));
157   memcpy(conn->rekey->send_enc_key, 
158          keymat->send_enc_key, keymat->enc_key_len / 8);
159   conn->rekey->enc_key_len = keymat->enc_key_len / 8;
160
161   if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
162     conn->rekey->pfs = TRUE;
163   conn->rekey->ske_group = silc_ske_group_get_number(group);
164
165   /* Save the HASH function */
166   silc_hash_alloc(hash->hash->name, &conn->hash);
167 }
168
169 /* Checks the version string of the server. */
170
171 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
172                                      uint32 len, void *context)
173 {
174   SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
175   SilcClient client = (SilcClient)ske->user_data;
176   SilcSKEStatus status = SILC_SKE_STATUS_OK;
177   char *cp;
178   int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
179
180   /* Check for initial version string */
181   if (!strstr(version, "SILC-1.0-"))
182     status = SILC_SKE_STATUS_BAD_VERSION;
183
184   /* Check software version */
185
186   cp = version + 9;
187   if (!cp)
188     status = SILC_SKE_STATUS_BAD_VERSION;
189
190   maj = atoi(cp);
191   cp = strchr(cp, '.');
192   if (cp) {
193     min = atoi(cp + 1);
194     cp++;
195   }
196   cp = strchr(cp, '.');
197   if (cp)
198     build = atoi(cp + 1);
199
200   cp = client->internal->silc_client_version + 9;
201   if (!cp)
202     status = SILC_SKE_STATUS_BAD_VERSION;
203
204   maj2 = atoi(cp);
205   cp = strchr(cp, '.');
206   if (cp) {
207     min2 = atoi(cp + 1);
208     cp++;
209   }
210   cp = strchr(cp, '.');
211   if (cp)
212     build2 = atoi(cp + 1);
213
214   if (maj != maj2)
215     status = SILC_SKE_STATUS_BAD_VERSION;
216
217   /* XXX backward support for 0.6.1 */
218   if (maj == 0 && min == 6 && build < 2)
219     ske->backward_version = 1;
220
221   if (status != SILC_SKE_STATUS_OK)
222     client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
223                                "We don't support server version `%s'", 
224                                version);
225
226   return status;
227 }
228
229 /* Callback that is called by the SKE to indicate that it is safe to
230    continue the execution of the protocol. Is given as argument to the 
231    silc_ske_initiator_finish or silc_ske_responder_phase_2 functions. 
232    This is called due to the fact that the public key verification
233    process is asynchronous and we must not continue the protocl until
234    the public key has been verified and this callback is called. */
235
236 static void silc_client_protocol_ke_continue(SilcSKE ske,
237                                              void *context)
238 {
239   SilcProtocol protocol = (SilcProtocol)context;
240   SilcClientKEInternalContext *ctx = 
241     (SilcClientKEInternalContext *)protocol->context;
242   SilcClient client = (SilcClient)ctx->client;
243   SilcClientConnection conn = ctx->sock->user_data;
244
245   SILC_LOG_DEBUG(("Start"));
246
247   if (ske->status != SILC_SKE_STATUS_OK) {
248     /* Call failure client operation */
249     client->internal->ops->failure(client, conn, protocol, 
250                                    (void *)ske->status);
251     protocol->state = SILC_PROTOCOL_STATE_ERROR;
252     silc_protocol_execute(protocol, client->schedule, 0, 0);
253     return;
254   }
255
256   /* Send Ok to the other end. We will end the protocol as server
257      sends Ok to us when we will take the new keys into use. Do this
258      if we are initiator. This is happens when this callback was sent
259      to silc_ske_initiator_finish function. */
260   if (ctx->responder == FALSE) {
261     silc_ske_end(ctx->ske);
262
263     /* End the protocol on the next round */
264     protocol->state = SILC_PROTOCOL_STATE_END;
265   }
266
267   /* Advance protocol state and call the next state if we are responder. 
268      This happens when this callback was sent to silc_ske_responder_phase_2
269      function. */
270   if (ctx->responder == TRUE) {
271     protocol->state++;
272     silc_protocol_execute(protocol, client->schedule, 0, 100000);
273   }
274 }
275
276 /* Performs key exchange protocol. This is used for both initiator
277    and responder key exchange. This may be called recursively. */
278
279 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
280 {
281   SilcProtocol protocol = (SilcProtocol)context;
282   SilcClientKEInternalContext *ctx = 
283     (SilcClientKEInternalContext *)protocol->context;
284   SilcClient client = (SilcClient)ctx->client;
285   SilcClientConnection conn = ctx->sock->user_data;
286   SilcSKEStatus status = SILC_SKE_STATUS_OK;
287
288   SILC_LOG_DEBUG(("Start"));
289
290   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
291     protocol->state = SILC_PROTOCOL_STATE_START;
292
293   switch(protocol->state) {
294   case SILC_PROTOCOL_STATE_START:
295     {
296       /*
297        * Start Protocol
298        */
299       SilcSKE ske;
300
301       /* Allocate Key Exchange object */
302       ske = silc_ske_alloc();
303       ctx->ske = ske;
304       ske->rng = client->rng;
305       ske->user_data = (void *)client;
306
307       silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
308                              ctx->verify,
309                              silc_client_protocol_ke_continue,
310                              silc_ske_check_version, 
311                              context);
312       
313       if (ctx->responder == TRUE) {
314         /* Start the key exchange by processing the received security
315            properties packet from initiator. */
316         status = 
317           silc_ske_responder_start(ske, ctx->rng, ctx->sock,
318                                    client->internal->silc_client_version,
319                                    ctx->packet->buffer, TRUE);
320       } else {
321         SilcSKEStartPayload *start_payload;
322
323         /* Assemble security properties. */
324         silc_ske_assemble_security_properties(
325                                   ske, SILC_SKE_SP_FLAG_MUTUAL, 
326                                   client->internal->silc_client_version,
327                                   &start_payload);
328
329         /* Start the key exchange by sending our security properties
330            to the remote end. */
331         status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
332                                           start_payload);
333       }
334
335       /* Return now if the procedure is pending */
336       if (status == SILC_SKE_STATUS_PENDING)
337         return;
338
339       if (status != SILC_SKE_STATUS_OK) {
340         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
341                           status));
342         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
343                         status));
344
345         protocol->state = SILC_PROTOCOL_STATE_ERROR;
346         silc_protocol_execute(protocol, client->schedule, 0, 0);
347         return;
348       }
349
350       /* Advance protocol state and call the next state if we are responder */
351       protocol->state++;
352       if (ctx->responder == TRUE)
353         silc_protocol_execute(protocol, client->schedule, 0, 100000);
354     }
355     break;
356   case 2:
357     {
358       /* 
359        * Phase 1 
360        */
361       if (ctx->responder == TRUE) {
362         /* Sends the selected security properties to the initiator. */
363         status = 
364           silc_ske_responder_phase_1(ctx->ske, 
365                                      ctx->ske->start_payload);
366       } else {
367         /* Call Phase-1 function. This processes the Key Exchange Start
368            paylaod reply we just got from the responder. The callback
369            function will receive the processed payload where we will
370            save it. */
371         status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
372       }
373
374       if (status != SILC_SKE_STATUS_OK) {
375         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
376                           status));
377         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
378                         status));
379
380         protocol->state = SILC_PROTOCOL_STATE_ERROR;
381         silc_protocol_execute(protocol, client->schedule, 0, 0);
382         return;
383       }
384
385       /* Advance protocol state and call next state if we are initiator */
386       protocol->state++;
387       if (ctx->responder == FALSE)
388         silc_protocol_execute(protocol, client->schedule, 0, 100000);
389     }
390     break;
391   case 3:
392     {
393       /* 
394        * Phase 2 
395        */
396       if (ctx->responder == TRUE) {
397         /* Process the received Key Exchange 1 Payload packet from
398            the initiator. This also creates our parts of the Diffie
399            Hellman algorithm. The silc_client_protocol_ke_continue will
400            be called after the public key has been verified. */
401         status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
402       } else {
403         /* Call the Phase-2 function. This creates Diffie Hellman
404            key exchange parameters and sends our public part inside
405            Key Exhange 1 Payload to the responder. */
406         status = silc_ske_initiator_phase_2(ctx->ske,
407                                             client->public_key,
408                                             client->private_key);
409         protocol->state++;
410       }
411
412       /* Return now if the procedure is pending */
413       if (status == SILC_SKE_STATUS_PENDING)
414         return;
415
416       if (status != SILC_SKE_STATUS_OK) {
417         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
418                           status));
419         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
420                         status));
421
422         protocol->state = SILC_PROTOCOL_STATE_ERROR;
423         silc_protocol_execute(protocol, client->schedule, 0, 0);
424         return;
425       }
426     }
427     break;
428   case 4:
429     {
430       /* 
431        * Finish protocol
432        */
433       if (ctx->responder == TRUE) {
434         /* This creates the key exchange material and sends our
435            public parts to the initiator inside Key Exchange 2 Payload. */
436         status = 
437           silc_ske_responder_finish(ctx->ske, 
438                                     client->public_key, client->private_key,
439                                     SILC_SKE_PK_TYPE_SILC);
440
441         /* End the protocol on the next round */
442         protocol->state = SILC_PROTOCOL_STATE_END;
443       } else {
444         /* Finish the protocol. This verifies the Key Exchange 2 payload
445            sent by responder. The silc_client_protocol_ke_continue will
446            be called after the public key has been verified. */
447         status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
448       }
449
450       /* Return now if the procedure is pending */
451       if (status == SILC_SKE_STATUS_PENDING)
452         return;
453
454       if (status != SILC_SKE_STATUS_OK) {
455         if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
456           client->internal->ops->say(
457                              client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
458                              "Received unsupported server %s public key",
459                              ctx->sock->hostname);
460         } else {
461           client->internal->ops->say(
462                            client, conn, SILC_CLIENT_MESSAGE_AUDIT,
463                            "Error during key exchange protocol with server %s",
464                            ctx->sock->hostname);
465         }
466         protocol->state = SILC_PROTOCOL_STATE_ERROR;
467         silc_protocol_execute(protocol, client->schedule, 0, 0);
468         return;
469       }
470     }
471     break;
472
473   case SILC_PROTOCOL_STATE_END:
474     {
475       /* 
476        * End protocol
477        */
478       SilcSKEKeyMaterial *keymat;
479       int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
480       int hash_len = ctx->ske->prop->hash->hash->hash_len;
481
482       /* Process the key material */
483       keymat = silc_calloc(1, sizeof(*keymat));
484       status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
485                                              keymat);
486       if (status != SILC_SKE_STATUS_OK) {
487         protocol->state = SILC_PROTOCOL_STATE_ERROR;
488         silc_protocol_execute(protocol, client->schedule, 0, 300000);
489         silc_ske_free_key_material(keymat);
490         return;
491       }
492       ctx->keymat = keymat;
493
494       /* Send Ok to the other end if we are responder. If we are initiator
495          we have sent this already. */
496       if (ctx->responder == TRUE)
497         silc_ske_end(ctx->ske);
498
499       /* Unregister the timeout task since the protocol has ended. 
500          This was the timeout task to be executed if the protocol is
501          not completed fast enough. */
502       if (ctx->timeout_task)
503         silc_schedule_task_del(client->schedule, ctx->timeout_task);
504
505       /* Protocol has ended, call the final callback */
506       if (protocol->final_callback)
507         silc_protocol_execute_final(protocol, client->schedule);
508       else
509         silc_protocol_free(protocol);
510     }
511     break;
512
513   case SILC_PROTOCOL_STATE_ERROR:
514     /*
515      * Error during protocol
516      */
517     
518     /* Send abort notification */
519     silc_ske_abort(ctx->ske, ctx->ske->status);
520
521     /* On error the final callback is always called. */
522     if (protocol->final_callback)
523       silc_protocol_execute_final(protocol, client->schedule);
524     else
525       silc_protocol_free(protocol);
526     break;
527
528   case SILC_PROTOCOL_STATE_FAILURE:
529     /*
530      * Received failure from remote.
531      */
532
533     /* Unregister the timeout task since the protocol has ended. 
534        This was the timeout task to be executed if the protocol is
535        not completed fast enough. */
536     if (ctx->timeout_task)
537       silc_schedule_task_del(client->schedule, ctx->timeout_task);
538
539     /* On error the final callback is always called. */
540     if (protocol->final_callback)
541       silc_protocol_execute_final(protocol, client->schedule);
542     else
543       silc_protocol_free(protocol);
544     break;
545   case SILC_PROTOCOL_STATE_UNKNOWN:
546     break;
547   }
548 }
549
550 /*
551  * Connection Authentication protocol functions
552  */
553
554 static int
555 silc_client_get_public_key_auth(SilcClient client,
556                                 SilcClientConnection conn,
557                                 unsigned char *auth_data,
558                                 uint32 *auth_data_len,
559                                 SilcSKE ske)
560 {
561   int len;
562   SilcPKCS pkcs;
563   SilcBuffer auth;
564
565   /* Use our default key */
566   pkcs = client->pkcs;
567
568   /* Make the authentication data. Protocol says it is HASH plus
569      KE Start Payload. */
570   len = ske->hash_len + ske->start_payload_copy->len;
571   auth = silc_buffer_alloc(len);
572   silc_buffer_pull_tail(auth, len);
573   silc_buffer_format(auth,
574                      SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
575                      SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
576                                           ske->start_payload_copy->len),
577                      SILC_STR_END);
578
579   if (silc_pkcs_sign_with_hash(pkcs, ske->prop->hash, auth->data, 
580                                auth->len, auth_data, auth_data_len)) {
581     silc_buffer_free(auth);
582     return TRUE;
583   }
584
585   silc_buffer_free(auth);
586   return FALSE;
587 }
588
589 /* Continues the connection authentication protocol. This funtion may
590    be called directly or used as SilcAskPassphrase callback. */
591
592 static void 
593 silc_client_conn_auth_continue(unsigned char *auth_data,
594                                uint32 auth_data_len, void *context)
595 {
596   SilcProtocol protocol = (SilcProtocol)context;
597   SilcClientConnAuthInternalContext *ctx = 
598     (SilcClientConnAuthInternalContext *)protocol->context;
599   SilcClient client = (SilcClient)ctx->client;
600   SilcBuffer packet;
601   int payload_len = 0;
602
603   SILC_LOG_DEBUG(("Start"));
604
605   payload_len = 4 + auth_data_len;
606   packet = silc_buffer_alloc(payload_len);
607   silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
608   silc_buffer_format(packet,
609                      SILC_STR_UI_SHORT(payload_len),
610                      SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
611                      SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
612                      SILC_STR_END);
613
614   /* Send the packet to server */
615   silc_client_packet_send(client, ctx->sock,
616                           SILC_PACKET_CONNECTION_AUTH,
617                           NULL, 0, NULL, NULL,
618                           packet->data, packet->len, TRUE);
619   silc_buffer_free(packet);
620       
621   /* Next state is end of protocol */
622   protocol->state = SILC_PROTOCOL_STATE_END;
623 }
624                                                     
625 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
626 {
627   SilcProtocol protocol = (SilcProtocol)context;
628   SilcClientConnAuthInternalContext *ctx = 
629     (SilcClientConnAuthInternalContext *)protocol->context;
630   SilcClient client = (SilcClient)ctx->client;
631   SilcClientConnection conn = ctx->sock->user_data;
632
633   SILC_LOG_DEBUG(("Start"));
634
635   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
636     protocol->state = SILC_PROTOCOL_STATE_START;
637
638   switch(protocol->state) {
639   case SILC_PROTOCOL_STATE_START:
640     {
641       /* 
642        * Start protocol. We send authentication data to the server
643        * to be authenticated.
644        */
645       unsigned char *auth_data = NULL;
646       uint32 auth_data_len = 0;
647       unsigned char sign[1024];
648
649       switch(ctx->auth_meth) {
650       case SILC_AUTH_NONE:
651         /* No authentication required */
652         break;
653
654       case SILC_AUTH_PASSWORD:
655         /* Password authentication */
656         if (ctx->auth_data && ctx->auth_data_len) {
657           auth_data = ctx->auth_data;
658           auth_data_len = ctx->auth_data_len;
659           break;
660         }
661
662         client->internal->ops->say(
663                         client, conn, SILC_CLIENT_MESSAGE_INFO,
664                         "Password authentication required by server %s",
665                         ctx->sock->hostname);
666         client->internal->ops->ask_passphrase(client, conn,
667                                               silc_client_conn_auth_continue,
668                                               protocol);
669         return;
670         break;
671
672       case SILC_AUTH_PUBLIC_KEY:
673         if (!ctx->auth_data) {
674           /* Public key authentication */
675           silc_client_get_public_key_auth(client, conn, sign, &auth_data_len, 
676                                           ctx->ske);
677           auth_data = sign;
678         } else {
679           auth_data = ctx->auth_data;
680           auth_data_len = ctx->auth_data_len;
681         }
682         
683         break;
684       }
685
686       silc_client_conn_auth_continue(auth_data,
687                                      auth_data_len, protocol);
688     }
689     break;
690
691   case SILC_PROTOCOL_STATE_END:
692     {
693       /* 
694        * End protocol. Nothing special to be done here.
695        */
696
697       /* Protocol has ended, call the final callback */
698       if (protocol->final_callback)
699         silc_protocol_execute_final(protocol, client->schedule);
700       else
701         silc_protocol_free(protocol);
702     }
703     break;
704
705   case SILC_PROTOCOL_STATE_ERROR:
706     {
707       /* 
708        * Error. Send notify to remote.
709        */
710       unsigned char error[4];
711
712       SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
713
714       /* Error in protocol. Send FAILURE packet. Although I don't think
715          this could ever happen on client side. */
716       silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
717                               NULL, 0, NULL, NULL, error, 4, TRUE);
718
719       /* On error the final callback is always called. */
720       if (protocol->final_callback)
721         silc_protocol_execute_final(protocol, client->schedule);
722       else
723         silc_protocol_free(protocol);
724     }
725
726   case SILC_PROTOCOL_STATE_FAILURE:
727     /*
728      * Received failure from remote.
729      */
730
731     /* On error the final callback is always called. */
732     if (protocol->final_callback)
733       silc_protocol_execute_final(protocol, client->schedule);
734     else
735       silc_protocol_free(protocol);
736     break;
737
738   case SILC_PROTOCOL_STATE_UNKNOWN:
739     break;
740   }
741 }
742
743 /*
744  * Re-key protocol routines
745  */
746
747 /* Actually takes the new keys into use. */
748
749 static void 
750 silc_client_protocol_rekey_validate(SilcClient client,
751                                     SilcClientRekeyInternalContext *ctx,
752                                     SilcSocketConnection sock,
753                                     SilcSKEKeyMaterial *keymat,
754                                     bool send)
755 {
756   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
757
758   if (ctx->responder == TRUE) {
759     if (send) {
760       silc_cipher_set_key(conn->send_key, keymat->receive_enc_key, 
761                           keymat->enc_key_len);
762       silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
763       silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key, 
764                         keymat->hmac_key_len);
765     } else {
766       silc_cipher_set_key(conn->receive_key, keymat->send_enc_key, 
767                           keymat->enc_key_len);
768       silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
769       silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key, 
770                         keymat->hmac_key_len);
771     }
772   } else {
773     if (send) {
774       silc_cipher_set_key(conn->send_key, keymat->send_enc_key, 
775                           keymat->enc_key_len);
776       silc_cipher_set_iv(conn->send_key, keymat->send_iv);
777       silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key, 
778                         keymat->hmac_key_len);
779     } else {
780       silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key, 
781                           keymat->enc_key_len);
782       silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
783       silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key, 
784                         keymat->hmac_key_len);
785     }
786   }
787
788   /* Save the current sending encryption key */
789   if (!send) {
790     memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
791     silc_free(conn->rekey->send_enc_key);
792     conn->rekey->send_enc_key = 
793       silc_calloc(keymat->enc_key_len / 8,
794                   sizeof(*conn->rekey->send_enc_key));
795     memcpy(conn->rekey->send_enc_key, keymat->send_enc_key, 
796            keymat->enc_key_len / 8);
797     conn->rekey->enc_key_len = keymat->enc_key_len / 8;
798   }
799 }
800
801 /* This function actually re-generates (when not using PFS) the keys and
802    takes them into use. */
803
804 static void 
805 silc_client_protocol_rekey_generate(SilcClient client,
806                                     SilcClientRekeyInternalContext *ctx,
807                                     bool send)
808 {
809   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
810   SilcSKEKeyMaterial *keymat;
811   uint32 key_len = silc_cipher_get_key_len(conn->send_key);
812   uint32 hash_len = conn->hash->hash->hash_len;
813
814   SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
815                   send ? "sending" : "receiving"));
816
817   /* Generate the new key */
818   keymat = silc_calloc(1, sizeof(*keymat));
819   silc_ske_process_key_material_data(conn->rekey->send_enc_key,
820                                      conn->rekey->enc_key_len,
821                                      16, key_len, hash_len, 
822                                      conn->hash, keymat);
823
824   /* Set the keys into use */
825   silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
826
827   silc_ske_free_key_material(keymat);
828 }
829
830 /* This function actually re-generates (with PFS) the keys and
831    takes them into use. */
832
833 static void 
834 silc_client_protocol_rekey_generate_pfs(SilcClient client,
835                                         SilcClientRekeyInternalContext *ctx,
836                                         bool send)
837 {
838   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
839   SilcSKEKeyMaterial *keymat;
840   uint32 key_len = silc_cipher_get_key_len(conn->send_key);
841   uint32 hash_len = conn->hash->hash->hash_len;
842   unsigned char *tmpbuf;
843   uint32 klen;
844
845   SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
846                   send ? "sending" : "receiving"));
847
848   /* Encode KEY to binary data */
849   tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
850
851   /* Generate the new key */
852   keymat = silc_calloc(1, sizeof(*keymat));
853   silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len, 
854                                      conn->hash, keymat);
855
856   /* Set the keys into use */
857   silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
858
859   memset(tmpbuf, 0, klen);
860   silc_free(tmpbuf);
861   silc_ske_free_key_material(keymat);
862 }
863
864 /* Packet sending callback. This function is provided as packet sending
865    routine to the Key Exchange functions. */
866
867 static void 
868 silc_client_protocol_rekey_send_packet(SilcSKE ske,
869                                        SilcBuffer packet,
870                                        SilcPacketType type,
871                                        void *context)
872 {
873   SilcProtocol protocol = (SilcProtocol)context;
874   SilcClientRekeyInternalContext *ctx = 
875     (SilcClientRekeyInternalContext *)protocol->context;
876   SilcClient client = (SilcClient)ctx->client;
877
878   /* Send the packet immediately */
879   silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
880                           packet->data, packet->len, FALSE);
881 }
882
883 /* Performs re-key as defined in the SILC protocol specification. */
884
885 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
886 {
887   SilcProtocol protocol = (SilcProtocol)context;
888   SilcClientRekeyInternalContext *ctx = 
889     (SilcClientRekeyInternalContext *)protocol->context;
890   SilcClient client = (SilcClient)ctx->client;
891   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
892   SilcSKEStatus status;
893
894   SILC_LOG_DEBUG(("Start"));
895
896   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
897     protocol->state = SILC_PROTOCOL_STATE_START;
898
899   SILC_LOG_DEBUG(("State=%d", protocol->state));
900
901   switch(protocol->state) {
902   case SILC_PROTOCOL_STATE_START:
903     {
904       /* 
905        * Start protocol.
906        */
907
908       if (ctx->responder == TRUE) {
909         /*
910          * We are receiving party
911          */
912
913         if (ctx->pfs == TRUE) {
914           /* 
915            * Use Perfect Forward Secrecy, ie. negotiate the key material
916            * using the SKE protocol.
917            */
918
919           if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
920             /* Error in protocol */
921             protocol->state = SILC_PROTOCOL_STATE_ERROR;
922             silc_protocol_execute(protocol, client->schedule, 0, 300000);
923           }
924
925           ctx->ske = silc_ske_alloc();
926           ctx->ske->rng = client->rng;
927           ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
928           silc_ske_group_get_by_number(conn->rekey->ske_group,
929                                        &ctx->ske->prop->group);
930
931           silc_ske_set_callbacks(ctx->ske, 
932                                  silc_client_protocol_rekey_send_packet,
933                                  NULL,  NULL, NULL, silc_ske_check_version,
934                                  context);
935       
936           status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
937           if (status != SILC_SKE_STATUS_OK) {
938             SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
939                               status));
940             
941             protocol->state = SILC_PROTOCOL_STATE_ERROR;
942             silc_protocol_execute(protocol, client->schedule, 0, 300000);
943             return;
944           }
945
946           /* Advance the protocol state */
947           protocol->state++;
948           silc_protocol_execute(protocol, client->schedule, 0, 0);
949         } else {
950           /*
951            * Do normal and simple re-key.
952            */
953
954           /* Send the REKEY_DONE to indicate we will take new keys into use */
955           silc_client_packet_send(client, ctx->sock, 
956                                   SILC_PACKET_REKEY_DONE, 
957                                   NULL, 0, NULL, NULL, NULL, 0, FALSE);
958
959           /* After we send REKEY_DONE we must set the sending encryption
960              key to the new key since all packets after this packet must
961              encrypted with the new key. */
962           silc_client_protocol_rekey_generate(client, ctx, TRUE);
963
964           /* The protocol ends in next stage. */
965           protocol->state = SILC_PROTOCOL_STATE_END;
966         }
967       
968       } else {
969         /*
970          * We are the initiator of this protocol
971          */
972
973         /* Start the re-key by sending the REKEY packet */
974         silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY, 
975                                 NULL, 0, NULL, NULL, NULL, 0, FALSE);
976
977         if (ctx->pfs == TRUE) {
978           /* 
979            * Use Perfect Forward Secrecy, ie. negotiate the key material
980            * using the SKE protocol.
981            */
982           ctx->ske = silc_ske_alloc();
983           ctx->ske->rng = client->rng;
984           ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
985           silc_ske_group_get_by_number(conn->rekey->ske_group,
986                                        &ctx->ske->prop->group);
987
988           silc_ske_set_callbacks(ctx->ske, 
989                                  silc_client_protocol_rekey_send_packet,
990                                  NULL,  NULL, NULL, silc_ske_check_version,
991                                  context);
992       
993           status =  silc_ske_initiator_phase_2(ctx->ske, NULL, NULL);
994           if (status != SILC_SKE_STATUS_OK) {
995             SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
996                               status));
997             
998             protocol->state = SILC_PROTOCOL_STATE_ERROR;
999             silc_protocol_execute(protocol, client->schedule, 0, 300000);
1000             return;
1001           }
1002
1003           /* Advance the protocol state */
1004           protocol->state++;
1005         } else {
1006           /*
1007            * Do normal and simple re-key.
1008            */
1009
1010           /* Send the REKEY_DONE to indicate we will take new keys into use 
1011              now. */ 
1012           silc_client_packet_send(client, ctx->sock, 
1013                                   SILC_PACKET_REKEY_DONE, 
1014                                   NULL, 0, NULL, NULL, NULL, 0, FALSE);
1015
1016           /* After we send REKEY_DONE we must set the sending encryption
1017              key to the new key since all packets after this packet must
1018              encrypted with the new key. */
1019           silc_client_protocol_rekey_generate(client, ctx, TRUE);
1020
1021           /* The protocol ends in next stage. */
1022           protocol->state = SILC_PROTOCOL_STATE_END;
1023         }
1024       }
1025     }
1026     break;
1027
1028   case 2:
1029     /*
1030      * Second state, used only when oding re-key with PFS.
1031      */
1032     if (ctx->responder == TRUE) {
1033       if (ctx->pfs == TRUE) {
1034         /*
1035          * Send our KE packe to the initiator now that we've processed
1036          * the initiator's KE packet.
1037          */
1038         status = silc_ske_responder_finish(ctx->ske, NULL, NULL, 
1039                                            SILC_SKE_PK_TYPE_SILC);
1040
1041           if (status != SILC_SKE_STATUS_OK) {
1042             SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1043                               status));
1044             
1045             protocol->state = SILC_PROTOCOL_STATE_ERROR;
1046             silc_protocol_execute(protocol, client->schedule, 0, 300000);
1047             return;
1048           }
1049       }
1050
1051     } else {
1052       if (ctx->pfs == TRUE) {
1053         /*
1054          * The packet type must be KE packet
1055          */
1056         if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1057           /* Error in protocol */
1058           protocol->state = SILC_PROTOCOL_STATE_ERROR;
1059           silc_protocol_execute(protocol, client->schedule, 0, 300000);
1060         }
1061         
1062         status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1063         if (status != SILC_SKE_STATUS_OK) {
1064           SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1065                             status));
1066           
1067           protocol->state = SILC_PROTOCOL_STATE_ERROR;
1068           silc_protocol_execute(protocol, client->schedule, 0, 300000);
1069           return;
1070         }
1071       }
1072     }
1073
1074     /* Send the REKEY_DONE to indicate we will take new keys into use 
1075        now. */ 
1076     silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE, 
1077                             NULL, 0, NULL, NULL, NULL, 0, FALSE);
1078     
1079     /* After we send REKEY_DONE we must set the sending encryption
1080        key to the new key since all packets after this packet must
1081        encrypted with the new key. */
1082     silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1083
1084     /* The protocol ends in next stage. */
1085     protocol->state = SILC_PROTOCOL_STATE_END;
1086     break;
1087
1088   case SILC_PROTOCOL_STATE_END:
1089     /* 
1090      * End protocol
1091      */
1092
1093     if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1094       /* Error in protocol */
1095       protocol->state = SILC_PROTOCOL_STATE_ERROR;
1096       silc_protocol_execute(protocol, client->schedule, 0, 0);
1097     }
1098
1099     /* We received the REKEY_DONE packet and all packets after this is
1100        encrypted with the new key so set the decryption key to the new key */
1101     silc_client_protocol_rekey_generate(client, ctx, FALSE);
1102
1103     /* Protocol has ended, call the final callback */
1104     if (protocol->final_callback)
1105       silc_protocol_execute_final(protocol, client->schedule);
1106     else
1107       silc_protocol_free(protocol);
1108     break;
1109
1110   case SILC_PROTOCOL_STATE_ERROR:
1111     /*
1112      * Error occured
1113      */
1114
1115     if (ctx->pfs == TRUE) {
1116       /* Send abort notification */
1117       silc_ske_abort(ctx->ske, ctx->ske->status);
1118     }
1119
1120     /* On error the final callback is always called. */
1121     if (protocol->final_callback)
1122       silc_protocol_execute_final(protocol, client->schedule);
1123     else
1124       silc_protocol_free(protocol);
1125     break;
1126
1127   case SILC_PROTOCOL_STATE_FAILURE:
1128     /*
1129      * We have received failure from remote
1130      */
1131
1132     /* On error the final callback is always called. */
1133     if (protocol->final_callback)
1134       silc_protocol_execute_final(protocol, client->schedule);
1135     else
1136       silc_protocol_free(protocol);
1137     break;
1138
1139   case SILC_PROTOCOL_STATE_UNKNOWN:
1140     break;
1141   }
1142
1143 }
1144
1145 /* Registers protocols used in client */
1146
1147 void silc_client_protocols_register(void)
1148 {
1149   silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1150                          silc_client_protocol_connection_auth);
1151   silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1152                          silc_client_protocol_key_exchange);
1153   silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1154                          silc_client_protocol_rekey);
1155 }
1156
1157 /* Unregisters protocols */
1158
1159 void silc_client_protocols_unregister(void)
1160 {
1161   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1162                            silc_client_protocol_connection_auth);
1163   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1164                            silc_client_protocol_key_exchange);
1165   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1166                            silc_client_protocol_rekey);
1167 }