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
31 extern char *silc_version_string;
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
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                                                  unsigned int 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 {
90   SilcClientConnection conn = (SilcClientConnection)sock->user_data;
91
92   SILC_LOG_DEBUG(("Setting new keys into use"));
93
94   /* Allocate cipher to be used in the communication */
95   silc_cipher_alloc(cipher->cipher->name, &conn->send_key);
96   silc_cipher_alloc(cipher->cipher->name, &conn->receive_key);
97
98   conn->send_key->cipher->set_key(conn->send_key->context, 
99                                  keymat->send_enc_key, 
100                                  keymat->enc_key_len);
101   conn->send_key->set_iv(conn->send_key, keymat->send_iv);
102   conn->receive_key->cipher->set_key(conn->receive_key->context, 
103                                     keymat->receive_enc_key, 
104                                     keymat->enc_key_len);
105   conn->receive_key->set_iv(conn->receive_key, keymat->receive_iv);
106
107   /* Allocate PKCS to be used */
108 #if 0
109   /* XXX Do we ever need to allocate PKCS for the connection??
110      If yes, we need to change KE protocol to get the initiators
111      public key. */
112   silc_pkcs_alloc(pkcs->pkcs->name, &conn->public_Key);
113   silc_pkcs_set_public_key(conn->public_key, ske->ke2_payload->pk_data, 
114                            ske->ke2_payload->pk_len);
115 #endif
116
117   /* Save HMAC key to be used in the communication. */
118   silc_hmac_alloc(hmac->hmac->name, NULL, &conn->hmac);
119   silc_hmac_set_key(conn->hmac, keymat->hmac_key, keymat->hmac_key_len);
120
121   /* Save the HASH function */
122   silc_hash_alloc(hash->hash->name, &conn->hash);
123 }
124
125 /* Checks the version string of the server. */
126
127 SilcSKEStatus silc_ske_check_version(SilcSKE ske, unsigned char *version,
128                                      unsigned int len)
129 {
130   SilcClientConnection conn = (SilcClientConnection)ske->sock->user_data;
131   SilcClient client = (SilcClient)ske->user_data;
132   SilcSKEStatus status = SILC_SKE_STATUS_OK;
133
134   /* Check for initial version string */
135   if (!strstr(version, "SILC-1.0-"))
136     status = SILC_SKE_STATUS_BAD_VERSION;
137
138   /* Check software version */
139
140   if (len < strlen(silc_version_string))
141     status = SILC_SKE_STATUS_BAD_VERSION;
142
143   /* XXX for now there is no other tests due to the abnormal version
144      string that is used */
145
146   if (status != SILC_SKE_STATUS_OK)
147     client->ops->say(client, conn, 
148                      "We don't support server version `%s'", version);
149
150   return status;
151 }
152
153 /* Performs key exchange protocol. This is used for both initiator
154    and responder key exchange. This may be called recursively. */
155
156 SILC_TASK_CALLBACK(silc_client_protocol_key_exchange)
157 {
158   SilcProtocol protocol = (SilcProtocol)context;
159   SilcClientKEInternalContext *ctx = 
160     (SilcClientKEInternalContext *)protocol->context;
161   SilcClient client = (SilcClient)ctx->client;
162   SilcClientConnection conn = ctx->sock->user_data;
163   SilcSKEStatus status = 0;
164
165   SILC_LOG_DEBUG(("Start"));
166
167   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
168     protocol->state = SILC_PROTOCOL_STATE_START;
169
170   switch(protocol->state) {
171   case SILC_PROTOCOL_STATE_START:
172     {
173       /*
174        * Start Protocol
175        */
176       SilcSKE ske;
177
178       /* Allocate Key Exchange object */
179       ske = silc_ske_alloc();
180       ctx->ske = ske;
181       ske->rng = client->rng;
182       ske->user_data = (void *)client;
183       
184       if (ctx->responder == TRUE) {
185         /* Start the key exchange by processing the received security
186            properties packet from initiator. */
187         status = silc_ske_responder_start(ske, ctx->rng, ctx->sock,
188                                           silc_version_string,
189                                           ctx->packet->buffer, TRUE,
190                                           NULL, NULL);
191       } else {
192         SilcSKEStartPayload *start_payload;
193
194         /* Assemble security properties. */
195         silc_ske_assemble_security_properties(ske, SILC_SKE_SP_FLAG_NONE, 
196                                               silc_version_string,
197                                               &start_payload);
198
199         /* Start the key exchange by sending our security properties
200            to the remote end. */
201         status = silc_ske_initiator_start(ske, ctx->rng, ctx->sock,
202                                           start_payload,
203                                           ctx->send_packet,
204                                           context);
205       }
206
207       if (status != SILC_SKE_STATUS_OK) {
208         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
209                           status));
210         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
211                         status));
212
213         protocol->state = SILC_PROTOCOL_STATE_ERROR;
214         protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
215         return;
216       }
217
218       /* Advance protocol state and call the next state if we are responder */
219       protocol->state++;
220       if (ctx->responder == TRUE)
221         protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
222     }
223     break;
224   case 2:
225     {
226       /* 
227        * Phase 1 
228        */
229       if (ctx->responder == TRUE) {
230         /* Sends the selected security properties to the initiator. */
231         status = 
232           silc_ske_responder_phase_1(ctx->ske, 
233                                      ctx->ske->start_payload,
234                                      ctx->send_packet,
235                                      context);
236       } else {
237         /* Call Phase-1 function. This processes the Key Exchange Start
238            paylaod reply we just got from the responder. The callback
239            function will receive the processed payload where we will
240            save it. */
241         status = silc_ske_initiator_phase_1(ctx->ske, ctx->packet->buffer, 
242                                             NULL, NULL);
243       }
244
245       if (status != SILC_SKE_STATUS_OK) {
246         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
247                           status));
248         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
249                         status));
250
251         protocol->state = SILC_PROTOCOL_STATE_ERROR;
252         protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
253         return;
254       }
255
256       /* Advance protocol state and call next state if we are initiator */
257       protocol->state++;
258       if (ctx->responder == FALSE)
259         protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
260     }
261     break;
262   case 3:
263     {
264       /* 
265        * Phase 2 
266        */
267       if (ctx->responder == TRUE) {
268         /* Process the received Key Exchange 1 Payload packet from
269            the initiator. This also creates our parts of the Diffie
270            Hellman algorithm. */
271         status = silc_ske_responder_phase_2(ctx->ske, ctx->packet->buffer, 
272                                             ctx->verify, context, NULL, NULL);
273       } else {
274         /* Call the Phase-2 function. This creates Diffie Hellman
275            key exchange parameters and sends our public part inside
276            Key Exhange 1 Payload to the responder. */
277         status = silc_ske_initiator_phase_2(ctx->ske,
278                                             client->public_key,
279                                             client->private_key,
280                                             ctx->send_packet,
281                                             context);
282       }
283
284       if (status != SILC_SKE_STATUS_OK) {
285         SILC_LOG_WARNING(("Error (type %d) during Key Exchange protocol",
286                           status));
287         SILC_LOG_DEBUG(("Error (type %d) during Key Exchange protocol",
288                         status));
289
290         protocol->state = SILC_PROTOCOL_STATE_ERROR;
291         protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
292         return;
293       }
294
295       /* Advance protocol state and call the next state if we are responder */
296       protocol->state++;
297       if (ctx->responder == TRUE)
298         protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 100000);
299     }
300     break;
301   case 4:
302     {
303       /* 
304        * Finish protocol
305        */
306       if (ctx->responder == TRUE) {
307         /* This creates the key exchange material and sends our
308            public parts to the initiator inside Key Exchange 2 Payload. */
309         status = 
310           silc_ske_responder_finish(ctx->ske, 
311                                     client->public_key, client->private_key,
312                                     SILC_SKE_PK_TYPE_SILC,
313                                     ctx->send_packet,
314                                     context);
315         status = 0;
316       } else {
317         /* Finish the protocol. This verifies the Key Exchange 2 payload
318            sent by responder. */
319         status = silc_ske_initiator_finish(ctx->ske, ctx->packet->buffer,
320                                            ctx->verify, context, NULL, NULL);
321       }
322
323       if (status != SILC_SKE_STATUS_OK) {
324
325         if (status == SILC_SKE_STATUS_UNSUPPORTED_PUBLIC_KEY) {
326           client->ops->say(client, conn, 
327                            "Received unsupported server %s public key",
328                            ctx->sock->hostname);
329         } else {
330           client->ops->say(client, conn,
331                            "Error during key exchange protocol with server %s",
332                            ctx->sock->hostname);
333         }
334         protocol->state = SILC_PROTOCOL_STATE_ERROR;
335         protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 0);
336         return;
337       }
338       
339       /* Send Ok to the other end. We will end the protocol as server
340          sends Ok to us when we will take the new keys into use. */
341       if (ctx->responder == FALSE)
342         silc_ske_end(ctx->ske, ctx->send_packet, context);
343       
344       /* End the protocol on the next round */
345       protocol->state = SILC_PROTOCOL_STATE_END;
346     }
347     break;
348
349   case SILC_PROTOCOL_STATE_END:
350     {
351       /* 
352        * End protocol
353        */
354       SilcSKEKeyMaterial *keymat;
355       int key_len = silc_cipher_get_key_len(ctx->ske->prop->cipher);
356       int hash_len = ctx->ske->prop->hash->hash->hash_len;
357
358       /* Process the key material */
359       keymat = silc_calloc(1, sizeof(*keymat));
360       status = silc_ske_process_key_material(ctx->ske, 16, key_len, hash_len,
361                                              keymat);
362       if (status != SILC_SKE_STATUS_OK) {
363         protocol->state = SILC_PROTOCOL_STATE_ERROR;
364         protocol->execute(client->timeout_queue, 0, protocol, fd, 0, 300000);
365         silc_ske_free_key_material(keymat);
366         return;
367       }
368       ctx->keymat = keymat;
369
370       /* Send Ok to the other end if we are responder. If we are initiator
371          we have sent this already. */
372       if (ctx->responder == TRUE)
373         silc_ske_end(ctx->ske, ctx->send_packet, context);
374
375       /* Unregister the timeout task since the protocol has ended. 
376          This was the timeout task to be executed if the protocol is
377          not completed fast enough. */
378       if (ctx->timeout_task)
379         silc_task_unregister(client->timeout_queue, ctx->timeout_task);
380
381       /* Protocol has ended, call the final callback */
382       if (protocol->final_callback)
383         protocol->execute_final(client->timeout_queue, 0, protocol, fd);
384       else
385         silc_protocol_free(protocol);
386     }
387     break;
388
389   case SILC_PROTOCOL_STATE_ERROR:
390     /*
391      * Error during protocol
392      */
393     
394     /* Send abort notification */
395     silc_ske_abort(ctx->ske, ctx->ske->status, 
396                    ctx->send_packet, context);
397
398     /* On error the final callback is always called. */
399     if (protocol->final_callback)
400       protocol->execute_final(client->timeout_queue, 0, protocol, fd);
401     else
402       silc_protocol_free(protocol);
403     break;
404
405   case SILC_PROTOCOL_STATE_FAILURE:
406     /*
407      * Received failure from remote.
408      */
409
410     /* Unregister the timeout task since the protocol has ended. 
411        This was the timeout task to be executed if the protocol is
412        not completed fast enough. */
413     if (ctx->timeout_task)
414       silc_task_unregister(client->timeout_queue, ctx->timeout_task);
415
416     /* On error the final callback is always called. */
417     if (protocol->final_callback)
418       protocol->execute_final(client->timeout_queue, 0, protocol, fd);
419     else
420       silc_protocol_free(protocol);
421     break;
422   case SILC_PROTOCOL_STATE_UNKNOWN:
423     break;
424   }
425 }
426
427 /*
428  * Connection Authentication protocol functions
429  */
430
431 static int
432 silc_client_get_public_key_auth(SilcClient client,
433                                 char *filepath,
434                                 unsigned char *auth_data,
435                                 unsigned int *auth_data_len,
436                                 SilcSKE ske)
437 {
438   int len;
439   SilcPKCS pkcs;
440   SilcBuffer auth;
441   SilcPublicKey pub_key;
442
443   if (!silc_pkcs_load_public_key(filepath,&pub_key, SILC_PKCS_FILE_PEM))
444     if (!silc_pkcs_load_public_key(filepath, &pub_key, SILC_PKCS_FILE_BIN))
445       return FALSE;
446
447   silc_pkcs_alloc(pub_key->name, &pkcs);
448   if (!silc_pkcs_public_key_set(pkcs, pub_key)) {
449     silc_pkcs_free(pkcs);
450     silc_pkcs_public_key_free(pub_key);
451     return FALSE;
452   }
453
454   /* Make the authentication data. Protocol says it is HASH plus
455      KE Start Payload. */
456   len = ske->hash_len + ske->start_payload_copy->len;
457   auth = silc_buffer_alloc(len);
458   silc_buffer_pull_tail(auth, len);
459   silc_buffer_format(auth,
460                      SILC_STR_UI_XNSTRING(ske->hash, ske->hash_len),
461                      SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
462                                           ske->start_payload_copy->len),
463                      SILC_STR_END);
464
465   if (silc_pkcs_sign(pkcs, auth->data, auth->len, auth_data, auth_data_len)) {
466     silc_pkcs_free(pkcs);
467     silc_buffer_free(auth);
468     silc_pkcs_public_key_free(pub_key);
469     return TRUE;
470   }
471
472   silc_pkcs_free(pkcs);
473   silc_buffer_free(auth);
474   silc_pkcs_public_key_free(pub_key);
475   return FALSE;
476 }
477
478 SILC_TASK_CALLBACK(silc_client_protocol_connection_auth)
479 {
480   SilcProtocol protocol = (SilcProtocol)context;
481   SilcClientConnAuthInternalContext *ctx = 
482     (SilcClientConnAuthInternalContext *)protocol->context;
483   SilcClient client = (SilcClient)ctx->client;
484   SilcClientConnection conn = ctx->sock->user_data;
485
486   SILC_LOG_DEBUG(("Start"));
487
488   if (protocol->state == SILC_PROTOCOL_STATE_UNKNOWN)
489     protocol->state = SILC_PROTOCOL_STATE_START;
490
491   switch(protocol->state) {
492   case SILC_PROTOCOL_STATE_START:
493     {
494       /* 
495        * Start protocol. We send authentication data to the server
496        * to be authenticated.
497        */
498       SilcBuffer packet;
499       int payload_len = 0;
500       unsigned char *auth_data = NULL;
501       unsigned int auth_data_len = 0;
502
503       switch(ctx->auth_meth) {
504       case SILC_AUTH_NONE:
505         /* No authentication required */
506         break;
507
508       case SILC_AUTH_PASSWORD:
509         /* Password authentication */
510         if (ctx->auth_data && ctx->auth_data_len) {
511           auth_data = ctx->auth_data;
512           auth_data_len = ctx->auth_data_len;
513           break;
514         }
515
516         client->ops->say(client, conn, 
517                          "Password authentication required by server %s",
518                          ctx->sock->hostname);
519         auth_data = client->ops->ask_passphrase(client, conn);
520         auth_data_len = strlen(auth_data);
521         break;
522
523       case SILC_AUTH_PUBLIC_KEY:
524         {
525           unsigned char sign[1024];
526
527           /* Public key authentication */
528           silc_client_get_public_key_auth(client, ctx->auth_data,
529                                           sign, &auth_data_len, 
530                                           ctx->ske);
531           auth_data = silc_calloc(auth_data_len, sizeof(*auth_data));
532           memcpy(auth_data, sign, auth_data_len);
533           break;
534         }
535       }
536
537       payload_len = 4 + auth_data_len;
538       packet = silc_buffer_alloc(payload_len);
539       silc_buffer_pull_tail(packet, SILC_BUFFER_END(packet));
540       silc_buffer_format(packet,
541                          SILC_STR_UI_SHORT(payload_len),
542                          SILC_STR_UI_SHORT(SILC_SOCKET_TYPE_CLIENT),
543                          SILC_STR_UI_XNSTRING(auth_data, auth_data_len),
544                          SILC_STR_END);
545
546       /* Send the packet to server */
547       silc_client_packet_send(client, ctx->sock,
548                               SILC_PACKET_CONNECTION_AUTH,
549                               NULL, 0, NULL, NULL,
550                               packet->data, packet->len, TRUE);
551
552       if (auth_data) {
553         memset(auth_data, 0, auth_data_len);
554         silc_free(auth_data);
555       }
556       silc_buffer_free(packet);
557       
558       /* Next state is end of protocol */
559       protocol->state = SILC_PROTOCOL_STATE_END;
560     }
561     break;
562
563   case SILC_PROTOCOL_STATE_END:
564     {
565       /* 
566        * End protocol. Nothing special to be done here.
567        */
568
569       /* Protocol has ended, call the final callback */
570       if (protocol->final_callback)
571         protocol->execute_final(client->timeout_queue, 0, protocol, fd);
572       else
573         silc_protocol_free(protocol);
574     }
575     break;
576
577   case SILC_PROTOCOL_STATE_ERROR:
578     {
579       /* 
580        * Error. Send notify to remote.
581        */
582       unsigned char error[4];
583
584       SILC_PUT32_MSB(SILC_AUTH_FAILED, error);
585
586       /* Error in protocol. Send FAILURE packet. Although I don't think
587          this could ever happen on client side. */
588       silc_client_packet_send(client, ctx->sock, SILC_PACKET_FAILURE,
589                               NULL, 0, NULL, NULL, error, 4, TRUE);
590
591       /* On error the final callback is always called. */
592       if (protocol->final_callback)
593         protocol->execute_final(client->timeout_queue, 0, protocol, fd);
594       else
595         silc_protocol_free(protocol);
596     }
597
598   case SILC_PROTOCOL_STATE_FAILURE:
599     /*
600      * Received failure from remote.
601      */
602
603     /* On error the final callback is always called. */
604     if (protocol->final_callback)
605       protocol->execute_final(client->timeout_queue, 0, protocol, fd);
606     else
607       silc_protocol_free(protocol);
608     break;
609
610   case SILC_PROTOCOL_STATE_UNKNOWN:
611     break;
612   }
613 }
614
615 /* Registers protocols used in client */
616
617 void silc_client_protocols_register(void)
618 {
619   silc_protocol_register(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
620                          silc_client_protocol_connection_auth);
621   silc_protocol_register(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
622                          silc_client_protocol_key_exchange);
623 }
624
625 /* Unregisters protocols */
626
627 void silc_client_protocols_unregister(void)
628 {
629   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_CONNECTION_AUTH,
630                            silc_client_protocol_connection_auth);
631   silc_protocol_unregister(SILC_PROTOCOL_CLIENT_KEY_EXCHANGE,
632                            silc_client_protocol_key_exchange);
633 }