1 /*
2 * ssl.c v0.0.3
3 * Copyright (C) 2000 -- DaP <profeta@freemail.c3.hu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20 #ifdef __APPLE__
21 #define __AVAILABILITYMACROS__
22 #define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
23 #endif
24
25 #include "inet.h" /* make it first to avoid macro redefinitions */
26 #include <openssl/ssl.h> /* SSL_() */
27 #include <openssl/err.h> /* ERR_() */
28 #include <openssl/x509v3.h>
29 #ifdef WIN32
30 #include <openssl/rand.h> /* RAND_seed() */
31 #endif
32 #include "config.h"
33 #include <time.h> /* asctime() */
34 #include <string.h> /* strncpy() */
35 #include "ssl.h" /* struct cert_info */
36
37 #include <glib.h>
38 #include <glib/gprintf.h>
39 #include <gio/gio.h>
40 #include "util.h"
41
42 /* If openssl was built without ec */
43 #ifndef SSL_OP_SINGLE_ECDH_USE
44 #define SSL_OP_SINGLE_ECDH_USE 0
45 #endif
46
47 #ifndef SSL_OP_NO_COMPRESSION
48 #define SSL_OP_NO_COMPRESSION 0
49 #endif
50
51 /* globals */
52 static struct chiper_info chiper_info; /* static buffer for _SSL_get_cipher_info() */
53 static char err_buf[256]; /* generic error buffer */
54
55
56 /* +++++ Internal functions +++++ */
57
58 static void
__SSL_fill_err_buf(char * funcname)59 __SSL_fill_err_buf (char *funcname)
60 {
61 int err;
62 char buf[256];
63
64
65 err = ERR_get_error ();
66 ERR_error_string (err, buf);
67 g_snprintf (err_buf, sizeof (err_buf), "%s: %s (%d)\n", funcname, buf, err);
68 }
69
70
71 static void
__SSL_critical_error(char * funcname)72 __SSL_critical_error (char *funcname)
73 {
74 __SSL_fill_err_buf (funcname);
75 fprintf (stderr, "%s\n", err_buf);
76
77 exit (1);
78 }
79
80 /* +++++ SSL functions +++++ */
81
82 SSL_CTX *
_SSL_context_init(void (* info_cb_func))83 _SSL_context_init (void (*info_cb_func))
84 {
85 SSL_CTX *ctx;
86
87 SSLeay_add_ssl_algorithms ();
88 SSL_load_error_strings ();
89 ctx = SSL_CTX_new (SSLv23_client_method ());
90
91 SSL_CTX_set_session_cache_mode (ctx, SSL_SESS_CACHE_BOTH);
92 SSL_CTX_set_timeout (ctx, 300);
93 SSL_CTX_set_options (ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3
94 |SSL_OP_NO_COMPRESSION
95 |SSL_OP_SINGLE_DH_USE|SSL_OP_SINGLE_ECDH_USE
96 |SSL_OP_NO_TICKET
97 |SSL_OP_CIPHER_SERVER_PREFERENCE);
98
99 #if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined (OPENSSL_NO_COMP) /* workaround for OpenSSL 0.9.8 */
100 sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
101 #endif
102
103 /* used in SSL_connect(), SSL_accept() */
104 SSL_CTX_set_info_callback (ctx, info_cb_func);
105
106 return(ctx);
107 }
108
109 static void
ASN1_TIME_snprintf(char * buf,int buf_len,ASN1_TIME * tm)110 ASN1_TIME_snprintf (char *buf, int buf_len, ASN1_TIME * tm)
111 {
112 char *expires = NULL;
113 BIO *inMem = BIO_new (BIO_s_mem ());
114
115 ASN1_TIME_print (inMem, tm);
116 BIO_get_mem_data (inMem, &expires);
117 buf[0] = 0;
118 if (expires != NULL)
119 {
120 /* expires is not \0 terminated */
121 safe_strcpy (buf, expires, MIN(24, buf_len));
122 }
123 BIO_free (inMem);
124 }
125
126
127 static void
broke_oneline(char * oneline,char * parray[])128 broke_oneline (char *oneline, char *parray[])
129 {
130 char *pt, *ppt;
131 int i;
132
133
134 i = 0;
135 ppt = pt = oneline + 1;
136 while ((pt = strchr (pt, '/')))
137 {
138 *pt = 0;
139 parray[i++] = ppt;
140 ppt = ++pt;
141 }
142 parray[i++] = ppt;
143 parray[i] = NULL;
144 }
145
146
147 /*
148 FIXME: Master-Key, Extensions, CA bits
149 (openssl x509 -text -in servcert.pem)
150 */
151 int
_SSL_get_cert_info(struct cert_info * cert_info,SSL * ssl)152 _SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl)
153 {
154 X509 *peer_cert;
155 X509_PUBKEY *key;
156 X509_ALGOR *algor = NULL;
157 EVP_PKEY *peer_pkey;
158 char notBefore[64];
159 char notAfter[64];
160 int alg;
161 int sign_alg;
162
163
164 if (!(peer_cert = SSL_get_peer_certificate (ssl)))
165 return (1); /* FATAL? */
166
167 X509_NAME_oneline (X509_get_subject_name (peer_cert), cert_info->subject,
168 sizeof (cert_info->subject));
169 X509_NAME_oneline (X509_get_issuer_name (peer_cert), cert_info->issuer,
170 sizeof (cert_info->issuer));
171 broke_oneline (cert_info->subject, cert_info->subject_word);
172 broke_oneline (cert_info->issuer, cert_info->issuer_word);
173
174 key = X509_get_X509_PUBKEY(peer_cert);
175 if (!X509_PUBKEY_get0_param(NULL, NULL, 0, &algor, key))
176 return 1;
177
178 alg = OBJ_obj2nid (algor->algorithm);
179 #ifndef HAVE_X509_GET_SIGNATURE_NID
180 sign_alg = OBJ_obj2nid (peer_cert->sig_alg->algorithm);
181 #else
182 sign_alg = X509_get_signature_nid (peer_cert);
183 #endif
184 ASN1_TIME_snprintf (notBefore, sizeof (notBefore),
185 X509_get_notBefore (peer_cert));
186 ASN1_TIME_snprintf (notAfter, sizeof (notAfter),
187 X509_get_notAfter (peer_cert));
188
189 peer_pkey = X509_get_pubkey (peer_cert);
190
191 safe_strcpy (cert_info->algorithm,
192 (alg == NID_undef) ? "Unknown" : OBJ_nid2ln (alg),
193 sizeof (cert_info->algorithm));
194 cert_info->algorithm_bits = EVP_PKEY_bits (peer_pkey);
195 safe_strcpy (cert_info->sign_algorithm,
196 (sign_alg == NID_undef) ? "Unknown" : OBJ_nid2ln (sign_alg),
197 sizeof (cert_info->sign_algorithm));
198 /* EVP_PKEY_bits(ca_pkey)); */
199 cert_info->sign_algorithm_bits = 0;
200 safe_strcpy (cert_info->notbefore, notBefore, sizeof (cert_info->notbefore));
201 safe_strcpy (cert_info->notafter, notAfter, sizeof (cert_info->notafter));
202
203 EVP_PKEY_free (peer_pkey);
204
205 /* SSL_SESSION_print_fp(stdout, SSL_get_session(ssl)); */
206 /*
207 if (ssl->session->sess_cert->peer_rsa_tmp) {
208 tmp_pkey = EVP_PKEY_new();
209 EVP_PKEY_assign_RSA(tmp_pkey, ssl->session->sess_cert->peer_rsa_tmp);
210 cert_info->rsa_tmp_bits = EVP_PKEY_bits (tmp_pkey);
211 EVP_PKEY_free(tmp_pkey);
212 } else
213 fprintf(stderr, "REMOTE SIDE DOESN'T PROVIDES ->peer_rsa_tmp\n");
214 */
215 cert_info->rsa_tmp_bits = 0;
216
217 X509_free (peer_cert);
218
219 return (0);
220 }
221
222
223 struct chiper_info *
_SSL_get_cipher_info(SSL * ssl)224 _SSL_get_cipher_info (SSL * ssl)
225 {
226 const SSL_CIPHER *c;
227
228
229 c = SSL_get_current_cipher (ssl);
230 safe_strcpy (chiper_info.version, SSL_CIPHER_get_version (c),
231 sizeof (chiper_info.version));
232 safe_strcpy (chiper_info.chiper, SSL_CIPHER_get_name (c),
233 sizeof (chiper_info.chiper));
234 SSL_CIPHER_get_bits (c, &chiper_info.chiper_bits);
235
236 return (&chiper_info);
237 }
238
239
240 int
_SSL_send(SSL * ssl,char * buf,int len)241 _SSL_send (SSL * ssl, char *buf, int len)
242 {
243 int num;
244
245
246 num = SSL_write (ssl, buf, len);
247
248 switch (SSL_get_error (ssl, num))
249 {
250 case SSL_ERROR_SSL: /* setup errno! */
251 /* ??? */
252 __SSL_fill_err_buf ("SSL_write");
253 fprintf (stderr, "%s\n", err_buf);
254 break;
255 case SSL_ERROR_SYSCALL:
256 /* ??? */
257 perror ("SSL_write/write");
258 break;
259 case SSL_ERROR_ZERO_RETURN:
260 /* fprintf(stderr, "SSL closed on write\n"); */
261 break;
262 }
263
264 return (num);
265 }
266
267
268 int
_SSL_recv(SSL * ssl,char * buf,int len)269 _SSL_recv (SSL * ssl, char *buf, int len)
270 {
271 int num;
272
273
274 num = SSL_read (ssl, buf, len);
275
276 switch (SSL_get_error (ssl, num))
277 {
278 case SSL_ERROR_SSL:
279 /* ??? */
280 __SSL_fill_err_buf ("SSL_read");
281 fprintf (stderr, "%s\n", err_buf);
282 break;
283 case SSL_ERROR_SYSCALL:
284 /* ??? */
285 if (!would_block ())
286 perror ("SSL_read/read");
287 break;
288 case SSL_ERROR_ZERO_RETURN:
289 /* fprintf(stdeerr, "SSL closed on read\n"); */
290 break;
291 }
292
293 return (num);
294 }
295
296
297 SSL *
_SSL_socket(SSL_CTX * ctx,int sd)298 _SSL_socket (SSL_CTX *ctx, int sd)
299 {
300 SSL *ssl;
301 const SSL_METHOD *method;
302
303 if (!(ssl = SSL_new (ctx)))
304 /* FATAL */
305 __SSL_critical_error ("SSL_new");
306
307 SSL_set_fd (ssl, sd);
308
309 #ifndef HAVE_SSL_CTX_GET_SSL_METHOD
310 method = ctx->method;
311 #else
312 method = SSL_CTX_get_ssl_method (ctx);
313 #endif
314 if (method == SSLv23_client_method())
315 SSL_set_connect_state (ssl);
316 else
317 SSL_set_accept_state(ssl);
318
319 return (ssl);
320 }
321
322
323 char *
_SSL_set_verify(SSL_CTX * ctx,void * verify_callback)324 _SSL_set_verify (SSL_CTX *ctx, void *verify_callback)
325 {
326 #ifdef DEFAULT_CERT_FILE
327 if (!SSL_CTX_load_verify_locations (ctx, DEFAULT_CERT_FILE, NULL))
328 {
329 __SSL_fill_err_buf ("SSL_CTX_load_verify_locations");
330 return (err_buf);
331 }
332 #else
333 if (!SSL_CTX_set_default_verify_paths (ctx))
334 {
335 __SSL_fill_err_buf ("SSL_CTX_set_default_verify_paths");
336 return (err_buf);
337 }
338 #endif
339
340 SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER, verify_callback);
341
342 return (NULL);
343 }
344
345
346 void
_SSL_close(SSL * ssl)347 _SSL_close (SSL * ssl)
348 {
349 SSL_set_shutdown (ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
350 SSL_free (ssl);
351 #ifdef HAVE_ERR_REMOVE_THREAD_STATE
352 #if OPENSSL_VERSION_NUMBER >= 0x10000000L && OPENSSL_VERSION_NUMBER < 0x10100000L
353 /* OpenSSL handles this itself in 1.1+ and this is a no-op */
354 ERR_remove_thread_state (NULL);
355 #endif
356 #else
357 ERR_remove_state (0);
358 #endif
359 }
360
361 /* Hostname validation code based on OpenBSD's libtls. */
362
363 static int
_SSL_match_hostname(const char * cert_hostname,const char * hostname)364 _SSL_match_hostname (const char *cert_hostname, const char *hostname)
365 {
366 const char *cert_domain, *domain, *next_dot;
367
368 if (g_ascii_strcasecmp (cert_hostname, hostname) == 0)
369 return 0;
370
371 /* Wildcard match? */
372 if (cert_hostname[0] == '*')
373 {
374 /*
375 * Valid wildcards:
376 * - "*.domain.tld"
377 * - "*.sub.domain.tld"
378 * - etc.
379 * Reject "*.tld".
380 * No attempt to prevent the use of eg. "*.co.uk".
381 */
382 cert_domain = &cert_hostname[1];
383 /* Disallow "*" */
384 if (cert_domain[0] == '\0')
385 return -1;
386 /* Disallow "*foo" */
387 if (cert_domain[0] != '.')
388 return -1;
389 /* Disallow "*.." */
390 if (cert_domain[1] == '.')
391 return -1;
392 next_dot = strchr (&cert_domain[1], '.');
393 /* Disallow "*.bar" */
394 if (next_dot == NULL)
395 return -1;
396 /* Disallow "*.bar.." */
397 if (next_dot[1] == '.')
398 return -1;
399
400 domain = strchr (hostname, '.');
401
402 /* No wildcard match against a hostname with no domain part. */
403 if (domain == NULL || strlen(domain) == 1)
404 return -1;
405
406 if (g_ascii_strcasecmp (cert_domain, domain) == 0)
407 return 0;
408 }
409
410 return -1;
411 }
412
413 static int
_SSL_check_subject_altname(X509 * cert,const char * host)414 _SSL_check_subject_altname (X509 *cert, const char *host)
415 {
416 STACK_OF(GENERAL_NAME) *altname_stack = NULL;
417 GInetAddress *addr;
418 GSocketFamily family;
419 int type = GEN_DNS;
420 int count, i;
421 int rv = -1;
422
423 altname_stack = X509_get_ext_d2i (cert, NID_subject_alt_name, NULL, NULL);
424 if (altname_stack == NULL)
425 return -1;
426
427 addr = g_inet_address_new_from_string (host);
428 if (addr != NULL)
429 {
430 family = g_inet_address_get_family (addr);
431 if (family == G_SOCKET_FAMILY_IPV4 || family == G_SOCKET_FAMILY_IPV6)
432 type = GEN_IPADD;
433 }
434
435 count = sk_GENERAL_NAME_num(altname_stack);
436 for (i = 0; i < count; i++)
437 {
438 GENERAL_NAME *altname;
439
440 altname = sk_GENERAL_NAME_value (altname_stack, i);
441
442 if (altname->type != type)
443 continue;
444
445 if (type == GEN_DNS)
446 {
447 const unsigned char *data;
448 int format;
449
450 format = ASN1_STRING_type (altname->d.dNSName);
451 if (format == V_ASN1_IA5STRING)
452 {
453 #ifdef HAVE_ASN1_STRING_GET0_DATA
454 data = ASN1_STRING_get0_data (altname->d.dNSName);
455 #else
456 data = ASN1_STRING_data (altname->d.dNSName);
457 #endif
458
459 if (ASN1_STRING_length (altname->d.dNSName) != (int)strlen(data))
460 {
461 g_warning("NUL byte in subjectAltName, probably a malicious certificate.\n");
462 rv = -2;
463 break;
464 }
465
466 if (_SSL_match_hostname (data, host) == 0)
467 {
468 rv = 0;
469 break;
470 }
471 }
472 else
473 g_warning ("unhandled subjectAltName dNSName encoding (%d)\n", format);
474
475 }
476 else if (type == GEN_IPADD)
477 {
478 const unsigned char *data;
479 const guint8 *addr_bytes;
480 int datalen, addr_len;
481
482 datalen = ASN1_STRING_length (altname->d.iPAddress);
483 #ifdef HAVE_ASN1_STRING_GET0_DATA
484 data = ASN1_STRING_get0_data (altname->d.iPAddress);
485 #else
486 data = ASN1_STRING_data (altname->d.iPAddress);
487 #endif
488
489 addr_bytes = g_inet_address_to_bytes (addr);
490 addr_len = (int)g_inet_address_get_native_size (addr);
491
492 if (datalen == addr_len && memcmp (data, addr_bytes, addr_len) == 0)
493 {
494 rv = 0;
495 break;
496 }
497 }
498 }
499
500 if (addr != NULL)
501 g_object_unref (addr);
502 sk_GENERAL_NAME_pop_free (altname_stack, GENERAL_NAME_free);
503 return rv;
504 }
505
506 static int
_SSL_check_common_name(X509 * cert,const char * host)507 _SSL_check_common_name (X509 *cert, const char *host)
508 {
509 X509_NAME *name;
510 char *common_name = NULL;
511 int common_name_len;
512 int rv = -1;
513 GInetAddress *addr;
514
515 name = X509_get_subject_name (cert);
516 if (name == NULL)
517 return -1;
518
519 common_name_len = X509_NAME_get_text_by_NID (name, NID_commonName, NULL, 0);
520 if (common_name_len < 0)
521 return -1;
522
523 common_name = g_malloc0 (common_name_len + 1);
524
525 X509_NAME_get_text_by_NID (name, NID_commonName, common_name, common_name_len + 1);
526
527 /* NUL bytes in CN? */
528 if (common_name_len != (int)strlen(common_name))
529 {
530 g_warning ("NUL byte in Common Name field, probably a malicious certificate.\n");
531 rv = -2;
532 goto out;
533 }
534
535 if ((addr = g_inet_address_new_from_string (host)) != NULL)
536 {
537 /*
538 * We don't want to attempt wildcard matching against IP
539 * addresses, so perform a simple comparison here.
540 */
541 if (g_strcmp0 (common_name, host) == 0)
542 rv = 0;
543 else
544 rv = -1;
545
546 g_object_unref (addr);
547 }
548 else if (_SSL_match_hostname (common_name, host) == 0)
549 rv = 0;
550
551 out:
552 g_free(common_name);
553 return rv;
554 }
555
556 int
_SSL_check_hostname(X509 * cert,const char * host)557 _SSL_check_hostname (X509 *cert, const char *host)
558 {
559 int rv;
560
561 rv = _SSL_check_subject_altname (cert, host);
562 if (rv == 0 || rv == -2)
563 return rv;
564
565 return _SSL_check_common_name (cert, host);
566 }
567