Merge Irssi 0.8.16-rc1
[silc.git] / apps / irssi / src / core / network-openssl.c
1 /*
2  network-ssl.c : SSL support
3
4     Copyright (C) 2002 vjt
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 along
17     with this program; if not, write to the Free Software Foundation, Inc.,
18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #include "module.h"
22 #include "network.h"
23 #include "misc.h"
24 #include "servers.h"
25
26 #ifdef HAVE_OPENSSL
27
28 #include <openssl/crypto.h>
29 #include <openssl/x509.h>
30 #include <openssl/x509v3.h>
31 #include <openssl/pem.h>
32 #include <openssl/ssl.h>
33 #include <openssl/err.h>
34
35 #ifdef HAVE_DANE
36 #include <validator/validator.h>
37 #include <validator/val_dane.h>
38 #endif
39
40 /* ssl i/o channel object */
41 typedef struct
42 {
43         GIOChannel pad;
44         gint fd;
45         GIOChannel *giochan;
46         SSL *ssl;
47         SSL_CTX *ctx;
48         unsigned int verify:1;
49         SERVER_REC *server;
50         int port;
51 } GIOSSLChannel;
52
53 static int ssl_inited = FALSE;
54
55 static void irssi_ssl_free(GIOChannel *handle)
56 {
57         GIOSSLChannel *chan = (GIOSSLChannel *)handle;
58         g_io_channel_unref(chan->giochan);
59         SSL_free(chan->ssl);
60         SSL_CTX_free(chan->ctx);
61         g_free(chan);
62 }
63
64 /* Checks if the given string has internal NUL characters. */
65 static gboolean has_internal_nul(const char* str, int len) {
66         /* Remove trailing nul characters. They would give false alarms */
67         while (len > 0 && str[len-1] == 0)
68                 len--;
69         return strlen(str) != len;
70 }
71
72 /* tls_dns_name - Extract valid DNS name from subjectAltName value */
73 static const char *tls_dns_name(const GENERAL_NAME * gn)
74 {
75         const char *dnsname;
76
77         /* We expect the OpenSSL library to construct GEN_DNS extension objects as
78            ASN1_IA5STRING values. Check we got the right union member. */
79         if (ASN1_STRING_type(gn->d.ia5) != V_ASN1_IA5STRING) {
80                 g_warning("Invalid ASN1 value type in subjectAltName");
81                 return NULL;
82         }
83
84         /* Safe to treat as an ASCII string possibly holding a DNS name */
85         dnsname = (char *) ASN1_STRING_data(gn->d.ia5);
86
87         if (has_internal_nul(dnsname, ASN1_STRING_length(gn->d.ia5))) {
88                 g_warning("Internal NUL in subjectAltName");
89                 return NULL;
90         }
91
92         return dnsname;
93 }
94
95 /* tls_text_name - extract certificate property value by name */
96 static char *tls_text_name(X509_NAME *name, int nid)
97 {
98         int     pos;
99         X509_NAME_ENTRY *entry;
100         ASN1_STRING *entry_str;
101         int     utf8_length;
102         unsigned char *utf8_value;
103         char *result;
104
105         if (name == 0 || (pos = X509_NAME_get_index_by_NID(name, nid, -1)) < 0) {
106                 return NULL;
107         }
108
109         entry = X509_NAME_get_entry(name, pos);
110         g_return_val_if_fail(entry != NULL, NULL);
111         entry_str = X509_NAME_ENTRY_get_data(entry);
112         g_return_val_if_fail(entry_str != NULL, NULL);
113
114         /* Convert everything into UTF-8. It's up to OpenSSL to do something
115            reasonable when converting ASCII formats that contain non-ASCII
116            content. */
117         if ((utf8_length = ASN1_STRING_to_UTF8(&utf8_value, entry_str)) < 0) {
118                 g_warning("Error decoding ASN.1 type=%d", ASN1_STRING_type(entry_str));
119                 return NULL;
120         }
121
122         if (has_internal_nul((char *)utf8_value, utf8_length)) {
123                 g_warning("NUL character in hostname in certificate");
124                 OPENSSL_free(utf8_value);
125                 return NULL;
126         }
127
128         result = g_strdup((char *) utf8_value);
129         OPENSSL_free(utf8_value);
130         return result;
131 }
132
133
134 /** check if a hostname in the certificate matches the hostname we used for the connection */
135 static gboolean match_hostname(const char *cert_hostname, const char *hostname)
136 {
137         const char *hostname_left;
138
139         if (!strcasecmp(cert_hostname, hostname)) { /* exact match */
140                 return TRUE;
141         } else if (cert_hostname[0] == '*' && cert_hostname[1] == '.' && cert_hostname[2] != 0) { /* wildcard match */
142                 /* The initial '*' matches exactly one hostname component */
143                 hostname_left = strchr(hostname, '.');
144                 if (hostname_left != NULL && ! strcasecmp(hostname_left + 1, cert_hostname + 2)) {
145                         return TRUE;
146                 }
147         }
148         return FALSE;
149 }
150
151 /* based on verify_extract_name from tls_client.c in postfix */
152 static gboolean irssi_ssl_verify_hostname(X509 *cert, const char *hostname)
153 {
154         int gen_index, gen_count;
155         gboolean matched = FALSE, has_dns_name = FALSE;
156         const char *cert_dns_name;
157         char *cert_subject_cn;
158         const GENERAL_NAME *gn;
159         STACK_OF(GENERAL_NAME) * gens;
160
161         /* Verify the dNSName(s) in the peer certificate against the hostname. */
162         gens = X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0);
163         if (gens) {
164                 gen_count = sk_GENERAL_NAME_num(gens);
165                 for (gen_index = 0; gen_index < gen_count && !matched; ++gen_index) {
166                         gn = sk_GENERAL_NAME_value(gens, gen_index);
167                         if (gn->type != GEN_DNS)
168                                 continue;
169
170                         /* Even if we have an invalid DNS name, we still ultimately
171                            ignore the CommonName, because subjectAltName:DNS is
172                            present (though malformed). */
173                         has_dns_name = TRUE;
174                         cert_dns_name = tls_dns_name(gn);
175                         if (cert_dns_name && *cert_dns_name) {
176                                 matched = match_hostname(cert_dns_name, hostname);
177                         }
178                 }
179
180                 /* Free stack *and* member GENERAL_NAME objects */
181                 sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free);
182         }
183
184         if (has_dns_name) {
185                 if (! matched) {
186                         /* The CommonName in the issuer DN is obsolete when SubjectAltName is available. */
187                         g_warning("None of the Subject Alt Names in the certificate match hostname '%s'", hostname);
188                 }
189                 return matched;
190         } else { /* No subjectAltNames, look at CommonName */
191                 cert_subject_cn = tls_text_name(X509_get_subject_name(cert), NID_commonName);
192                 if (cert_subject_cn && *cert_subject_cn) {
193                         matched = match_hostname(cert_subject_cn, hostname);
194                         if (! matched) {
195                                 g_warning("SSL certificate common name '%s' doesn't match host name '%s'", cert_subject_cn, hostname);
196                         }
197                 } else {
198                         g_warning("No subjectAltNames and no valid common name in certificate");
199                 }
200                 free(cert_subject_cn);
201         }
202
203         return matched;
204 }
205
206 static gboolean irssi_ssl_verify(SSL *ssl, SSL_CTX *ctx, const char* hostname, int port, X509 *cert, SERVER_REC *server)
207 {
208         long result;
209 #ifdef HAVE_DANE
210         int dane_ret;
211         struct val_daneparams daneparams;
212         struct val_danestatus *danestatus = NULL;
213
214         // Check if a TLSA record is available.
215         daneparams.port = port;
216         daneparams.proto = DANE_PARAM_PROTO_TCP;
217
218         dane_ret = val_getdaneinfo(NULL, hostname, &daneparams, &danestatus);
219
220         if (dane_ret == VAL_DANE_NOERROR) {
221                 signal_emit("tlsa available", 1, server);
222         }
223
224         if (danestatus != NULL) {
225                 int do_certificate_check = 1;
226
227                 if (val_dane_check(NULL, ssl, danestatus, &do_certificate_check) != VAL_DANE_NOERROR) {
228                         g_warning("DANE: TLSA record for hostname %s port %d could not be verified", hostname, port);
229                         signal_emit("tlsa verification failed", 1, server);
230                         val_free_dane(danestatus);
231                         return FALSE;
232                 }
233
234                 signal_emit("tlsa verification success", 1, server);
235                 val_free_dane(danestatus);
236
237                 if (do_certificate_check == 0) {
238                         return TRUE;
239                 }
240         }
241 #endif
242
243         result = SSL_get_verify_result(ssl);
244         if (result != X509_V_OK) {
245                 unsigned char md[EVP_MAX_MD_SIZE];
246                 unsigned int n;
247                 char *str;
248
249                 g_warning("Could not verify SSL servers certificate: %s",
250                                 X509_verify_cert_error_string(result));
251                 if ((str = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0)) == NULL)
252                         g_warning("  Could not get subject-name from peer certificate");
253                 else {
254                         g_warning("  Subject : %s", str);
255                         free(str);
256                 }
257                 if ((str = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0)) == NULL)
258                         g_warning("  Could not get issuer-name from peer certificate");
259                 else {
260                         g_warning("  Issuer  : %s", str);
261                         free(str);
262                 }
263                 if (! X509_digest(cert, EVP_md5(), md, &n))
264                         g_warning("  Could not get fingerprint from peer certificate");
265                 else {
266                         char hex[] = "0123456789ABCDEF";
267                         char fp[EVP_MAX_MD_SIZE*3];
268                         if (n < sizeof(fp)) {
269                                 unsigned int i;
270                                 for (i = 0; i < n; i++) {
271                                         fp[i*3+0] = hex[(md[i] >> 4) & 0xF];
272                                         fp[i*3+1] = hex[(md[i] >> 0) & 0xF];
273                                         fp[i*3+2] = i == n - 1 ? '\0' : ':';
274                                 }
275                                 g_warning("  MD5 Fingerprint : %s", fp);
276                         }
277                 }
278                 return FALSE;
279         } else if (! irssi_ssl_verify_hostname(cert, hostname)){
280                 return FALSE;
281         }
282         return TRUE;
283 }
284
285 static GIOStatus irssi_ssl_read(GIOChannel *handle, gchar *buf, gsize len, gsize *ret, GError **gerr)
286 {
287         GIOSSLChannel *chan = (GIOSSLChannel *)handle;
288         gint ret1, err;
289         const char *errstr;
290         gchar *errmsg;
291
292         ret1 = SSL_read(chan->ssl, buf, len);
293         if(ret1 <= 0)
294         {
295                 *ret = 0;
296                 err = SSL_get_error(chan->ssl, ret1);
297                 if(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
298                         return G_IO_STATUS_AGAIN;
299                 else if(err == SSL_ERROR_ZERO_RETURN)
300                         return G_IO_STATUS_EOF;
301                 else if (err == SSL_ERROR_SYSCALL)
302                 {
303                         errstr = ERR_reason_error_string(ERR_get_error());
304                         if (errstr == NULL && ret1 == -1)
305                                 errstr = strerror(errno);
306                         if (errstr == NULL)
307                                 errstr = "server closed connection unexpectedly";
308                 }
309                 else
310                 {
311                         errstr = ERR_reason_error_string(ERR_get_error());
312                         if (errstr == NULL)
313                                 errstr = "unknown SSL error";
314                 }
315                 errmsg = g_strdup_printf("SSL read error: %s", errstr);
316                 *gerr = g_error_new_literal(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED,
317                                             errmsg);
318                 g_free(errmsg);
319                 return G_IO_STATUS_ERROR;
320         }
321         else
322         {
323                 *ret = ret1;
324                 return G_IO_STATUS_NORMAL;
325         }
326         /*UNREACH*/
327         return G_IO_STATUS_ERROR;
328 }
329
330 static GIOStatus irssi_ssl_write(GIOChannel *handle, const gchar *buf, gsize len, gsize *ret, GError **gerr)
331 {
332         GIOSSLChannel *chan = (GIOSSLChannel *)handle;
333         gint ret1, err;
334         const char *errstr;
335         gchar *errmsg;
336
337         ret1 = SSL_write(chan->ssl, (const char *)buf, len);
338         if(ret1 <= 0)
339         {
340                 *ret = 0;
341                 err = SSL_get_error(chan->ssl, ret1);
342                 if(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE)
343                         return G_IO_STATUS_AGAIN;
344                 else if(err == SSL_ERROR_ZERO_RETURN)
345                         errstr = "server closed connection";
346                 else if (err == SSL_ERROR_SYSCALL)
347                 {
348                         errstr = ERR_reason_error_string(ERR_get_error());
349                         if (errstr == NULL && ret1 == -1)
350                                 errstr = strerror(errno);
351                         if (errstr == NULL)
352                                 errstr = "server closed connection unexpectedly";
353                 }
354                 else
355                 {
356                         errstr = ERR_reason_error_string(ERR_get_error());
357                         if (errstr == NULL)
358                                 errstr = "unknown SSL error";
359                 }
360                 errmsg = g_strdup_printf("SSL write error: %s", errstr);
361                 *gerr = g_error_new_literal(G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED,
362                                             errmsg);
363                 g_free(errmsg);
364                 return G_IO_STATUS_ERROR;
365         }
366         else
367         {
368                 *ret = ret1;
369                 return G_IO_STATUS_NORMAL;
370         }
371         /*UNREACH*/
372         return G_IO_STATUS_ERROR;
373 }
374
375 static GIOStatus irssi_ssl_seek(GIOChannel *handle, gint64 offset, GSeekType type, GError **gerr)
376 {
377         GIOSSLChannel *chan = (GIOSSLChannel *)handle;
378
379         return chan->giochan->funcs->io_seek(handle, offset, type, gerr);
380 }
381
382 static GIOStatus irssi_ssl_close(GIOChannel *handle, GError **gerr)
383 {
384         GIOSSLChannel *chan = (GIOSSLChannel *)handle;
385
386         return chan->giochan->funcs->io_close(handle, gerr);
387 }
388
389 static GSource *irssi_ssl_create_watch(GIOChannel *handle, GIOCondition cond)
390 {
391         GIOSSLChannel *chan = (GIOSSLChannel *)handle;
392
393         return chan->giochan->funcs->io_create_watch(handle, cond);
394 }
395
396 static GIOStatus irssi_ssl_set_flags(GIOChannel *handle, GIOFlags flags, GError **gerr)
397 {
398     GIOSSLChannel *chan = (GIOSSLChannel *)handle;
399
400     return chan->giochan->funcs->io_set_flags(handle, flags, gerr);
401 }
402
403 static GIOFlags irssi_ssl_get_flags(GIOChannel *handle)
404 {
405     GIOSSLChannel *chan = (GIOSSLChannel *)handle;
406
407     return chan->giochan->funcs->io_get_flags(handle);
408 }
409
410 static GIOFuncs irssi_ssl_channel_funcs = {
411     irssi_ssl_read,
412     irssi_ssl_write,
413     irssi_ssl_seek,
414     irssi_ssl_close,
415     irssi_ssl_create_watch,
416     irssi_ssl_free,
417     irssi_ssl_set_flags,
418     irssi_ssl_get_flags
419 };
420
421 static gboolean irssi_ssl_init(void)
422 {
423         SSL_library_init();
424         SSL_load_error_strings();
425         OpenSSL_add_all_algorithms();
426         ssl_inited = TRUE;
427
428         return TRUE;
429
430 }
431
432 static GIOChannel *irssi_ssl_get_iochannel(GIOChannel *handle, int port, SERVER_REC *server)
433 {
434         GIOSSLChannel *chan;
435         GIOChannel *gchan;
436         int fd;
437         SSL *ssl;
438         SSL_CTX *ctx = NULL;
439
440         const char *mycert = server->connrec->ssl_cert;
441         const char *mypkey = server->connrec->ssl_pkey;
442         const char *cafile = server->connrec->ssl_cafile;
443         const char *capath = server->connrec->ssl_capath;
444         gboolean verify = server->connrec->ssl_verify;
445
446         g_return_val_if_fail(handle != NULL, NULL);
447
448         if(!ssl_inited && !irssi_ssl_init())
449                 return NULL;
450
451         if(!(fd = g_io_channel_unix_get_fd(handle)))
452                 return NULL;
453
454         ctx = SSL_CTX_new(SSLv23_client_method());
455         if (ctx == NULL) {
456                 g_error("Could not allocate memory for SSL context");
457                 return NULL;
458         }
459         SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
460
461         if (mycert && *mycert) {
462                 char *scert = NULL, *spkey = NULL;
463                 scert = convert_home(mycert);
464                 if (mypkey && *mypkey)
465                         spkey = convert_home(mypkey);
466                 if (! SSL_CTX_use_certificate_file(ctx, scert, SSL_FILETYPE_PEM))
467                         g_warning("Loading of client certificate '%s' failed", mycert);
468                 else if (! SSL_CTX_use_PrivateKey_file(ctx, spkey ? spkey : scert, SSL_FILETYPE_PEM))
469                         g_warning("Loading of private key '%s' failed", mypkey ? mypkey : mycert);
470                 else if (! SSL_CTX_check_private_key(ctx))
471                         g_warning("Private key does not match the certificate");
472                 g_free(scert);
473                 g_free(spkey);
474         }
475
476         if ((cafile && *cafile) || (capath && *capath)) {
477                 char *scafile = NULL;
478                 char *scapath = NULL;
479                 if (cafile && *cafile)
480                         scafile = convert_home(cafile);
481                 if (capath && *capath)
482                         scapath = convert_home(capath);
483                 if (! SSL_CTX_load_verify_locations(ctx, scafile, scapath)) {
484                         g_warning("Could not load CA list for verifying SSL server certificate");
485                         g_free(scafile);
486                         g_free(scapath);
487                         SSL_CTX_free(ctx);
488                         return NULL;
489                 }
490                 g_free(scafile);
491                 g_free(scapath);
492                 verify = TRUE;
493         } else {
494                 if (!SSL_CTX_set_default_verify_paths(ctx))
495                         g_warning("Could not load default certificates");
496         }
497
498         if(!(ssl = SSL_new(ctx)))
499         {
500                 g_warning("Failed to allocate SSL structure");
501                 SSL_CTX_free(ctx);
502                 return NULL;
503         }
504
505         if(!SSL_set_fd(ssl, fd))
506         {
507                 g_warning("Failed to associate socket to SSL stream");
508                 SSL_free(ssl);
509                 SSL_CTX_free(ctx);
510                 return NULL;
511         }
512
513         SSL_set_mode(ssl, SSL_MODE_ENABLE_PARTIAL_WRITE |
514                         SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
515
516         chan = g_new0(GIOSSLChannel, 1);
517         chan->fd = fd;
518         chan->giochan = handle;
519         chan->ssl = ssl;
520         chan->ctx = ctx;
521         chan->server = server;
522         chan->port = port;
523         chan->verify = verify;
524
525         gchan = (GIOChannel *)chan;
526         gchan->funcs = &irssi_ssl_channel_funcs;
527         g_io_channel_init(gchan);
528         gchan->is_readable = gchan->is_writeable = TRUE;
529         gchan->use_buffer = FALSE;
530
531         return gchan;
532 }
533
534 GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC *server)
535 {
536         GIOChannel *handle, *ssl_handle;
537
538         handle = net_connect_ip(ip, port, my_ip);
539         if (handle == NULL)
540                 return NULL;
541         ssl_handle  = irssi_ssl_get_iochannel(handle, port, server);
542         if (ssl_handle == NULL)
543                 g_io_channel_unref(handle);
544         return ssl_handle;
545 }
546
547 int irssi_ssl_handshake(GIOChannel *handle)
548 {
549         GIOSSLChannel *chan = (GIOSSLChannel *)handle;
550         int ret, err;
551         X509 *cert;
552         const char *errstr;
553
554         ret = SSL_connect(chan->ssl);
555         if (ret <= 0) {
556                 err = SSL_get_error(chan->ssl, ret);
557                 switch (err) {
558                         case SSL_ERROR_WANT_READ:
559                                 return 1;
560                         case SSL_ERROR_WANT_WRITE:
561                                 return 3;
562                         case SSL_ERROR_ZERO_RETURN:
563                                 g_warning("SSL handshake failed: %s", "server closed connection");
564                                 return -1;
565                         case SSL_ERROR_SYSCALL:
566                                 errstr = ERR_reason_error_string(ERR_get_error());
567                                 if (errstr == NULL && ret == -1)
568                                         errstr = strerror(errno);
569                                 g_warning("SSL handshake failed: %s", errstr != NULL ? errstr : "server closed connection unexpectedly");
570                                 return -1;
571                         default:
572                                 errstr = ERR_reason_error_string(ERR_get_error());
573                                 g_warning("SSL handshake failed: %s", errstr != NULL ? errstr : "unknown SSL error");
574                                 return -1;
575                 }
576         }
577
578         cert = SSL_get_peer_certificate(chan->ssl);
579         if (cert == NULL) {
580                 g_warning("SSL server supplied no certificate");
581                 return -1;
582         }
583         ret = !chan->verify || irssi_ssl_verify(chan->ssl, chan->ctx, chan->server->connrec->address, chan->port, cert, chan->server);
584         X509_free(cert);
585         return ret ? 0 : -1;
586 }
587
588 #else /* HAVE_OPENSSL */
589
590 GIOChannel *net_connect_ip_ssl(IPADDR *ip, int port, IPADDR *my_ip, SERVER_REC *server)
591 {
592         g_warning("Connection failed: SSL support not enabled in this build.");
593         errno = ENOSYS;
594         return NULL;
595 }
596
597 #endif /* ! HAVE_OPENSSL */