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