1 /*
2 * gnome-keyring
3 *
4 * Copyright (C) 2008 Stefan Walter
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
21 #include "config.h"
22
23 #include "pkcs11/pkcs11.h"
24
25 #include "gkm-attributes.h"
26 #include "gkm-crypto.h"
27 #define DEBUG_FLAG GKM_DEBUG_OBJECT
28 #include "gkm-debug.h"
29 #include "gkm-factory.h"
30 #include "gkm-dh-private-key.h"
31 #include "gkm-session.h"
32 #include "gkm-transaction.h"
33 #include "gkm-util.h"
34
35 struct _GkmDhPrivateKey {
36 GkmDhKey parent;
37 gcry_mpi_t value;
38 };
39
40 G_DEFINE_TYPE (GkmDhPrivateKey, gkm_dh_private_key, GKM_TYPE_DH_KEY);
41
42 /* -----------------------------------------------------------------------------
43 * INTERNAL
44 */
45
46 static GkmObject*
factory_create_dh_private_key(GkmSession * session,GkmTransaction * transaction,CK_ATTRIBUTE_PTR attrs,CK_ULONG n_attrs)47 factory_create_dh_private_key (GkmSession *session, GkmTransaction *transaction,
48 CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs)
49 {
50 GkmManager *manager;
51 gcry_mpi_t prime = NULL;
52 gcry_mpi_t base = NULL;
53 gcry_mpi_t value = NULL;
54 CK_ATTRIBUTE_PTR idattr;
55 GkmObject *object;
56
57 if (!gkm_attributes_find_mpi (attrs, n_attrs, CKA_PRIME, &prime) ||
58 !gkm_attributes_find_mpi (attrs, n_attrs, CKA_BASE, &base) ||
59 !gkm_attributes_find_mpi (attrs, n_attrs, CKA_VALUE, &value)) {
60 gcry_mpi_release (prime);
61 gcry_mpi_release (base);
62 gcry_mpi_release (value);
63 gkm_transaction_fail (transaction, CKR_TEMPLATE_INCOMPLETE);
64 return NULL;
65 }
66
67 manager = gkm_manager_for_template (attrs, n_attrs, session);
68 idattr = gkm_attributes_find (attrs, n_attrs, CKA_ID);
69
70 object = GKM_OBJECT (gkm_dh_private_key_new (gkm_session_get_module (session),
71 manager, prime, base, value,
72 idattr ? g_memdup (idattr->pValue, idattr->ulValueLen) : NULL,
73 idattr ? idattr->ulValueLen : 0));
74 gkm_attributes_consume (attrs, n_attrs, CKA_PRIME, CKA_BASE, CKA_VALUE, G_MAXULONG);
75
76 gkm_session_complete_object_creation (session, transaction, object,
77 TRUE, attrs, n_attrs);
78 return object;
79 }
80
81 /* -----------------------------------------------------------------------------
82 * DH_PRIVATE_KEY
83 */
84
85 static CK_RV
gkm_dh_private_key_real_get_attribute(GkmObject * base,GkmSession * session,CK_ATTRIBUTE * attr)86 gkm_dh_private_key_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE* attr)
87 {
88 GkmDhPrivateKey *self = GKM_DH_PRIVATE_KEY (base);
89
90 switch (attr->type)
91 {
92
93 case CKA_CLASS:
94 return gkm_attribute_set_ulong (attr, CKO_PRIVATE_KEY);
95
96 case CKA_PRIVATE:
97 return gkm_attribute_set_bool (attr, TRUE);
98
99 case CKA_SENSITIVE:
100 return gkm_attribute_set_bool (attr, FALSE);
101
102 case CKA_DECRYPT:
103 return gkm_attribute_set_bool (attr, FALSE);
104
105 case CKA_SIGN:
106 return gkm_attribute_set_bool (attr, FALSE);
107
108 case CKA_SIGN_RECOVER:
109 return gkm_attribute_set_bool (attr, FALSE);
110
111 case CKA_DERIVE:
112 return gkm_attribute_set_bool (attr, TRUE);
113
114 case CKA_UNWRAP:
115 return gkm_attribute_set_bool (attr, FALSE);
116
117 case CKA_EXTRACTABLE:
118 return gkm_attribute_set_bool (attr, TRUE);
119
120 case CKA_ALWAYS_SENSITIVE:
121 return gkm_attribute_set_bool (attr, FALSE);
122
123 case CKA_NEVER_EXTRACTABLE:
124 return gkm_attribute_set_bool (attr, FALSE);
125
126 case CKA_WRAP_WITH_TRUSTED:
127 return gkm_attribute_set_bool (attr, FALSE);
128
129 case CKA_UNWRAP_TEMPLATE:
130 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: no CKA_UNWRAP_TEMPLATE attribute");
131 return CKR_ATTRIBUTE_TYPE_INVALID;
132
133 case CKA_ALWAYS_AUTHENTICATE:
134 return gkm_attribute_set_bool (attr, FALSE);
135
136 case CKA_VALUE:
137 return gkm_attribute_set_mpi (attr, self->value);
138
139 case CKA_VALUE_BITS:
140 return gkm_attribute_set_ulong (attr, gcry_mpi_get_nbits (self->value));
141 };
142
143 return GKM_OBJECT_CLASS (gkm_dh_private_key_parent_class)->get_attribute (base, session, attr);
144 }
145
146 static void
gkm_dh_private_key_init(GkmDhPrivateKey * self)147 gkm_dh_private_key_init (GkmDhPrivateKey *self)
148 {
149
150 }
151
152 static void
gkm_dh_private_key_finalize(GObject * obj)153 gkm_dh_private_key_finalize (GObject *obj)
154 {
155 GkmDhPrivateKey *self = GKM_DH_PRIVATE_KEY (obj);
156
157 gcry_mpi_release (self->value);
158 self->value = NULL;
159
160 G_OBJECT_CLASS (gkm_dh_private_key_parent_class)->finalize (obj);
161 }
162
163 static void
gkm_dh_private_key_class_init(GkmDhPrivateKeyClass * klass)164 gkm_dh_private_key_class_init (GkmDhPrivateKeyClass *klass)
165 {
166 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
167 GkmObjectClass *gkm_class = GKM_OBJECT_CLASS (klass);
168
169 gkm_dh_private_key_parent_class = g_type_class_peek_parent (klass);
170
171 gobject_class->finalize = gkm_dh_private_key_finalize;
172
173 gkm_class->get_attribute = gkm_dh_private_key_real_get_attribute;
174 }
175
176 /* -----------------------------------------------------------------------------
177 * PRIVATE
178 */
179
180 GkmFactory*
gkm_dh_private_key_get_factory(void)181 gkm_dh_private_key_get_factory (void)
182 {
183 static CK_OBJECT_CLASS klass = CKO_PRIVATE_KEY;
184 static CK_KEY_TYPE type = CKK_DH;
185
186 static CK_ATTRIBUTE attributes[] = {
187 { CKA_CLASS, &klass, sizeof (klass) },
188 { CKA_KEY_TYPE, &type, sizeof (type) }
189 };
190
191 static GkmFactory factory = {
192 attributes,
193 G_N_ELEMENTS (attributes),
194 factory_create_dh_private_key
195 };
196
197 return &factory;
198 }
199
200 GkmDhPrivateKey*
gkm_dh_private_key_new(GkmModule * module,GkmManager * manager,gcry_mpi_t prime,gcry_mpi_t base,gcry_mpi_t value,gpointer id,gsize n_id)201 gkm_dh_private_key_new (GkmModule *module, GkmManager *manager,
202 gcry_mpi_t prime, gcry_mpi_t base, gcry_mpi_t value,
203 gpointer id, gsize n_id)
204 {
205 GkmDhPrivateKey *key;
206
207 key = g_object_new (GKM_TYPE_DH_PRIVATE_KEY,
208 "manager", manager,
209 "module", module,
210 NULL);
211
212 gkm_dh_key_initialize (GKM_DH_KEY (key), prime, base, id, n_id);
213 key->value = value;
214 return key;
215 }
216
217 gcry_mpi_t
gkm_dh_private_key_get_value(GkmDhPrivateKey * self)218 gkm_dh_private_key_get_value (GkmDhPrivateKey *self)
219 {
220 g_return_val_if_fail (GKM_IS_DH_PRIVATE_KEY (self), NULL);
221 return self->value;
222 }
223