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-public-key.h"
31 #include "gkm-session.h"
32 #include "gkm-transaction.h"
33 #include "gkm-util.h"
34
35 struct _GkmDhPublicKey {
36 GkmDhKey parent;
37 gcry_mpi_t value;
38 };
39
40 G_DEFINE_TYPE (GkmDhPublicKey, gkm_dh_public_key, GKM_TYPE_DH_KEY);
41
42 /* -----------------------------------------------------------------------------
43 * INTERNAL
44 */
45
46 static GkmObject*
factory_create_dh_public_key(GkmSession * session,GkmTransaction * transaction,CK_ATTRIBUTE_PTR attrs,CK_ULONG n_attrs)47 factory_create_dh_public_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_public_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_PUBLIC_KEY
83 */
84
85 static CK_RV
gkm_dh_public_key_real_get_attribute(GkmObject * base,GkmSession * session,CK_ATTRIBUTE * attr)86 gkm_dh_public_key_real_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE* attr)
87 {
88 GkmDhPublicKey *self = GKM_DH_PUBLIC_KEY (base);
89
90 switch (attr->type)
91 {
92
93 case CKA_CLASS:
94 return gkm_attribute_set_ulong (attr, CKO_PUBLIC_KEY);
95
96 case CKA_DERIVE:
97 return gkm_attribute_set_bool (attr, FALSE);
98
99 case CKA_ENCRYPT:
100 return gkm_attribute_set_bool (attr, FALSE);
101
102 case CKA_VERIFY:
103 return gkm_attribute_set_bool (attr, FALSE);
104
105 case CKA_VERIFY_RECOVER:
106 return gkm_attribute_set_bool (attr, FALSE);
107
108 case CKA_WRAP:
109 return gkm_attribute_set_bool (attr, FALSE);
110
111 case CKA_TRUSTED:
112 return gkm_attribute_set_bool (attr, FALSE);
113
114 case CKA_WRAP_TEMPLATE:
115 gkm_debug ("CKR_ATTRIBUTE_TYPE_INVALID: no CKA_WRAP_TEMPLATE attribute");
116 return CKR_ATTRIBUTE_TYPE_INVALID;
117
118 case CKA_VALUE:
119 return gkm_attribute_set_mpi (attr, self->value);
120 };
121
122 return GKM_OBJECT_CLASS (gkm_dh_public_key_parent_class)->get_attribute (base, session, attr);
123 }
124
125 static void
gkm_dh_public_key_init(GkmDhPublicKey * self)126 gkm_dh_public_key_init (GkmDhPublicKey *self)
127 {
128
129 }
130
131 static void
gkm_dh_public_key_finalize(GObject * obj)132 gkm_dh_public_key_finalize (GObject *obj)
133 {
134 GkmDhPublicKey *self = GKM_DH_PUBLIC_KEY (obj);
135
136 gcry_mpi_release (self->value);
137 self->value = NULL;
138
139 G_OBJECT_CLASS (gkm_dh_public_key_parent_class)->finalize (obj);
140 }
141
142 static void
gkm_dh_public_key_class_init(GkmDhPublicKeyClass * klass)143 gkm_dh_public_key_class_init (GkmDhPublicKeyClass *klass)
144 {
145 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
146 GkmObjectClass *gkm_class = GKM_OBJECT_CLASS (klass);
147
148 gkm_dh_public_key_parent_class = g_type_class_peek_parent (klass);
149
150 gobject_class->finalize = gkm_dh_public_key_finalize;
151
152 gkm_class->get_attribute = gkm_dh_public_key_real_get_attribute;
153 }
154
155 /* -----------------------------------------------------------------------------
156 * PUBLIC
157 */
158
159 GkmFactory*
gkm_dh_public_key_get_factory(void)160 gkm_dh_public_key_get_factory (void)
161 {
162 static CK_OBJECT_CLASS klass = CKO_PUBLIC_KEY;
163 static CK_KEY_TYPE type = CKK_DH;
164
165 static CK_ATTRIBUTE attributes[] = {
166 { CKA_CLASS, &klass, sizeof (klass) },
167 { CKA_KEY_TYPE, &type, sizeof (type) }
168 };
169
170 static GkmFactory factory = {
171 attributes,
172 G_N_ELEMENTS (attributes),
173 factory_create_dh_public_key
174 };
175
176 return &factory;
177 }
178
179 GkmDhPublicKey*
gkm_dh_public_key_new(GkmModule * module,GkmManager * manager,gcry_mpi_t prime,gcry_mpi_t base,gcry_mpi_t value,gpointer id,gsize n_id)180 gkm_dh_public_key_new (GkmModule *module, GkmManager *manager,
181 gcry_mpi_t prime, gcry_mpi_t base, gcry_mpi_t value,
182 gpointer id, gsize n_id)
183 {
184 GkmDhPublicKey *key;
185
186 key = g_object_new (GKM_TYPE_DH_PUBLIC_KEY,
187 "manager", manager,
188 "module", module,
189 NULL);
190
191 key->value = value;
192 gkm_dh_key_initialize (GKM_DH_KEY (key), prime, base, id, n_id);
193 return key;
194 }
195