1 /* -*- mode: c; c-file-style:"stroustrup"; -*- */
2
3 /*
4 * Copyright (c) 2018 Mastercard
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19
20 #include <config.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include "pkcs11lib.h"
26
27
28 #define P11SEARCH_NUM_HANDLES 64
29
30
pkcs11_new_search(pkcs11Context * p11Context,CK_ATTRIBUTE_PTR search,CK_ULONG length)31 pkcs11Search * pkcs11_new_search( pkcs11Context *p11Context, CK_ATTRIBUTE_PTR search, CK_ULONG length)
32 {
33 pkcs11Search *p11s = NULL;
34 CK_RV retCode;
35
36 p11s = calloc(1, sizeof(pkcs11Search));
37
38 if(p11s==NULL) {
39 fprintf(stderr, "Error: Can't allocate memory for pkcs11Search structure");
40 goto error;
41 }
42
43 p11s->p11Context = p11Context;
44 p11s->FindObjectsInit = p11Context->FunctionList.C_FindObjectsInit;
45 p11s->FindObjects = p11Context->FunctionList.C_FindObjects;
46 p11s->FindObjectsFinal = p11Context->FunctionList.C_FindObjectsFinal;
47
48 p11s->handle_array = calloc( P11SEARCH_NUM_HANDLES, sizeof (CK_OBJECT_HANDLE));
49
50 if(p11s->handle_array==NULL) {
51 fprintf(stderr, "Error: Can't allocate memory for pkcs11Search handle array");
52 goto error;
53 }
54
55 p11s->allocated = P11SEARCH_NUM_HANDLES;
56 p11s->count = p11s->index = 0;
57
58
59 if ( ( retCode = p11s->FindObjectsInit( p11Context->Session, search, length ) ) != CKR_OK )
60 {
61 pkcs11_error( retCode, "C_FindObjectsInit" );
62 goto error;
63 }
64
65 return p11s;
66
67 error:
68 if(p11s) {
69 if(p11s->handle_array) {
70 free(p11s->handle_array);
71 p11s->handle_array=NULL;
72 }
73 free(p11s);
74 p11s = NULL;
75 }
76
77 return p11s;
78 }
79
80
pkcs11_new_search_from_idtemplate(pkcs11Context * p11Context,pkcs11IdTemplate * idtmpl)81 pkcs11Search * pkcs11_new_search_from_idtemplate( pkcs11Context *p11Context, pkcs11IdTemplate *idtmpl)
82 {
83 pkcs11Search *p11s = NULL;
84
85 if(p11Context && idtmpl) {
86 p11s = pkcs11_new_search(p11Context, idtmpl->template, idtmpl->template_len);
87 }
88 return p11s;
89 }
90
91
92
pkcs11_fetch_next(pkcs11Search * p11s)93 CK_OBJECT_HANDLE pkcs11_fetch_next(pkcs11Search *p11s)
94 {
95
96 CK_OBJECT_HANDLE rv = 0;
97
98 if(p11s) {
99 /* have we ever executed FindObjects? */
100 if(p11s->count==0 || (p11s->count>0 && p11s->index==p11s->count) ) {
101 CK_RV retCode;
102
103 if ( ( retCode = p11s->FindObjects( p11s->p11Context->Session,
104 p11s->handle_array,
105 p11s->allocated,
106 &(p11s->count) ) ) != CKR_OK )
107 {
108 pkcs11_error( retCode, "C_FindObjects" );
109 return NULL_PTR;
110 }
111 p11s->index=0; /* reset index */
112 }
113
114 if(p11s->count>0 && p11s->index < p11s->count) {
115 rv = p11s->handle_array[p11s->index++];
116 }
117 }
118 return rv;
119
120 }
121
122
pkcs11_delete_search(pkcs11Search * p11s)123 void pkcs11_delete_search(pkcs11Search *p11s)
124 {
125
126 if(p11s) {
127 CK_RV retCode;
128
129 if ( ( retCode = p11s->FindObjectsFinal( p11s->p11Context->Session ) ) != CKR_OK ) {
130 pkcs11_error( retCode, "C_FindObjectsFinal" );
131 }
132
133 if(p11s->handle_array) {
134 free(p11s->handle_array);
135 p11s->handle_array=NULL;
136 }
137 free(p11s);
138 p11s = NULL;
139 }
140 }
141
142
143 /* high-level search functions */
144
pkcs11_object_with_class_exists(pkcs11Context * p11Context,char * label,CK_OBJECT_CLASS cla)145 static int pkcs11_object_with_class_exists(pkcs11Context *p11Context, char *label, CK_OBJECT_CLASS cla)
146 {
147
148 int rv=0;
149 pkcs11Search *search=NULL;
150 CK_OBJECT_CLASS oclass = cla;
151
152 CK_ATTRIBUTE searchTemplate[] = {
153 { CKA_CLASS, &oclass, sizeof oclass },
154 { CKA_LABEL, label, strlen(label) },
155 };
156
157 search = pkcs11_new_search( p11Context, searchTemplate, sizeof(searchTemplate) / sizeof(CK_ATTRIBUTE) );
158
159
160 if(search) { /* we just need one hit */
161 rv = pkcs11_fetch_next(search)!=0 ? 1 : 0 ;
162 pkcs11_delete_search(search);
163 }
164
165 return rv;
166 }
167
pkcs11_find_object_with_class(pkcs11Context * p11Context,char * label,CK_OBJECT_CLASS cla)168 static CK_OBJECT_HANDLE pkcs11_find_object_with_class(pkcs11Context *p11Context, char *label, CK_OBJECT_CLASS cla)
169 {
170
171 pkcs11Search *search=NULL;
172 CK_OBJECT_CLASS oclass = cla;
173 CK_OBJECT_HANDLE hndl=NULL_PTR;
174
175 CK_ATTRIBUTE searchTemplate[] = {
176 { CKA_CLASS, &oclass, sizeof oclass },
177 { CKA_LABEL, label, strlen(label) },
178 };
179
180 search = pkcs11_new_search( p11Context, searchTemplate, sizeof(searchTemplate) / sizeof(CK_ATTRIBUTE) );
181
182
183 if(search) { /* we stop by the first hit */
184
185 hndl = pkcs11_fetch_next(search);
186
187 pkcs11_delete_search(search);
188
189 }
190
191 return hndl;
192 }
193
194
pkcs11_label_exists(pkcs11Context * p11Context,char * label)195 int pkcs11_label_exists(pkcs11Context *p11Context, char *label)
196 {
197
198 int rv=0;
199 pkcs11Search *search=NULL;
200 CK_ATTRIBUTE searchTemplate[] = {
201 { CKA_LABEL, label, strlen(label) },
202 };
203
204 search = pkcs11_new_search( p11Context, searchTemplate, sizeof(searchTemplate) / sizeof(CK_ATTRIBUTE) );
205
206
207 if(search) { /* we just need one hit */
208 rv = pkcs11_fetch_next(search)!=0 ? 1 : 0 ;
209 pkcs11_delete_search(search);
210 }
211
212 return rv;
213 }
214
215
pkcs11_privatekey_exists(pkcs11Context * p11Context,char * label)216 inline int pkcs11_privatekey_exists(pkcs11Context *p11Context, char *label)
217 {
218 return pkcs11_object_with_class_exists(p11Context, label, CKO_PRIVATE_KEY);
219 }
220
pkcs11_publickey_exists(pkcs11Context * p11Context,char * label)221 inline int pkcs11_publickey_exists(pkcs11Context *p11Context, char *label)
222 {
223 return pkcs11_object_with_class_exists(p11Context, label, CKO_PUBLIC_KEY);
224 }
225
pkcs11_secretkey_exists(pkcs11Context * p11Context,char * label)226 inline int pkcs11_secretkey_exists(pkcs11Context *p11Context, char *label)
227 {
228 return pkcs11_object_with_class_exists(p11Context, label, CKO_SECRET_KEY);
229 }
230
pkcs11_certificate_exists(pkcs11Context * p11Context,char * label)231 inline int pkcs11_certificate_exists(pkcs11Context *p11Context, char *label)
232 {
233 return pkcs11_object_with_class_exists(p11Context, label, CKO_CERTIFICATE);
234 }
235
pkcs11_data_exists(pkcs11Context * p11Context,char * label)236 inline int pkcs11_data_exists(pkcs11Context *p11Context, char *label)
237 {
238 return pkcs11_object_with_class_exists(p11Context, label, CKO_DATA);
239 }
240
241
pkcs11_findkeypair(pkcs11Context * p11Context,char * label,CK_OBJECT_HANDLE_PTR hPublicKey,CK_OBJECT_HANDLE_PTR hPrivateKey)242 int pkcs11_findkeypair(pkcs11Context *p11Context, char *label, CK_OBJECT_HANDLE_PTR hPublicKey, CK_OBJECT_HANDLE_PTR hPrivateKey)
243 {
244
245 int rv=0;
246
247 *hPrivateKey = pkcs11_find_object_with_class(p11Context, label, CKO_PRIVATE_KEY);
248 *hPublicKey = pkcs11_find_object_with_class(p11Context, label, CKO_PUBLIC_KEY);
249
250 /* we need hPrivateKey. hPublicKey is optional. */
251 if (*hPrivateKey != NULL_PTR) {
252 rv++;
253 if (*hPublicKey != NULL_PTR) {
254 rv++;
255 } else {
256 fprintf(stderr, "Warning: no public key object found for label '%s'\n", label);
257 }
258 }
259
260 return rv;
261 }
262
pkcs11_findpublickey(pkcs11Context * p11Context,char * label,CK_OBJECT_HANDLE_PTR hPublicKey)263 int pkcs11_findpublickey(pkcs11Context *p11Context, char *label, CK_OBJECT_HANDLE_PTR hPublicKey)
264 {
265
266 int rv=0;
267
268 *hPublicKey = pkcs11_find_object_with_class(p11Context, label, CKO_PUBLIC_KEY);
269
270 rv = *hPublicKey!=0;
271
272 return rv;
273 }
274
pkcs11_findprivatekey(pkcs11Context * p11Context,char * label,CK_OBJECT_HANDLE_PTR hPrivateKey)275 int pkcs11_findprivatekey(pkcs11Context *p11Context, char *label, CK_OBJECT_HANDLE_PTR hPrivateKey)
276 {
277
278 int rv=0;
279
280 *hPrivateKey = pkcs11_find_object_with_class(p11Context, label, CKO_PRIVATE_KEY);
281
282 rv = *hPrivateKey!=0;
283
284 return rv;
285 }
286
pkcs11_findsecretkey(pkcs11Context * p11Context,char * label,CK_OBJECT_HANDLE_PTR hSecretKey)287 int pkcs11_findsecretkey(pkcs11Context *p11Context, char *label, CK_OBJECT_HANDLE_PTR hSecretKey)
288 {
289
290 int rv=0;
291
292 *hSecretKey = pkcs11_find_object_with_class(p11Context, label, CKO_SECRET_KEY);
293
294 rv = *hSecretKey!=0;
295
296 return rv;
297 }
298
pkcs11_findprivateorsecretkey(pkcs11Context * p11Context,char * label,CK_OBJECT_HANDLE_PTR hKey,CK_OBJECT_CLASS * oclass)299 int pkcs11_findprivateorsecretkey(pkcs11Context *p11Context, char *label, CK_OBJECT_HANDLE_PTR hKey, CK_OBJECT_CLASS *oclass)
300 {
301
302 int rv=0;
303
304 *hKey = pkcs11_find_object_with_class(p11Context, label, CKO_PRIVATE_KEY);
305
306 if(*hKey) {
307 /* good, we have our private key */
308 *oclass = CKO_PRIVATE_KEY;
309
310 } else {
311 *hKey = pkcs11_find_object_with_class(p11Context, label, CKO_SECRET_KEY);
312
313 if(*hKey) {
314 /* good, we have our secret key */
315 *oclass = CKO_SECRET_KEY;
316 }
317 }
318
319 rv = *hKey!=0;
320
321 return rv;
322 }
323
324
325 /* EOF */
326