Line data Source code
1 : /*
2 : * gnome-keyring
3 : *
4 : * Copyright (C) 2009 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 "gkm-null-key.h"
24 : #include "gkm-null-mechanism.h"
25 : #include "gkm-session.h"
26 : #include "gkm-transaction.h"
27 : #include "gkm-util.h"
28 :
29 : #include "egg/egg-libgcrypt.h"
30 : #include "egg/egg-secure-memory.h"
31 :
32 0 : EGG_SECURE_DECLARE (null_mechanism);
33 :
34 : static CK_RV
35 0 : retrieve_length (GkmSession *session, GkmObject *wrapped, gsize *length)
36 : {
37 : CK_ATTRIBUTE attr;
38 : CK_RV rv;
39 :
40 0 : attr.type = CKA_VALUE;
41 0 : attr.pValue = NULL;
42 0 : attr.ulValueLen = 0;
43 :
44 0 : rv = gkm_object_get_attribute (wrapped, session, &attr);
45 0 : if (rv == CKR_OK)
46 0 : *length = attr.ulValueLen;
47 0 : return rv;
48 : }
49 :
50 : static CK_RV
51 0 : retrieve_value (GkmSession *session, GkmObject *wrapped,
52 : gpointer *value, gsize *n_value)
53 : {
54 : CK_ATTRIBUTE attr;
55 : CK_RV rv;
56 :
57 0 : rv = retrieve_length (session, wrapped, n_value);
58 0 : if (rv != CKR_OK)
59 0 : return rv;
60 :
61 0 : attr.type = CKA_VALUE;
62 0 : attr.pValue = egg_secure_alloc (*n_value);
63 0 : attr.ulValueLen = *n_value;
64 :
65 0 : rv = gkm_object_get_attribute (wrapped, session, &attr);
66 0 : if (rv == CKR_OK)
67 0 : *value = attr.pValue;
68 : else
69 0 : egg_secure_free (attr.pValue);
70 :
71 0 : return rv;
72 : }
73 :
74 : CK_RV
75 0 : gkm_null_mechanism_wrap (GkmSession *session, CK_MECHANISM_PTR mech,
76 : GkmObject *wrapper, GkmObject *wrapped,
77 : CK_BYTE_PTR output, CK_ULONG_PTR n_output)
78 : {
79 : gpointer value;
80 : gsize n_value;
81 : CK_RV rv;
82 :
83 0 : g_return_val_if_fail (GKM_IS_SESSION (session), CKR_GENERAL_ERROR);
84 0 : g_return_val_if_fail (mech, CKR_GENERAL_ERROR);
85 0 : g_return_val_if_fail (mech->mechanism == CKM_G_NULL, CKR_GENERAL_ERROR);
86 0 : g_return_val_if_fail (GKM_IS_OBJECT (wrapped), CKR_GENERAL_ERROR);
87 0 : g_return_val_if_fail (n_output, CKR_GENERAL_ERROR);
88 :
89 0 : if (!GKM_IS_NULL_KEY (wrapper))
90 0 : return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
91 :
92 : /* They just want the length */
93 0 : if (!output) {
94 0 : rv = retrieve_length (session, wrapped, &n_value);
95 0 : if (rv == CKR_OK)
96 0 : *n_output = n_value;
97 0 : return rv;
98 : }
99 :
100 0 : if (mech->ulParameterLen)
101 0 : return CKR_MECHANISM_PARAM_INVALID;
102 :
103 0 : rv = retrieve_value (session, wrapped, &value, &n_value);
104 0 : if (rv != CKR_OK)
105 0 : return rv;
106 :
107 0 : rv = gkm_util_return_data (output, n_output, value, n_value);
108 0 : egg_secure_free (value);
109 0 : return rv;
110 : }
111 :
112 : CK_RV
113 18 : gkm_null_mechanism_unwrap (GkmSession *session, CK_MECHANISM_PTR mech,
114 : GkmObject *wrapper, CK_VOID_PTR input, CK_ULONG n_input,
115 : CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs,
116 : GkmObject **unwrapped)
117 : {
118 : CK_ATTRIBUTE attr;
119 : GArray *array;
120 : GkmTransaction *transaction;
121 :
122 18 : g_return_val_if_fail (GKM_IS_SESSION (session), CKR_GENERAL_ERROR);
123 18 : g_return_val_if_fail (mech, CKR_GENERAL_ERROR);
124 18 : g_return_val_if_fail (mech->mechanism == CKM_G_NULL, CKR_GENERAL_ERROR);
125 18 : g_return_val_if_fail (GKM_IS_OBJECT (wrapper), CKR_GENERAL_ERROR);
126 :
127 18 : if (!GKM_IS_NULL_KEY (wrapper))
128 0 : return CKR_WRAPPING_KEY_TYPE_INCONSISTENT;
129 :
130 18 : if (mech->ulParameterLen)
131 0 : return CKR_MECHANISM_PARAM_INVALID;
132 :
133 : /* Now setup the attributes with our new value */
134 18 : array = g_array_new (FALSE, FALSE, sizeof (CK_ATTRIBUTE));
135 :
136 : /* Prepend the value */
137 18 : attr.type = CKA_VALUE;
138 18 : attr.pValue = input;
139 18 : attr.ulValueLen = n_input;
140 18 : g_array_append_val (array, attr);
141 :
142 : /* Add the remainder of the attributes */
143 18 : g_array_append_vals (array, attrs, n_attrs);
144 :
145 18 : transaction = gkm_transaction_new ();
146 :
147 : /* Now create an object with these attributes */
148 36 : *unwrapped = gkm_session_create_object_for_attributes (session, transaction,
149 18 : (CK_ATTRIBUTE_PTR)array->data, array->len);
150 :
151 18 : g_array_free (array, TRUE);
152 :
153 18 : return gkm_transaction_complete_and_unref (transaction);
154 : }
|