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