9231f8cf5ac7e3f5f0e7b8f06d6d69f8ce15cdfa
[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     silc_protocol_execute(protocol, client->timeout_queue, 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     silc_protocol_execute(protocol, client->timeout_queue, 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         silc_protocol_execute(protocol, client->timeout_queue, 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         silc_protocol_execute(protocol, client->timeout_queue, 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         silc_protocol_execute(protocol, client->timeout_queue, 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         silc_protocol_execute(protocol, client->timeout_queue, 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         silc_protocol_execute(protocol, client->timeout_queue, 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         silc_protocol_execute(protocol, client->timeout_queue, 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         silc_protocol_execute(protocol, client->timeout_queue, 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         silc_protocol_execute_final(protocol, client->timeout_queue);
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       silc_protocol_execute_final(protocol, client->timeout_queue);
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       silc_protocol_execute_final(protocol, client->timeout_queue);
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         silc_protocol_execute_final(protocol, client->timeout_queue);
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         silc_protocol_execute_final(protocol, client->timeout_queue);
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       silc_protocol_execute_final(protocol, client->timeout_queue);
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             silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
952           }
953
954           ctx->ske = silc_ske_alloc();
955           ctx->ske->rng = client->rng;
956           ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
957           silc_ske_get_group_by_number(conn->rekey->ske_group,
958                                        &ctx->ske->prop->group);
959
960           status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer,
961                                               NULL, NULL, NULL, NULL);
962           if (status != SILC_SKE_STATUS_OK) {
963             SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
964                               status));
965             
966             protocol->state = SILC_PROTOCOL_STATE_ERROR;
967             silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
968             return;
969           }
970
971           /* Advance the protocol state */
972           protocol->state++;
973           silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
974         } else {
975           /*
976            * Do normal and simple re-key.
977            */
978
979           /* Send the REKEY_DONE to indicate we will take new keys into use */
980           silc_client_packet_send(client, ctx->sock, 
981                                   SILC_PACKET_REKEY_DONE, 
982                                   NULL, 0, NULL, NULL, NULL, 0, FALSE);
983
984           /* After we send REKEY_DONE we must set the sending encryption
985              key to the new key since all packets after this packet must
986              encrypted with the new key. */
987           silc_client_protocol_rekey_generate(client, ctx, TRUE);
988
989           /* The protocol ends in next stage. */
990           protocol->state = SILC_PROTOCOL_STATE_END;
991         }
992       
993       } else {
994         /*
995          * We are the initiator of this protocol
996          */
997
998         /* Start the re-key by sending the REKEY packet */
999         silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY, 
1000                                 NULL, 0, NULL, NULL, NULL, 0, FALSE);
1001
1002         if (ctx->pfs == TRUE) {
1003           /* 
1004            * Use Perfect Forward Secrecy, ie. negotiate the key material
1005            * using the SKE protocol.
1006            */
1007           ctx->ske = silc_ske_alloc();
1008           ctx->ske->rng = client->rng;
1009           ctx->ske->prop = silc_calloc(1, sizeof(*ctx->ske->prop));
1010           silc_ske_get_group_by_number(conn->rekey->ske_group,
1011                                        &ctx->ske->prop->group);
1012
1013           status = 
1014             silc_ske_initiator_phase_2(ctx->ske, NULL, NULL,
1015                                        silc_client_protocol_rekey_send_packet,
1016                                        context);
1017
1018           if (status != SILC_SKE_STATUS_OK) {
1019             SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1020                               status));
1021             
1022             protocol->state = SILC_PROTOCOL_STATE_ERROR;
1023             silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1024             return;
1025           }
1026
1027           /* Advance the protocol state */
1028           protocol->state++;
1029         } else {
1030           /*
1031            * Do normal and simple re-key.
1032            */
1033
1034           /* Send the REKEY_DONE to indicate we will take new keys into use 
1035              now. */ 
1036           silc_client_packet_send(client, ctx->sock, 
1037                                   SILC_PACKET_REKEY_DONE, 
1038                                   NULL, 0, NULL, NULL, NULL, 0, FALSE);
1039
1040           /* After we send REKEY_DONE we must set the sending encryption
1041              key to the new key since all packets after this packet must
1042              encrypted with the new key. */
1043           silc_client_protocol_rekey_generate(client, ctx, TRUE);
1044
1045           /* The protocol ends in next stage. */
1046           protocol->state = SILC_PROTOCOL_STATE_END;
1047         }
1048       }
1049     }
1050     break;
1051
1052   case 2:
1053     /*
1054      * Second state, used only when oding re-key with PFS.
1055      */
1056     if (ctx->responder == TRUE) {
1057       if (ctx->pfs == TRUE) {
1058         /*
1059          * Send our KE packe to the initiator now that we've processed
1060          * the initiator's KE packet.
1061          */
1062         status = 
1063           silc_ske_responder_finish(ctx->ske, NULL, NULL, 
1064                                     SILC_SKE_PK_TYPE_SILC,
1065                                     silc_client_protocol_rekey_send_packet,
1066                                     context);
1067
1068           if (status != SILC_SKE_STATUS_OK) {
1069             SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1070                               status));
1071             
1072             protocol->state = SILC_PROTOCOL_STATE_ERROR;
1073             silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1074             return;
1075           }
1076       }
1077
1078     } else {
1079       if (ctx->pfs == TRUE) {
1080         /*
1081          * The packet type must be KE packet
1082          */
1083         if (ctx->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
1084           /* Error in protocol */
1085           protocol->state = SILC_PROTOCOL_STATE_ERROR;
1086           silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1087         }
1088         
1089         status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
1090                                            NULL, NULL, NULL, NULL);
1091         if (status != SILC_SKE_STATUS_OK) {
1092           SILC_LOG_WARNING(("Error (type %d) during Re-key (PFS)",
1093                             status));
1094           
1095           protocol->state = SILC_PROTOCOL_STATE_ERROR;
1096           silc_protocol_execute(protocol, client->timeout_queue, 0, 300000);
1097           return;
1098         }
1099       }
1100     }
1101
1102     /* Send the REKEY_DONE to indicate we will take new keys into use 
1103        now. */ 
1104     silc_client_packet_send(client, ctx->sock, SILC_PACKET_REKEY_DONE, 
1105                             NULL, 0, NULL, NULL, NULL, 0, FALSE);
1106     
1107     /* After we send REKEY_DONE we must set the sending encryption
1108        key to the new key since all packets after this packet must
1109        encrypted with the new key. */
1110     silc_client_protocol_rekey_generate_pfs(client, ctx, TRUE);
1111
1112     /* The protocol ends in next stage. */
1113     protocol->state = SILC_PROTOCOL_STATE_END;
1114     break;
1115
1116   case SILC_PROTOCOL_STATE_END:
1117     /* 
1118      * End protocol
1119      */
1120
1121     if (ctx->packet->type != SILC_PACKET_REKEY_DONE) {
1122       /* Error in protocol */
1123       protocol->state = SILC_PROTOCOL_STATE_ERROR;
1124       silc_protocol_execute(protocol, client->timeout_queue, 0, 0);
1125     }
1126
1127     /* We received the REKEY_DONE packet and all packets after this is
1128        encrypted with the new key so set the decryption key to the new key */
1129     silc_client_protocol_rekey_generate(client, ctx, FALSE);
1130
1131     /* Protocol has ended, call the final callback */
1132     if (protocol->final_callback)
1133       silc_protocol_execute_final(protocol, client->timeout_queue);
1134     else
1135       silc_protocol_free(protocol);
1136     break;
1137
1138   case SILC_PROTOCOL_STATE_ERROR:
1139     /*
1140      * Error occured
1141      */
1142
1143     if (ctx->pfs == TRUE) {
1144       /* Send abort notification */
1145       silc_ske_abort(ctx->ske, ctx->ske->status, 
1146                      silc_client_protocol_ke_send_packet,
1147                      context);
1148     }
1149
1150     /* On error the final callback is always called. */
1151     if (protocol->final_callback)
1152       silc_protocol_execute_final(protocol, client->timeout_queue);
1153     else
1154       silc_protocol_free(protocol);
1155     break;
1156
1157   case SILC_PROTOCOL_STATE_FAILURE:
1158     /*
1159      * We have received failure from remote
1160      */
1161
1162     /* On error the final callback is always called. */
1163     if (protocol->final_callback)
1164       silc_protocol_execute_final(protocol, client->timeout_queue);
1165     else
1166       silc_protocol_free(protocol);
1167     break;
1168
1169   case SILC_PROTOCOL_STATE_UNKNOWN:
1170     break;
1171   }
1172
1173 }
1174
1175 /* Registers protocols used in client */
1176
1177 void silc_client_protocols_register(void)
1178 {
1179   silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1180                          silc_client_protocol_connection_auth);
1181   silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1182                          silc_client_protocol_key_exchange);
1183   silc_protocol_register(SILC_PROTOCOL_CLIENT_REKEY,
1184                          silc_client_protocol_rekey);
1185 }
1186
1187 /* Unregisters protocols */
1188
1189 void silc_client_protocols_unregister(void)
1190 {
1191   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
1192                            silc_client_protocol_connection_auth);
1193   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
1194                            silc_client_protocol_key_exchange);
1195   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_REKEY,
1196                            silc_client_protocol_rekey);
1197 }