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