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