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