Git init
[profile/ivi/libsoup2.4.git] / libsoup / soup-ssl.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-ssl.c: temporary ssl integration
4  *
5  * Copyright (C) 2010 Red Hat, Inc.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <gio/gio.h>
13
14 #include "soup-ssl.h"
15 #include "soup-misc.h"
16
17 const gboolean soup_ssl_supported = TRUE;
18
19 struct SoupSSLCredentials {
20         GList *ca_list;
21         GTlsCertificateFlags validation_flags;
22         GTlsCertificate *certificate;
23 };
24
25 SoupSSLCredentials *
26 soup_ssl_get_client_credentials (const char *ca_file)
27 {
28         SoupSSLCredentials *creds;
29
30         creds = g_slice_new0 (SoupSSLCredentials);
31
32         if (ca_file) {
33                 GError *error = NULL;
34
35                 creds->ca_list = g_tls_certificate_list_new_from_file (ca_file, &error);
36                 if (error) {
37                         if (!g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE)) {
38                                 g_warning ("Could not set SSL credentials from '%s': %s",
39                                            ca_file, error->message);
40                         }
41                         g_error_free (error);
42                 }
43                 creds->validation_flags = G_TLS_CERTIFICATE_VALIDATE_ALL;
44         }
45
46         return creds;
47 }
48
49 gboolean
50 soup_ssl_credentials_verify_certificate (SoupSSLCredentials   *creds,
51                                          GTlsCertificate      *cert,
52                                          GTlsCertificateFlags  errors)
53 {
54         errors = errors & creds->validation_flags;
55
56         if (errors & G_TLS_CERTIFICATE_UNKNOWN_CA) {
57                 GList *ca;
58
59                 for (ca = creds->ca_list; ca; ca = ca->next) {
60                         if ((g_tls_certificate_verify (cert, NULL, ca->data) & G_TLS_CERTIFICATE_UNKNOWN_CA) == 0) {
61                                 errors &= ~G_TLS_CERTIFICATE_UNKNOWN_CA;
62                                 break;
63                         }
64                 }
65         }
66
67         return errors == 0;
68 }
69
70 void
71 soup_ssl_free_client_credentials (SoupSSLCredentials *client_creds)
72 {
73         GList *c;
74
75         for (c = client_creds->ca_list; c; c = c->next)
76                 g_object_unref (c->data);
77         g_list_free (client_creds->ca_list);
78         g_slice_free (SoupSSLCredentials, client_creds);
79 }
80
81 SoupSSLCredentials *
82 soup_ssl_get_server_credentials (const char *cert_file, const char *key_file)
83 {
84         SoupSSLCredentials *creds;
85         GError *error = NULL;
86
87         creds = g_slice_new0 (SoupSSLCredentials);
88
89         creds->certificate = g_tls_certificate_new_from_files (cert_file, key_file, &error);
90         if (!creds->certificate) {
91                 g_warning ("Could not read SSL certificate from '%s': %s",
92                            cert_file, error->message);
93                 g_error_free (error);
94                 g_slice_free (SoupSSLCredentials, creds);
95                 return NULL;
96         }
97
98         return creds;
99 }
100
101 GTlsCertificate *
102 soup_ssl_credentials_get_certificate (SoupSSLCredentials *creds)
103 {
104         return creds->certificate;
105 }
106
107 void
108 soup_ssl_free_server_credentials (SoupSSLCredentials *server_creds)
109 {
110         g_object_unref (server_creds->certificate);
111         g_slice_free (SoupSSLCredentials, server_creds);
112 }
113
114 /**
115  * SOUP_SSL_ERROR:
116  *
117  * A #GError domain representing an SSL error. Used with #SoupSSLError.
118  **/
119 /**
120  * soup_ssl_error_quark:
121  *
122  * The quark used as %SOUP_SSL_ERROR
123  *
124  * Return value: The quark used as %SOUP_SSL_ERROR
125  **/
126 GQuark
127 soup_ssl_error_quark (void)
128 {
129         static GQuark error;
130         if (!error)
131                 error = g_quark_from_static_string ("soup_ssl_error_quark");
132         return error;
133 }
134
135 /**
136  * SoupSSLError:
137  * @SOUP_SSL_ERROR_HANDSHAKE_NEEDS_READ: Internal error. Never exposed
138  * outside of libsoup.
139  * @SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE: Internal error. Never exposed
140  * outside of libsoup.
141  * @SOUP_SSL_ERROR_CERTIFICATE: Indicates an error validating an SSL
142  * certificate
143  *
144  * SSL-related I/O errors.
145  **/