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