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 "silcincludes.h"
26 #include "silcclient.h"
27 #include "client_internal.h"
28
29 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth);
30 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange);
31 SILC_TASK_CALLBACK(silc_client_protocol_rekey);
32
33 /*
34  * Key Exhange protocol functions
35  */
36
37 /* Function that is called when SKE protocol sends packets to network. */
38
39 void silc_client_protocol_ke_send_packet(SilcSKE ske,
40                                          SilcBuffer packet,
41                                          SilcPacketType type,
42                                          void *context)
43 {
44   SilcProtocol protocol = (SilcProtocol)context;
45   SilcClientKEInternalContext *ctx = 
46     (SilcClientKEInternalContext *)protocol->context;
47   SilcClient client = (SilcClient)ctx->client;
48
49   /* Send the packet immediately */
50   silc_client_packet_send(client, ske->sock, type, NULL, 0, NULL, NULL,
51                           packet->data, packet->len, TRUE);
52 }
53
54 /* Public key verification callback. Called by the application. */
55
56 typedef struct {
57   SilcSKE ske;
58   SilcSKEVerifyCbCompletion completion;
59   void *completion_context;
60 } *VerifyKeyContext;
61
62 static void silc_client_verify_key_cb(bool success, void *context)
63 {
64   VerifyKeyContext verify = (VerifyKeyContext)context;
65
66   SILC_LOG_DEBUG(("Start"));
67
68   /* Call the completion callback back to the SKE */
69   verify->completion(verify->ske, success ? SILC_SKE_STATUS_OK : 
70                      SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY, 
71                      verify->completion_context);
72
73   silc_free(verify);
74 }
75
76 /* Callback that is called when we have received KE payload from
77    responder. We try to verify the public key now. */
78
79 void silc_client_protocol_ke_verify_key(SilcSKE ske,
80                                         unsigned char *pk_data,
81                                         SilcUInt32 pk_len,
82                                         SilcSKEPKType pk_type,
83                                         void *context,
84                                         SilcSKEVerifyCbCompletion completion,
85                                         void *completion_context)
86 {
87   SilcProtocol protocol = (SilcProtocol)context;
88   SilcClientKEInternalContext *ctx = 
89     (SilcClientKEInternalContext *)protocol->context;
90   SilcClient client = (SilcClient)ctx->client;
91   VerifyKeyContext verify;
92
93   SILC_LOG_DEBUG(("Start"));
94
95   verify = silc_calloc(1, sizeof(*verify));
96   verify->ske = ske;
97   verify->completion = completion;
98   verify->completion_context = completion_context;
99
100   /* Verify public key from user. */
101   client->internal->ops->verify_public_key(client, ctx->sock->user_data, 
102                                            ctx->sock->type,
103                                            pk_data, pk_len, pk_type,
104                                            silc_client_verify_key_cb, verify);
105 }
106
107 /* Sets the negotiated key material into use for particular connection. */
108
109 void silc_client_protocol_ke_set_keys(SilcSKE ske,
110                                       SilcSocketConnection sock,
111                                       SilcSKEKeyMaterial *keymat,
112                                       SilcCipher cipher,
113                                       SilcPKCS pkcs,
114                                       SilcHash hash,
115                                       SilcHmac hmac,
116                                       SilcSKEDiffieHellmanGroup group,
117                                       bool is_responder)
118 {
119   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
120
121   SILC_LOG_DEBUG(("Setting new keys into use"));
122
123   /* Allocate cipher to be used in the communication */
124   silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
125   silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
126   silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_send);
127   silc_hmac_alloc((char *)silc_hmac_get_name(hmac), NULL, &conn->hmac_receive);
128
129   if (is_responder == TRUE) {
130     silc_cipher_set_key(conn->send_key, keymat->receive_enc_key, 
131                         keymat->enc_key_len);
132     silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
133     silc_cipher_set_key(conn->receive_key, keymat->send_enc_key, 
134                         keymat->enc_key_len);
135     silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
136     silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key, 
137                       keymat->hmac_key_len);
138     silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key, 
139                       keymat->hmac_key_len);
140   } else {
141     silc_cipher_set_key(conn->send_key, keymat->send_enc_key, 
142                         keymat->enc_key_len);
143     silc_cipher_set_iv(conn->send_key, keymat->send_iv);
144     silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key, 
145                         keymat->enc_key_len);
146     silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
147     silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key, 
148                       keymat->hmac_key_len);
149     silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key, 
150                       keymat->hmac_key_len);
151   }
152
153   /* Rekey stuff */
154   conn->rekey = silc_calloc(1, sizeof(*conn->rekey));
155   conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key, 
156                                           keymat->enc_key_len / 8);
157   conn->rekey->enc_key_len = keymat->enc_key_len / 8;
158
159   if (ske->start_payload->flags & SILC_SKE_SP_FLAG_PFS)
160     conn->rekey->pfs = TRUE;
161   conn->rekey->ske_group = silc_ske_group_get_number(group);
162
163   /* Save the HASH function */
164   silc_hash_alloc(hash->hash->name, &conn->hash);
165 }
166
167 /* Checks the version string of the server. */
168
169 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
170                                      SilcUInt32 len, void *context)
171 {
172   SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
173   SilcClient client = (SilcClient)ske->user_data;
174   SilcSKEStatus status = SILC_SKE_STATUS_OK;
175   char *cp;
176   int maj = 0, min = 0, build = 0, maj2 = 0, min2 = 0, build2 = 0;
177
178   /* Check for initial version string */
179   if (!strstr(version, "SILC-1.0-"))
180     status = SILC_SKE_STATUS_BAD_VERSION;
181
182   /* Check software version */
183
184   cp = version + 9;
185   if (!cp)
186     status = SILC_SKE_STATUS_BAD_VERSION;
187
188   maj = atoi(cp);
189   cp = strchr(cp, '.');
190   if (cp) {
191     min = atoi(cp + 1);
192     cp++;
193   }
194   cp = strchr(cp, '.');
195   if (cp)
196     build = atoi(cp + 1);
197
198   cp = client->internal->silc_client_version + 9;
199   if (!cp)
200     status = SILC_SKE_STATUS_BAD_VERSION;
201
202   maj2 = atoi(cp);
203   cp = strchr(cp, '.');
204   if (cp) {
205     min2 = atoi(cp + 1);
206     cp++;
207   }
208   cp = strchr(cp, '.');
209   if (cp)
210     build2 = atoi(cp + 1);
211
212   if (maj != maj2)
213     status = SILC_SKE_STATUS_BAD_VERSION;
214
215   if (status != SILC_SKE_STATUS_OK)
216     client->internal->ops->say(client, conn, SILC_CLIENT_MESSAGE_AUDIT,
217                                "We don't support server version `%s'", 
218                                version);
219
220   return status;
221 }
222
223 /* Callback that is called by the SKE to indicate that it is safe to
224    continue the execution of the protocol. Is given as argument to the 
225    silc_ske_initiator_finish or silc_ske_responder_phase_2 functions. 
226    This is called due to the fact that the public key verification
227    process is asynchronous and we must not continue the protocl until
228    the public key has been verified and this callback is called. */
229
230 static void silc_client_protocol_ke_continue(SilcSKE ske,
231                                              void *context)
232 {
233   SilcProtocol protocol = (SilcProtocol)context;
234   SilcClientKEInternalContext *ctx = 
235     (SilcClientKEInternalContext *)protocol->context;
236   SilcClient client = (SilcClient)ctx->client;
237   SilcClientConnection conn = ctx->sock->user_data;
238
239   SILC_LOG_DEBUG(("Start"));
240
241   if (ske->status != SILC_SKE_STATUS_OK) {
242     /* Call failure client operation */
243     client->internal->ops->failure(client, conn, protocol, 
244                                    (void *)ske->status);
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       ctx->ske = ske = silc_ske_alloc(client->rng, client);
297
298       silc_ske_set_callbacks(ske, ctx->send_packet, NULL,
299                              ctx->verify,
300                              silc_client_protocol_ke_continue,
301                              silc_ske_check_version, 
302                              context);
303       
304       if (ctx->responder == TRUE) {
305         /* Start the key exchange by processing the received security
306            properties packet from initiator. */
307         status = 
308           silc_ske_responder_start(ske, ctx->rng, ctx->sock,
309                                    client->internal->silc_client_version,
310                                    ctx->packet->buffer, TRUE);
311       } else {
312         SilcSKEStartPayload *start_payload;
313
314         /* Assemble security properties. */
315         silc_ske_assemble_security_properties(
316                                   ske, SILC_SKE_SP_FLAG_MUTUAL, 
317                                   client->internal->silc_client_version,
318                                   &start_payload);
319
320         /* Start the key exchange by sending our security properties
321            to the remote end. */
322         status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
323                                           start_payload);
324       }
325
326       /* Return now if the procedure is pending */
327       if (status == SILC_SKE_STATUS_PENDING)
328         return;
329
330       if (status != SILC_SKE_STATUS_OK) {
331         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
332                           status));
333         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
334                         status));
335
336         protocol->state = SILC_PROTOCOL_STATE_ERROR;
337         silc_protocol_execute(protocol, client->schedule, 0, 0);
338         return;
339       }
340
341       /* Advance protocol state and call the next state if we are responder */
342       protocol->state++;
343       if (ctx->responder == TRUE)
344         silc_protocol_execute(protocol, client->schedule, 0, 100000);
345     }
346     break;
347   case 2:
348     {
349       /* 
350        * Phase 1 
351        */
352       if (ctx->responder == TRUE) {
353         /* Sends the selected security properties to the initiator. */
354         status = silc_ske_responder_phase_1(ctx->ske);
355       } else {
356         /* Call Phase-1 function. This processes the Key Exchange Start
357            paylaod reply we just got from the responder. The callback
358            function will receive the processed payload where we will
359            save it. */
360         status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer);
361       }
362
363       if (status != SILC_SKE_STATUS_OK) {
364         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
365                           status));
366         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
367                         status));
368
369         protocol->state = SILC_PROTOCOL_STATE_ERROR;
370         silc_protocol_execute(protocol, client->schedule, 0, 0);
371         return;
372       }
373
374       /* Advance protocol state and call next state if we are initiator */
375       protocol->state++;
376       if (ctx->responder == FALSE)
377         silc_protocol_execute(protocol, client->schedule, 0, 100000);
378     }
379     break;
380   case 3:
381     {
382       /* 
383        * Phase 2 
384        */
385       if (ctx->responder == TRUE) {
386         /* Process the received Key Exchange 1 Payload packet from
387            the initiator. This also creates our parts of the Diffie
388            Hellman algorithm. The silc_client_protocol_ke_continue will
389            be called after the public key has been verified. */
390         status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
391       } else {
392         /* Call the Phase-2 function. This creates Diffie Hellman
393            key exchange parameters and sends our public part inside
394            Key Exhange 1 Payload to the responder. */
395         status = silc_ske_initiator_phase_2(ctx->ske,
396                                             client->public_key,
397                                             client->private_key,
398                                             SILC_SKE_PK_TYPE_SILC);
399         protocol->state++;
400       }
401
402       /* Return now if the procedure is pending */
403       if (status == SILC_SKE_STATUS_PENDING)
404         return;
405
406       if (status != SILC_SKE_STATUS_OK) {
407         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
408                           status));
409         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
410                         status));
411
412         protocol->state = SILC_PROTOCOL_STATE_ERROR;
413         silc_protocol_execute(protocol, client->schedule, 0, 0);
414         return;
415       }
416     }
417     break;
418   case 4:
419     {
420       /* 
421        * Finish protocol
422        */
423       if (ctx->responder == TRUE) {
424         /* This creates the key exchange material and sends our
425            public parts to the initiator inside Key Exchange 2 Payload. */
426         status = 
427           silc_ske_responder_finish(ctx->ske, 
428                                     client->public_key, client->private_key,
429                                     SILC_SKE_PK_TYPE_SILC);
430
431         /* End the protocol on the next round */
432         protocol->state = SILC_PROTOCOL_STATE_END;
433       } else {
434         /* Finish the protocol. This verifies the Key Exchange 2 payload
435            sent by responder. The silc_client_protocol_ke_continue will
436            be called after the public key has been verified. */
437         status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
438       }
439
440       /* Return now if the procedure is pending */
441       if (status == SILC_SKE_STATUS_PENDING)
442         return;
443
444       if (status != SILC_SKE_STATUS_OK) {
445         if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
446           client->internal->ops->say(
447                              client, conn, SILC_CLIENT_MESSAGE_AUDIT, 
448                              "Received unsupported server %s public key",
449                              ctx->sock->hostname);
450         } else {
451           client->internal->ops->say(
452                            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                                 SilcUInt32 *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                                SilcUInt32 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       SilcUInt32 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->internal->ops->say(
653                         client, conn, SILC_CLIENT_MESSAGE_INFO,
654                         "Password authentication required by server %s",
655                         ctx->sock->hostname);
656         client->internal->ops->ask_passphrase(client, conn,
657                                               silc_client_conn_auth_continue,
658                                               protocol);
659         return;
660         break;
661
662       case SILC_AUTH_PUBLIC_KEY:
663         if (!ctx->auth_data) {
664           /* Public key authentication */
665           silc_client_get_public_key_auth(client, conn, sign, &auth_data_len, 
666                                           ctx->ske);
667           auth_data = sign;
668         } else {
669           auth_data = ctx->auth_data;
670           auth_data_len = ctx->auth_data_len;
671         }
672         
673         break;
674       }
675
676       silc_client_conn_auth_continue(auth_data,
677                                      auth_data_len, protocol);
678     }
679     break;
680
681   case SILC_PROTOCOL_STATE_END:
682     {
683       /* 
684        * End protocol. Nothing special to be done here.
685        */
686
687       /* Protocol has ended, call the final callback */
688       if (protocol->final_callback)
689         silc_protocol_execute_final(protocol, client->schedule);
690       else
691         silc_protocol_free(protocol);
692     }
693     break;
694
695   case SILC_PROTOCOL_STATE_ERROR:
696     {
697       /* 
698        * Error. Send notify to remote.
699        */
700       unsigned char error[4];
701
702       SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
703
704       /* Error in protocol. Send FAILURE packet. Although I don't think
705          this could ever happen on client side. */
706       silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
707                               NULL, 0, NULL, NULL, error, 4, TRUE);
708
709       /* On error the final callback is always called. */
710       if (protocol->final_callback)
711         silc_protocol_execute_final(protocol, client->schedule);
712       else
713         silc_protocol_free(protocol);
714     }
715
716   case SILC_PROTOCOL_STATE_FAILURE:
717     /*
718      * Received failure from remote.
719      */
720
721     /* On error the final callback is always called. */
722     if (protocol->final_callback)
723       silc_protocol_execute_final(protocol, client->schedule);
724     else
725       silc_protocol_free(protocol);
726     break;
727
728   case SILC_PROTOCOL_STATE_UNKNOWN:
729     break;
730   }
731 }
732
733 /*
734  * Re-key protocol routines
735  */
736
737 /* Actually takes the new keys into use. */
738
739 static void 
740 silc_client_protocol_rekey_validate(SilcClient client,
741                                     SilcClientRekeyInternalContext *ctx,
742                                     SilcSocketConnection sock,
743                                     SilcSKEKeyMaterial *keymat,
744                                     bool send)
745 {
746   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
747
748   if (ctx->responder == TRUE) {
749     if (send) {
750       silc_cipher_set_key(conn->send_key, keymat->receive_enc_key, 
751                           keymat->enc_key_len);
752       silc_cipher_set_iv(conn->send_key, keymat->receive_iv);
753       silc_hmac_set_key(conn->hmac_send, keymat->receive_hmac_key, 
754                         keymat->hmac_key_len);
755     } else {
756       silc_cipher_set_key(conn->receive_key, keymat->send_enc_key, 
757                           keymat->enc_key_len);
758       silc_cipher_set_iv(conn->receive_key, keymat->send_iv);
759       silc_hmac_set_key(conn->hmac_receive, keymat->send_hmac_key, 
760                         keymat->hmac_key_len);
761     }
762   } else {
763     if (send) {
764       silc_cipher_set_key(conn->send_key, keymat->send_enc_key, 
765                           keymat->enc_key_len);
766       silc_cipher_set_iv(conn->send_key, keymat->send_iv);
767       silc_hmac_set_key(conn->hmac_send, keymat->send_hmac_key, 
768                         keymat->hmac_key_len);
769     } else {
770       silc_cipher_set_key(conn->receive_key, keymat->receive_enc_key, 
771                           keymat->enc_key_len);
772       silc_cipher_set_iv(conn->receive_key, keymat->receive_iv);
773       silc_hmac_set_key(conn->hmac_receive, keymat->receive_hmac_key, 
774                         keymat->hmac_key_len);
775     }
776   }
777
778   /* Save the current sending encryption key */
779   if (!send) {
780     memset(conn->rekey->send_enc_key, 0, conn->rekey->enc_key_len);
781     silc_free(conn->rekey->send_enc_key);
782     conn->rekey->send_enc_key = silc_memdup(keymat->send_enc_key,
783                                             keymat->enc_key_len / 8);
784     conn->rekey->enc_key_len = keymat->enc_key_len / 8;
785   }
786 }
787
788 /* This function actually re-generates (when not using PFS) the keys and
789    takes them into use. */
790
791 static void 
792 silc_client_protocol_rekey_generate(SilcClient client,
793                                     SilcClientRekeyInternalContext *ctx,
794                                     bool send)
795 {
796   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
797   SilcSKEKeyMaterial *keymat;
798   SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
799   SilcUInt32 hash_len = conn->hash->hash->hash_len;
800
801   SILC_LOG_DEBUG(("Generating new %s session keys (no PFS)",
802                   send ? "sending" : "receiving"));
803
804   /* Generate the new key */
805   keymat = silc_calloc(1, sizeof(*keymat));
806   silc_ske_process_key_material_data(conn->rekey->send_enc_key,
807                                      conn->rekey->enc_key_len,
808                                      16, key_len, hash_len, 
809                                      conn->hash, keymat);
810
811   /* Set the keys into use */
812   silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
813
814   silc_ske_free_key_material(keymat);
815 }
816
817 /* This function actually re-generates (with PFS) the keys and
818    takes them into use. */
819
820 static void 
821 silc_client_protocol_rekey_generate_pfs(SilcClient client,
822                                         SilcClientRekeyInternalContext *ctx,
823                                         bool send)
824 {
825   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
826   SilcSKEKeyMaterial *keymat;
827   SilcUInt32 key_len = silc_cipher_get_key_len(conn->send_key);
828   SilcUInt32 hash_len = conn->hash->hash->hash_len;
829   unsigned char *tmpbuf;
830   SilcUInt32 klen;
831
832   SILC_LOG_DEBUG(("Generating new %s session keys (with PFS)",
833                   send ? "sending" : "receiving"));
834
835   /* Encode KEY to binary data */
836   tmpbuf = silc_mp_mp2bin(ctx->ske->KEY, 0, &klen);
837
838   /* Generate the new key */
839   keymat = silc_calloc(1, sizeof(*keymat));
840   silc_ske_process_key_material_data(tmpbuf, klen, 16, key_len, hash_len, 
841                                      conn->hash, keymat);
842
843   /* Set the keys into use */
844   silc_client_protocol_rekey_validate(client, ctx, ctx->sock, keymat, send);
845
846   memset(tmpbuf, 0, klen);
847   silc_free(tmpbuf);
848   silc_ske_free_key_material(keymat);
849 }
850
851 /* Packet sending callback. This function is provided as packet sending
852    routine to the Key Exchange functions. */
853
854 static void 
855 silc_client_protocol_rekey_send_packet(SilcSKE ske,
856                                        SilcBuffer packet,
857                                        SilcPacketType type,
858                                        void *context)
859 {
860   SilcProtocol protocol = (SilcProtocol)context;
861   SilcClientRekeyInternalContext *ctx = 
862     (SilcClientRekeyInternalContext *)protocol->context;
863   SilcClient client = (SilcClient)ctx->client;
864
865   /* Send the packet immediately */
866   silc_client_packet_send(client, ctx->sock, type, NULL, 0, NULL, NULL,
867                           packet->data, packet->len, FALSE);
868 }
869
870 /* Performs re-key as defined in the SILC protocol specification. */
871
872 SILC_TASK_CALLBACK(silc_client_protocol_rekey)
873 {
874   SilcProtocol protocol = (SilcProtocol)context;
875   SilcClientRekeyInternalContext *ctx = 
876     (SilcClientRekeyInternalContext *)protocol->context;
877   SilcClient client = (SilcClient)ctx->client;
878   SilcClientConnection conn = (SilcClientConnection)ctx->sock->user_data;
879   SilcSKEStatus status;
880
881   SILC_LOG_DEBUG(("Start"));
882
883   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
884     protocol->state = SILC_PROTOCOL_STATE_START;
885
886   SILC_LOG_DEBUG(("State=%d", protocol->state));
887
888   switch(protocol->state) {
889   case SILC_PROTOCOL_STATE_START:
890     {
891       /* 
892        * Start protocol.
893        */
894
895       if (ctx->responder == TRUE) {
896         /*
897          * We are receiving party
898          */
899
900         if (ctx->pfs == TRUE) {
901           /* 
902            * Use Perfect Forward Secrecy, ie. negotiate the key material
903            * using the SKE protocol.
904            */
905
906           if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
907             /* Error in protocol */
908             protocol->state = SILC_PROTOCOL_STATE_ERROR;
909             silc_protocol_execute(protocol, client->schedule, 0, 300000);
910           }
911
912           ctx->ske = silc_ske_alloc(client->rng, client);
913           ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
914           silc_ske_group_get_by_number(conn->rekey->ske_group,
915                                        &ctx->ske->prop->group);
916
917           silc_ske_set_callbacks(ctx->ske, 
918                                  silc_client_protocol_rekey_send_packet,
919                                  NULL,  NULL, NULL, silc_ske_check_version,
920                                  context);
921       
922           status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer);
923           if (status != SILC_SKE_STATUS_OK) {
924             SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
925                               status));
926             
927             protocol->state = SILC_PROTOCOL_STATE_ERROR;
928             silc_protocol_execute(protocol, client->schedule, 0, 300000);
929             return;
930           }
931
932           /* Advance the protocol state */
933           protocol->state++;
934           silc_protocol_execute(protocol, client->schedule, 0, 0);
935         } else {
936           /*
937            * Do normal and simple re-key.
938            */
939
940           /* Send the REKEY_DONE to indicate we will take new keys into use */
941           silc_client_packet_send(client, ctx->sock, 
942                                   SILC_PACKET_REKEY_DONE, 
943                                   NULL, 0, NULL, NULL, NULL, 0, FALSE);
944
945           /* After we send REKEY_DONE we must set the sending encryption
946              key to the new key since all packets after this packet must
947              encrypted with the new key. */
948           silc_client_protocol_rekey_generate(client, ctx, TRUE);
949
950           /* The protocol ends in next stage. */
951           protocol->state = SILC_PROTOCOL_STATE_END;
952         }
953       
954       } else {
955         /*
956          * We are the initiator of this protocol
957          */
958
959         /* Start the re-key by sending the REKEY packet */
960         silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY, 
961                                 NULL, 0, NULL, NULL, NULL, 0, FALSE);
962
963         if (ctx->pfs == TRUE) {
964           /* 
965            * Use Perfect Forward Secrecy, ie. negotiate the key material
966            * using the SKE protocol.
967            */
968           ctx->ske = silc_ske_alloc(client->rng, client);
969           ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
970           silc_ske_group_get_by_number(conn->rekey->ske_group,
971                                        &ctx->ske->prop->group);
972
973           silc_ske_set_callbacks(ctx->ske, 
974                                  silc_client_protocol_rekey_send_packet,
975                                  NULL,  NULL, NULL, silc_ske_check_version,
976                                  context);
977       
978           status =  silc_ske_initiator_phase_2(ctx->ske, NULL, NULL, 0);
979           if (status != SILC_SKE_STATUS_OK) {
980             SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
981                               status));
982             
983             protocol->state = SILC_PROTOCOL_STATE_ERROR;
984             silc_protocol_execute(protocol, client->schedule, 0, 300000);
985             return;
986           }
987
988           /* Advance the protocol state */
989           protocol->state++;
990         } else {
991           /*
992            * Do normal and simple re-key.
993            */
994
995           /* Send the REKEY_DONE to indicate we will take new keys into use 
996              now. */ 
997           silc_client_packet_send(client, ctx->sock, 
998                                   SILC_PACKET_REKEY_DONE, 
999                                   NULL, 0, NULL, NULL, NULL, 0, FALSE);
1000
1001           /* After we send REKEY_DONE we must set the sending encryption
1002              key to the new key since all packets after this packet must
1003              encrypted with the new key. */
1004           silc_client_protocol_rekey_generate(client, ctx, TRUE);
1005
1006           /* The protocol ends in next stage. */
1007           protocol->state = SILC_PROTOCOL_STATE_END;
1008         }
1009       }
1010     }
1011     break;
1012
1013   case 2:
1014     /*
1015      * Second state, used only when oding re-key with PFS.
1016      */
1017     if (ctx->responder == TRUE) {
1018       if (ctx->pfs == TRUE) {
1019         /*
1020          * Send our KE packe to the initiator now that we've processed
1021          * the initiator's KE packet.
1022          */
1023         status = silc_ske_responder_finish(ctx->ske, NULL, NULL, 
1024                                            SILC_SKE_PK_TYPE_SILC);
1025
1026           if (status != SILC_SKE_STATUS_OK) {
1027             SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1028                               status));
1029             
1030             protocol->state = SILC_PROTOCOL_STATE_ERROR;
1031             silc_protocol_execute(protocol, client->schedule, 0, 300000);
1032             return;
1033           }
1034       }
1035
1036     } else {
1037       if (ctx->pfs == TRUE) {
1038         /*
1039          * The packet type must be KE packet
1040          */
1041         if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1042           /* Error in protocol */
1043           protocol->state = SILC_PROTOCOL_STATE_ERROR;
1044           silc_protocol_execute(protocol, client->schedule, 0, 300000);
1045         }
1046         
1047         status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer);
1048         if (status != SILC_SKE_STATUS_OK) {
1049           SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1050                             status));
1051           
1052           protocol->state = SILC_PROTOCOL_STATE_ERROR;
1053           silc_protocol_execute(protocol, client->schedule, 0, 300000);
1054           return;
1055         }
1056       }
1057     }
1058
1059     /* Send the REKEY_DONE to indicate we will take new keys into use 
1060        now. */ 
1061     silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE, 
1062                             NULL, 0, NULL, NULL, NULL, 0, FALSE);
1063     
1064     /* After we send REKEY_DONE we must set the sending encryption
1065        key to the new key since all packets after this packet must
1066        encrypted with the new key. */
1067     silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1068
1069     /* The protocol ends in next stage. */
1070     protocol->state = SILC_PROTOCOL_STATE_END;
1071     break;
1072
1073   case SILC_PROTOCOL_STATE_END:
1074     /* 
1075      * End protocol
1076      */
1077
1078     if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1079       /* Error in protocol */
1080       protocol->state = SILC_PROTOCOL_STATE_ERROR;
1081       silc_protocol_execute(protocol, client->schedule, 0, 0);
1082     }
1083
1084     /* We received the REKEY_DONE packet and all packets after this is
1085        encrypted with the new key so set the decryption key to the new key */
1086     silc_client_protocol_rekey_generate(client, ctx, FALSE);
1087
1088     /* Protocol has ended, call the final callback */
1089     if (protocol->final_callback)
1090       silc_protocol_execute_final(protocol, client->schedule);
1091     else
1092       silc_protocol_free(protocol);
1093     break;
1094
1095   case SILC_PROTOCOL_STATE_ERROR:
1096     /*
1097      * Error occured
1098      */
1099
1100     if (ctx->pfs == TRUE) {
1101       /* Send abort notification */
1102       silc_ske_abort(ctx->ske, ctx->ske->status);
1103     }
1104
1105     /* On error the final callback is always called. */
1106     if (protocol->final_callback)
1107       silc_protocol_execute_final(protocol, client->schedule);
1108     else
1109       silc_protocol_free(protocol);
1110     break;
1111
1112   case SILC_PROTOCOL_STATE_FAILURE:
1113     /*
1114      * We have received failure from remote
1115      */
1116
1117     /* On error the final callback is always called. */
1118     if (protocol->final_callback)
1119       silc_protocol_execute_final(protocol, client->schedule);
1120     else
1121       silc_protocol_free(protocol);
1122     break;
1123
1124   case SILC_PROTOCOL_STATE_UNKNOWN:
1125     break;
1126   }
1127
1128 }
1129
1130 /* Registers protocols used in client */
1131
1132 void silc_client_protocols_register(void)
1133 {
1134   silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1135                          silc_client_protocol_connection_auth);
1136   silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1137                          silc_client_protocol_key_exchange);
1138   silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1139                          silc_client_protocol_rekey);
1140 }
1141
1142 /* Unregisters protocols */
1143
1144 void silc_client_protocols_unregister(void)
1145 {
1146   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1147                            silc_client_protocol_connection_auth);
1148   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1149                            silc_client_protocol_key_exchange);
1150   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1151                            silc_client_protocol_rekey);
1152 }