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