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