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