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