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