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