imported.
[silc.git] / apps / irssi / src / silc / core / clientutil.c
1 /*
2  clientutil.c : irssi
3
4     Copyright (C) 2000 Timo Sirainen
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 #include "module.h"
22
23 #include "silc-servers.h"
24
25 /* Verifies received public key. If user decides to trust the key it is
26    saved as trusted server key for later use. If user does not trust the
27    key this returns FALSE. */
28
29 int silc_client_verify_server_key(SILC_SERVER_REC *server,
30                                   unsigned char *pk, unsigned int pk_len,
31                                   SilcSKEPKType pk_type)
32 {
33   char filename[256];
34   char file[256];
35   char *hostname, *fingerprint;
36   struct stat st;
37
38   hostname = server->connrec->address;
39
40   if (pk_type != SILC_SKE_PK_TYPE_SILC) {
41     //silc_say(client, "We don't support server %s key type", hostname);
42     return FALSE;
43   }
44
45   memset(filename, 0, sizeof(filename));
46   memset(file, 0, sizeof(file));
47   snprintf(file, sizeof(file) - 1, "serverkey_%s_%d.pub", hostname,
48            server->connrec->port);
49   snprintf(filename, sizeof(filename) - 1, "%s/.silc/serverkeys/%s", 
50            g_get_home_dir(), file);
51
52   /* Check wheter this key already exists */
53   if (stat(filename, &st) < 0) {
54
55     fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
56     /*silc_say(client, "Received server %s public key", hostname);
57     silc_say(client, "Fingerprint for the server %s key is", hostname);
58     silc_say(client, "%s", fingerprint);*/
59     silc_free(fingerprint);
60
61     /* Ask user to verify the key and save it */
62     /*if (silc_client_ask_yes_no(client,
63        "Would you like to accept the key (y/n)? "))*/
64       {
65         /* Save the key for future checking */
66         silc_pkcs_save_public_key_data(filename, pk, pk_len, 
67                                        SILC_PKCS_FILE_PEM);
68         return TRUE;
69       }
70   } else {
71     /* The key already exists, verify it. */
72     SilcPublicKey public_key;
73     unsigned char *encpk;
74     unsigned int encpk_len;
75
76     /* Load the key file */
77     if (!silc_pkcs_load_public_key(filename, &public_key, 
78                                    SILC_PKCS_FILE_PEM))
79       if (!silc_pkcs_load_public_key(filename, &public_key, 
80                                      SILC_PKCS_FILE_BIN)) {
81         fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
82         /*silc_say(client, "Received server %s public key", hostname);
83         silc_say(client, "Fingerprint for the server %s key is", hostname);
84         silc_say(client, "%s", fingerprint);*/
85         silc_free(fingerprint);
86         /*silc_say(client, "Could not load your local copy of the server %s key",
87                  hostname);
88         if (silc_client_ask_yes_no(client, 
89            "Would you like to accept the key anyway (y/n)? "))*/
90           {
91             /* Save the key for future checking */
92             unlink(filename);
93             silc_pkcs_save_public_key_data(filename, pk, pk_len,
94                                            SILC_PKCS_FILE_PEM);
95             return TRUE;
96           }
97         
98         return FALSE;
99       }
100   
101     /* Encode the key data */
102     encpk = silc_pkcs_public_key_encode(public_key, &encpk_len);
103     if (!encpk) {
104       fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
105       /*silc_say(client, "Received server %s public key", hostname);
106       silc_say(client, "Fingerprint for the server %s key is", hostname);
107       silc_say(client, "%s", fingerprint);*/
108       silc_free(fingerprint);
109       /*silc_say(client, "Your local copy of the server %s key is malformed",
110                hostname);
111       if (silc_client_ask_yes_no(client,
112          "Would you like to accept the key anyway (y/n)? "))*/
113         {
114           /* Save the key for future checking */
115           unlink(filename);
116           silc_pkcs_save_public_key_data(filename, pk, pk_len,
117                                          SILC_PKCS_FILE_PEM);
118           return TRUE;
119         }
120
121       return FALSE;
122     }
123
124     if (memcmp(encpk, pk, encpk_len)) {
125       fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
126       /*silc_say(client, "Received server %s public key", hostname);
127       silc_say(client, "Fingerprint for the server %s key is", hostname);
128       silc_say(client, "%s", fingerprint);*/
129       silc_free(fingerprint);
130       /*silc_say(client, "Server %s key does not match with your local copy",
131                hostname);
132       silc_say(client, "It is possible that the key has expired or changed");
133       silc_say(client, "It is also possible that some one is performing "
134                        "man-in-the-middle attack");*/
135       
136       /* Ask user to verify the key and save it */
137       /*if (silc_client_ask_yes_no(client,
138          "Would you like to accept the key anyway (y/n)? "))*/
139         {
140           /* Save the key for future checking */
141           unlink(filename);
142           silc_pkcs_save_public_key_data(filename, pk, pk_len,
143                                          SILC_PKCS_FILE_PEM);
144           return TRUE;
145         }
146
147       //silc_say(client, "Will not accept server %s key", hostname);
148       return FALSE;
149     }
150
151     /* Local copy matched */
152     return TRUE;
153   }
154
155   //silc_say(client, "Will not accept server %s key", hostname);
156   return FALSE;
157 }