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