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