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