Line data Source code
1 : /*
2 : * gnome-keyring
3 : *
4 : * Copyright (C) 2011 Collabora Ltd.
5 : *
6 : * This program is free software; you can redistribute it and/or modify
7 : * it under the terms of the GNU Lesser General Public License as
8 : * published by the Free Software Foundation; either version 2.1 of
9 : * the License, or (at your option) any later version.
10 : *
11 : * This program is distributed in the hope that it will be useful, but
12 : * WITHOUT ANY WARRANTY; without even the implied warranty of
13 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : * Lesser General Public License for more details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public
17 : * License along with this program; if not, see
18 : * <http://www.gnu.org/licenses/>.
19 : *
20 : * Author: Stef Walter <stefw@collabora.co.uk>
21 : */
22 :
23 : #include "config.h"
24 :
25 : #include "gkd-secret-exchange.h"
26 : #include "gkd-secret-secret.h"
27 : #include "gkd-secret-service.h"
28 : #include "gkd-secret-session.h"
29 :
30 : #include <gcr/gcr-base.h>
31 :
32 : #include <glib/gi18n.h>
33 :
34 : #include <string.h>
35 :
36 : enum {
37 : PROP_0,
38 : PROP_CALLER,
39 : PROP_SERVICE,
40 : };
41 :
42 : struct _GkdSecretExchange {
43 : GcrSecretExchange parent;
44 : gchar *caller;
45 : GkdSecretService *service;
46 : GkdSecretSession *session;
47 : GkdSecretSecret *last_secret;
48 : };
49 :
50 : struct _GkdSecretExchangeClass {
51 : GcrSecretExchangeClass parent_class;
52 : };
53 :
54 10 : G_DEFINE_TYPE (GkdSecretExchange, gkd_secret_exchange, GCR_TYPE_SECRET_EXCHANGE);
55 :
56 : static void
57 1 : gkd_secret_exchange_init (GkdSecretExchange *self)
58 : {
59 :
60 1 : }
61 :
62 : static void
63 2 : gkd_secret_exchange_set_property (GObject *obj,
64 : guint prop_id,
65 : const GValue *value,
66 : GParamSpec *pspec)
67 : {
68 2 : GkdSecretExchange *self = GKD_SECRET_EXCHANGE (obj);
69 :
70 2 : switch (prop_id) {
71 1 : case PROP_CALLER:
72 1 : g_return_if_fail (!self->caller);
73 1 : self->caller = g_value_dup_string (value);
74 1 : break;
75 1 : case PROP_SERVICE:
76 1 : g_return_if_fail (!self->service);
77 1 : self->service = g_value_get_object (value);
78 1 : g_return_if_fail (self->service);
79 1 : g_object_add_weak_pointer (G_OBJECT (self->service),
80 1 : (gpointer*)&(self->service));
81 1 : break;
82 0 : default:
83 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
84 0 : break;
85 : }
86 : }
87 :
88 : static void
89 0 : gkd_secret_exchange_get_property (GObject *obj,
90 : guint prop_id,
91 : GValue *value,
92 : GParamSpec *pspec)
93 : {
94 0 : GkdSecretExchange *self = GKD_SECRET_EXCHANGE (obj);
95 :
96 0 : switch (prop_id) {
97 0 : case PROP_CALLER:
98 0 : g_value_set_string (value, self->caller);
99 0 : break;
100 0 : case PROP_SERVICE:
101 0 : g_value_set_object (value, self->service);
102 0 : break;
103 0 : default:
104 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
105 0 : break;
106 : }
107 0 : }
108 :
109 : static void
110 1 : gkd_secret_exchange_finalize (GObject *obj)
111 : {
112 1 : GkdSecretExchange *self = GKD_SECRET_EXCHANGE (obj);
113 :
114 1 : if (self->service) {
115 1 : g_object_remove_weak_pointer (G_OBJECT (self->service),
116 1 : (gpointer*)&(self->service));
117 1 : self->service = NULL;
118 : }
119 :
120 1 : g_clear_object (&self->session);
121 1 : gkd_secret_secret_free (self->last_secret);
122 1 : g_free (self->caller);
123 :
124 1 : G_OBJECT_CLASS (gkd_secret_exchange_parent_class)->finalize (obj);
125 1 : }
126 :
127 : static gboolean
128 1 : gkd_secret_exchange_generate_exchange_key (GcrSecretExchange *exchange,
129 : const gchar *scheme,
130 : guchar **public_key,
131 : gsize *n_public_key)
132 : {
133 1 : GkdSecretExchange *self = GKD_SECRET_EXCHANGE (exchange);
134 :
135 1 : g_return_val_if_fail (self->service != NULL, FALSE);
136 :
137 1 : g_clear_object (&self->session);
138 1 : self->session = gkd_secret_session_new (self->service, self->caller);
139 1 : *public_key = gkd_secret_session_begin (self->session,
140 : "ietf-ike-grp-modp-1536",
141 : n_public_key);
142 1 : return (*public_key != NULL) ? TRUE : FALSE;
143 : }
144 :
145 : static gboolean
146 1 : gkd_secret_exchange_derive_transport_key (GcrSecretExchange *exchange,
147 : const guchar *peer,
148 : gsize n_peer)
149 : {
150 1 : GkdSecretExchange *self = GKD_SECRET_EXCHANGE (exchange);
151 :
152 1 : return gkd_secret_session_complete (self->session, peer, n_peer);
153 : }
154 :
155 : static gboolean
156 0 : gkd_secret_exchange_encrypt_transport_data (GcrSecretExchange *exchange,
157 : GckAllocator allocator,
158 : const guchar *plain_text,
159 : gsize n_plain_text,
160 : guchar **parameter,
161 : gsize *n_parameter,
162 : guchar **cipher_text,
163 : gsize *n_cipher_text)
164 : {
165 0 : g_warning ("Not implemented: a GkdSecretExchange was used to encrypt a secret");
166 0 : return FALSE;
167 : }
168 :
169 : static gboolean
170 1 : gkd_secret_exchange_decrypt_transport_data (GcrSecretExchange *exchange,
171 : GckAllocator allocator,
172 : const guchar *cipher_text,
173 : gsize n_cipher_text,
174 : const guchar *parameter,
175 : gsize n_parameter,
176 : guchar **plain_text,
177 : gsize *n_plain_text)
178 : {
179 1 : GkdSecretExchange *self = GKD_SECRET_EXCHANGE (exchange);
180 :
181 1 : gkd_secret_secret_free (self->last_secret);
182 :
183 1 : self->last_secret = gkd_secret_secret_new (self->session,
184 : parameter, n_parameter,
185 : cipher_text, n_cipher_text);
186 :
187 1 : *plain_text = NULL;
188 1 : *n_plain_text = 0;
189 1 : return TRUE;
190 : }
191 :
192 : static void
193 1 : gkd_secret_exchange_class_init (GkdSecretExchangeClass *klass)
194 : {
195 1 : GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
196 1 : GcrSecretExchangeClass *exchange_class = GCR_SECRET_EXCHANGE_CLASS (klass);
197 :
198 1 : gobject_class->finalize = gkd_secret_exchange_finalize;
199 1 : gobject_class->get_property = gkd_secret_exchange_get_property;
200 1 : gobject_class->set_property = gkd_secret_exchange_set_property;
201 :
202 1 : exchange_class->generate_exchange_key = gkd_secret_exchange_generate_exchange_key;
203 1 : exchange_class->derive_transport_key = gkd_secret_exchange_derive_transport_key;
204 1 : exchange_class->encrypt_transport_data = gkd_secret_exchange_encrypt_transport_data;
205 1 : exchange_class->decrypt_transport_data = gkd_secret_exchange_decrypt_transport_data;
206 :
207 1 : g_object_class_install_property (gobject_class, PROP_CALLER,
208 : g_param_spec_string ("caller", "Caller", "DBus caller name",
209 : NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY ));
210 :
211 1 : g_object_class_install_property (gobject_class, PROP_SERVICE,
212 : g_param_spec_object ("service", "Service", "Service which owns this session",
213 : GKD_SECRET_TYPE_SERVICE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
214 1 : }
215 :
216 : GkdSecretExchange *
217 1 : gkd_secret_exchange_new (GkdSecretService *service,
218 : const gchar *caller)
219 : {
220 1 : return g_object_new (GKD_TYPE_SECRET_EXCHANGE,
221 : "service", service,
222 : "caller", caller,
223 : NULL);
224 : }
225 :
226 : GkdSecretSecret *
227 1 : gkd_secret_exchange_take_last_secret (GkdSecretExchange *self)
228 : {
229 : GkdSecretSecret *secret;
230 :
231 1 : g_return_val_if_fail (GKD_IS_SECRET_EXCHANGE (self), NULL);
232 :
233 1 : secret = self->last_secret;
234 1 : self->last_secret = NULL;
235 1 : return secret;
236 : }
|