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