loudmouth/lm-ssl-gnutls.c
author Mikael Hallendal <micke@imendio.com>
Sun, 29 Apr 2007 22:09:44 +0200
changeset 265 ebfc8419758d
parent 189 8ad7a25e4613
child 273 6be9056c1fb3
permissions -rw-r--r--
Bumped the version to 1.2.2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
137
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
     1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
     2
/*
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
     3
 * Copyright (C) 2003-2006 Imendio AB
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
     4
 *
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
     5
 * This program is free software; you can redistribute it and/or
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
     6
 * modify it under the terms of the GNU Lesser General Public License as
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
     7
 * published by the Free Software Foundation; either version 2 of the
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
     8
 * License, or (at your option) any later version.
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
     9
 *
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    10
 * This program is distributed in the hope that it will be useful,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    13
 * Lesser General Public License for more details.
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    14
 *
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    15
 * You should have received a copy of the GNU Lesser General Public
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    16
 * License along with this program; if not, write to the
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    17
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    18
 * Boston, MA 02111-1307, USA.
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    19
 */
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    20
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    21
#include <config.h>
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    22
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    23
#include <string.h>
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    24
#include <glib.h>
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    25
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    26
#include "lm-error.h"
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    27
#include "lm-ssl-base.h"
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    28
#include "lm-ssl-internals.h"
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    29
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    30
#ifdef HAVE_GNUTLS
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    31
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    32
#include <gnutls/x509.h>
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    33
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    34
struct _LmSSL {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    35
	LmSSLBase base;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    36
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    37
	gnutls_session                        gnutls_session;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    38
	gnutls_certificate_client_credentials gnutls_xcred;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    39
};
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    40
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    41
static gboolean       ssl_verify_certificate    (LmSSL       *ssl,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    42
						 const gchar *server);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    43
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    44
static gboolean
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    45
ssl_verify_certificate (LmSSL *ssl, const gchar *server)
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    46
{
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    47
	LmSSLBase *base;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    48
	int        status;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    49
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    50
	base = LM_SSL_BASE (ssl);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    51
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    52
	/* This verification function uses the trusted CAs in the credentials
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    53
	 * structure. So you must have installed one or more CA certificates.
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    54
	 */
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    55
	status = gnutls_certificate_verify_peers (ssl->gnutls_session);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    56
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    57
	if (status == GNUTLS_E_NO_CERTIFICATE_FOUND) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    58
		if (base->func (ssl,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    59
			       LM_SSL_STATUS_NO_CERT_FOUND,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    60
			       base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    61
			return FALSE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    62
		}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    63
	}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    64
	
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    65
	if (status & GNUTLS_CERT_INVALID
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    66
	    || status & GNUTLS_CERT_REVOKED) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    67
		if (base->func (ssl, LM_SSL_STATUS_UNTRUSTED_CERT,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    68
			       base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    69
			return FALSE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    70
		}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    71
	}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    72
	
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    73
	if (gnutls_certificate_expiration_time_peers (ssl->gnutls_session) < time (0)) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    74
		if (base->func (ssl, LM_SSL_STATUS_CERT_EXPIRED,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    75
			       base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    76
			return FALSE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    77
		}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    78
	}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    79
	
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    80
	if (gnutls_certificate_activation_time_peers (ssl->gnutls_session) > time (0)) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    81
		if (base->func (ssl, LM_SSL_STATUS_CERT_NOT_ACTIVATED,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    82
			       base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    83
			return FALSE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    84
		}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    85
	}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    86
	
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    87
	if (gnutls_certificate_type_get (ssl->gnutls_session) == GNUTLS_CRT_X509) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    88
		const gnutls_datum* cert_list;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    89
		guint cert_list_size;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    90
		size_t digest_size;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    91
		gnutls_x509_crt cert;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    92
		
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    93
		cert_list = gnutls_certificate_get_peers (ssl->gnutls_session, &cert_list_size);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    94
		if (cert_list == NULL) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    95
			if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    96
				       base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    97
				return FALSE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    98
			}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
    99
		}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   100
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   101
		gnutls_x509_crt_init (&cert);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   102
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   103
		if (!gnutls_x509_crt_import (cert, &cert_list[0],
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   104
					     GNUTLS_X509_FMT_DER)) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   105
			if (base->func (ssl, LM_SSL_STATUS_NO_CERT_FOUND, 
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   106
					base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   107
				return FALSE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   108
			}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   109
		}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   110
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   111
		if (!gnutls_x509_crt_check_hostname (cert, server)) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   112
			if (base->func (ssl, LM_SSL_STATUS_CERT_HOSTNAME_MISMATCH,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   113
				       base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   114
				return FALSE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   115
			}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   116
		}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   117
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   118
		gnutls_x509_crt_deinit (cert);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   119
146
5da5bf8186dd 2006-05-27 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents: 137
diff changeset
   120
		digest_size = sizeof (base->fingerprint);
5da5bf8186dd 2006-05-27 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents: 137
diff changeset
   121
137
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   122
		if (gnutls_fingerprint (GNUTLS_DIG_MD5, &cert_list[0],
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   123
					base->fingerprint,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   124
					&digest_size) >= 0) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   125
			if (base->expected_fingerprint &&
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   126
			    memcmp (base->expected_fingerprint, 
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   127
				    base->fingerprint,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   128
				    digest_size) &&
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   129
			    base->func (ssl,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   130
				       LM_SSL_STATUS_CERT_FINGERPRINT_MISMATCH,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   131
				       base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   132
				return FALSE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   133
			}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   134
		} 
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   135
		else if (base->func (ssl, LM_SSL_STATUS_GENERIC_ERROR,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   136
				     base->func_data) != LM_SSL_RESPONSE_CONTINUE) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   137
			return FALSE; 
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   138
		} 
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   139
	}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   140
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   141
	return TRUE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   142
}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   143
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   144
/* From lm-ssl-protected.h */
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   145
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   146
LmSSL *
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   147
_lm_ssl_new (const gchar    *expected_fingerprint,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   148
	    LmSSLFunction   ssl_function,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   149
	    gpointer        user_data,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   150
	    GDestroyNotify  notify)
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   151
{
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   152
	LmSSL *ssl;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   153
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   154
	ssl = g_new0 (LmSSL, 1);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   155
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   156
	_lm_ssl_base_init ((LmSSLBase *) ssl,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   157
			   expected_fingerprint,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   158
			   ssl_function, user_data, notify);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   159
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   160
	return ssl;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   161
}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   162
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   163
void
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   164
_lm_ssl_initialize (LmSSL *ssl) 
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   165
{
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   166
	gnutls_global_init ();
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   167
	gnutls_certificate_allocate_credentials (&ssl->gnutls_xcred);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   168
}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   169
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   170
gboolean
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   171
_lm_ssl_begin (LmSSL *ssl, gint fd, const gchar *server, GError **error)
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   172
{
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   173
	int ret;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   174
	gboolean auth_ok = TRUE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   175
	const int cert_type_priority[2] =
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   176
	{ GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP };
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   177
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   178
	gnutls_init (&ssl->gnutls_session, GNUTLS_CLIENT);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   179
	gnutls_set_default_priority (ssl->gnutls_session);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   180
	gnutls_certificate_type_set_priority (ssl->gnutls_session,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   181
					      cert_type_priority);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   182
	gnutls_credentials_set (ssl->gnutls_session,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   183
				GNUTLS_CRD_CERTIFICATE,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   184
				ssl->gnutls_xcred);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   185
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   186
	gnutls_transport_set_ptr (ssl->gnutls_session,
189
8ad7a25e4613 2006-12-06 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents: 161
diff changeset
   187
				  (gnutls_transport_ptr_t) fd);
137
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   188
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   189
	ret = gnutls_handshake (ssl->gnutls_session);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   190
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   191
	if (ret >= 0) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   192
		auth_ok = ssl_verify_certificate (ssl, server);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   193
	}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   194
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   195
	if (ret < 0 || !auth_ok) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   196
		char *errmsg;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   197
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   198
		gnutls_perror (ret);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   199
	
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   200
		if (!auth_ok) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   201
			errmsg = "*** GNUTLS authentication error";
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   202
		} else {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   203
			errmsg = "*** GNUTLS handshake failed";
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   204
		}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   205
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   206
		g_set_error (error, 
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   207
			     LM_ERROR, LM_ERROR_CONNECTION_OPEN,
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   208
			     errmsg);			
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   209
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   210
		return FALSE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   211
	}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   212
	
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   213
	return TRUE;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   214
}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   215
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   216
GIOStatus
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   217
_lm_ssl_read (LmSSL *ssl, gchar *buf, gint len, gsize *bytes_read)
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   218
{
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   219
	GIOStatus status;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   220
	gint      b_read;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   221
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   222
	*bytes_read = 0;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   223
	b_read = gnutls_record_recv (ssl->gnutls_session, buf, len);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   224
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   225
	if (b_read == GNUTLS_E_AGAIN) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   226
		status = G_IO_STATUS_AGAIN;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   227
	}
161
05ddf1d0440f 2006-08-01 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents: 146
diff changeset
   228
	else if (b_read == 0) {
137
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   229
		status = G_IO_STATUS_EOF;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   230
	}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   231
	else if (b_read < 0) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   232
		status = G_IO_STATUS_ERROR;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   233
	} else {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   234
		*bytes_read = (guint) b_read;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   235
		status = G_IO_STATUS_NORMAL;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   236
	}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   237
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   238
	return status;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   239
}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   240
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   241
gint
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   242
_lm_ssl_send (LmSSL *ssl, const gchar *str, gint len)
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   243
{
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   244
	gint bytes_written;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   245
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   246
	bytes_written = gnutls_record_send (ssl->gnutls_session, str, len);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   247
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   248
	while (bytes_written < 0) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   249
		if (bytes_written != GNUTLS_E_INTERRUPTED &&
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   250
		    bytes_written != GNUTLS_E_AGAIN) {
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   251
			return -1;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   252
		}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   253
	
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   254
		bytes_written = gnutls_record_send (ssl->gnutls_session, 
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   255
						    str, len);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   256
	}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   257
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   258
	return bytes_written;
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   259
}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   260
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   261
void 
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   262
_lm_ssl_close (LmSSL *ssl)
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   263
{
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   264
	gnutls_deinit (ssl->gnutls_session);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   265
	gnutls_certificate_free_credentials (ssl->gnutls_xcred);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   266
	gnutls_global_deinit ();
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   267
}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   268
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   269
void
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   270
_lm_ssl_free (LmSSL *ssl)
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   271
{
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   272
	_lm_ssl_base_free_fields (LM_SSL_BASE (ssl));
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   273
	g_free (ssl);
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   274
}
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   275
18785575aa7a 2006-04-05 Mikael Hallendal <micke@imendio.com>
hallski <hallski>
parents:
diff changeset
   276
#endif /* HAVE_GNUTLS */