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