1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert * Copyright (c) 2004-2006, Stockholms universitet
4*7f2fe78bSCy Schubert * (Stockholm University, Stockholm Sweden)
5*7f2fe78bSCy Schubert * All rights reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Redistribution and use in source and binary forms, with or without
8*7f2fe78bSCy Schubert * modification, are permitted provided that the following conditions
9*7f2fe78bSCy Schubert * are met:
10*7f2fe78bSCy Schubert *
11*7f2fe78bSCy Schubert * 1. Redistributions of source code must retain the above copyright
12*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer.
13*7f2fe78bSCy Schubert *
14*7f2fe78bSCy Schubert * 2. Redistributions in binary form must reproduce the above copyright
15*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer in the
16*7f2fe78bSCy Schubert * documentation and/or other materials provided with the distribution.
17*7f2fe78bSCy Schubert *
18*7f2fe78bSCy Schubert * 3. Neither the name of the university nor the names of its contributors
19*7f2fe78bSCy Schubert * may be used to endorse or promote products derived from this software
20*7f2fe78bSCy Schubert * without specific prior written permission.
21*7f2fe78bSCy Schubert *
22*7f2fe78bSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23*7f2fe78bSCy Schubert * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24*7f2fe78bSCy Schubert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25*7f2fe78bSCy Schubert * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26*7f2fe78bSCy Schubert * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27*7f2fe78bSCy Schubert * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28*7f2fe78bSCy Schubert * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29*7f2fe78bSCy Schubert * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30*7f2fe78bSCy Schubert * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31*7f2fe78bSCy Schubert * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32*7f2fe78bSCy Schubert * POSSIBILITY OF SUCH DAMAGE.
33*7f2fe78bSCy Schubert */
34*7f2fe78bSCy Schubert
35*7f2fe78bSCy Schubert #include "k5-platform.h"
36*7f2fe78bSCy Schubert
37*7f2fe78bSCy Schubert #include <openssl/err.h>
38*7f2fe78bSCy Schubert #include <openssl/evp.h>
39*7f2fe78bSCy Schubert #include <openssl/pem.h>
40*7f2fe78bSCy Schubert #include <openssl/rand.h>
41*7f2fe78bSCy Schubert #include <openssl/x509.h>
42*7f2fe78bSCy Schubert
43*7f2fe78bSCy Schubert #include <ctype.h>
44*7f2fe78bSCy Schubert #include <pwd.h>
45*7f2fe78bSCy Schubert
46*7f2fe78bSCy Schubert #include <pkcs11.h>
47*7f2fe78bSCy Schubert
48*7f2fe78bSCy Schubert #if OPENSSL_VERSION_NUMBER < 0x10100000L
49*7f2fe78bSCy Schubert #define EVP_PKEY_get0_RSA(key) ((key)->pkey.rsa)
50*7f2fe78bSCy Schubert #define RSA_PKCS1_OpenSSL RSA_PKCS1_SSLeay
51*7f2fe78bSCy Schubert #define RSA_get0_key compat_rsa_get0_key
52*7f2fe78bSCy Schubert static void
compat_rsa_get0_key(const RSA * rsa,const BIGNUM ** n,const BIGNUM ** e,const BIGNUM ** d)53*7f2fe78bSCy Schubert compat_rsa_get0_key(const RSA *rsa, const BIGNUM **n, const BIGNUM **e,
54*7f2fe78bSCy Schubert const BIGNUM **d)
55*7f2fe78bSCy Schubert {
56*7f2fe78bSCy Schubert if (n != NULL)
57*7f2fe78bSCy Schubert *n = rsa->n;
58*7f2fe78bSCy Schubert if (e != NULL)
59*7f2fe78bSCy Schubert *e = rsa->e;
60*7f2fe78bSCy Schubert if (d != NULL)
61*7f2fe78bSCy Schubert *d = rsa->d;
62*7f2fe78bSCy Schubert }
63*7f2fe78bSCy Schubert #endif
64*7f2fe78bSCy Schubert
65*7f2fe78bSCy Schubert #define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \
66*7f2fe78bSCy Schubert { \
67*7f2fe78bSCy Schubert unsigned char *p; \
68*7f2fe78bSCy Schubert (BL) = i2d_##T((S), NULL); \
69*7f2fe78bSCy Schubert if ((BL) <= 0) { \
70*7f2fe78bSCy Schubert (R) = EINVAL; \
71*7f2fe78bSCy Schubert } else { \
72*7f2fe78bSCy Schubert (B) = malloc((BL)); \
73*7f2fe78bSCy Schubert if ((B) == NULL) { \
74*7f2fe78bSCy Schubert (R) = ENOMEM; \
75*7f2fe78bSCy Schubert } else { \
76*7f2fe78bSCy Schubert p = (B); \
77*7f2fe78bSCy Schubert (R) = 0; \
78*7f2fe78bSCy Schubert (BL) = i2d_##T((S), &p); \
79*7f2fe78bSCy Schubert if ((BL) <= 0) { \
80*7f2fe78bSCy Schubert free((B)); \
81*7f2fe78bSCy Schubert (B) = NULL; \
82*7f2fe78bSCy Schubert (R) = EINVAL; \
83*7f2fe78bSCy Schubert } \
84*7f2fe78bSCy Schubert } \
85*7f2fe78bSCy Schubert } \
86*7f2fe78bSCy Schubert }
87*7f2fe78bSCy Schubert
88*7f2fe78bSCy Schubert /* RCSID("$Id: main.c,v 1.24 2006/01/11 12:42:53 lha Exp $"); */
89*7f2fe78bSCy Schubert
90*7f2fe78bSCy Schubert #define OBJECT_ID_MASK 0xfff
91*7f2fe78bSCy Schubert #define HANDLE_OBJECT_ID(h) ((h) & OBJECT_ID_MASK)
92*7f2fe78bSCy Schubert #define OBJECT_ID(obj) HANDLE_OBJECT_ID((obj)->object_handle)
93*7f2fe78bSCy Schubert
94*7f2fe78bSCy Schubert struct st_attr {
95*7f2fe78bSCy Schubert CK_ATTRIBUTE attribute;
96*7f2fe78bSCy Schubert int secret;
97*7f2fe78bSCy Schubert };
98*7f2fe78bSCy Schubert
99*7f2fe78bSCy Schubert struct st_object {
100*7f2fe78bSCy Schubert CK_OBJECT_HANDLE object_handle;
101*7f2fe78bSCy Schubert struct st_attr *attrs;
102*7f2fe78bSCy Schubert int num_attributes;
103*7f2fe78bSCy Schubert enum {
104*7f2fe78bSCy Schubert STO_T_CERTIFICATE,
105*7f2fe78bSCy Schubert STO_T_PRIVATE_KEY,
106*7f2fe78bSCy Schubert STO_T_PUBLIC_KEY
107*7f2fe78bSCy Schubert } type;
108*7f2fe78bSCy Schubert union {
109*7f2fe78bSCy Schubert X509 *cert;
110*7f2fe78bSCy Schubert EVP_PKEY *public_key;
111*7f2fe78bSCy Schubert struct {
112*7f2fe78bSCy Schubert char *file;
113*7f2fe78bSCy Schubert EVP_PKEY *key;
114*7f2fe78bSCy Schubert X509 *cert;
115*7f2fe78bSCy Schubert } private_key;
116*7f2fe78bSCy Schubert } u;
117*7f2fe78bSCy Schubert };
118*7f2fe78bSCy Schubert
119*7f2fe78bSCy Schubert static struct soft_token {
120*7f2fe78bSCy Schubert CK_VOID_PTR application;
121*7f2fe78bSCy Schubert CK_NOTIFY notify;
122*7f2fe78bSCy Schubert struct {
123*7f2fe78bSCy Schubert struct st_object **objs;
124*7f2fe78bSCy Schubert int num_objs;
125*7f2fe78bSCy Schubert } object;
126*7f2fe78bSCy Schubert struct {
127*7f2fe78bSCy Schubert int hardware_slot;
128*7f2fe78bSCy Schubert int app_error_fatal;
129*7f2fe78bSCy Schubert int login_done;
130*7f2fe78bSCy Schubert } flags;
131*7f2fe78bSCy Schubert int open_sessions;
132*7f2fe78bSCy Schubert struct session_state {
133*7f2fe78bSCy Schubert CK_SESSION_HANDLE session_handle;
134*7f2fe78bSCy Schubert
135*7f2fe78bSCy Schubert struct {
136*7f2fe78bSCy Schubert CK_ATTRIBUTE *attributes;
137*7f2fe78bSCy Schubert CK_ULONG num_attributes;
138*7f2fe78bSCy Schubert int next_object;
139*7f2fe78bSCy Schubert } find;
140*7f2fe78bSCy Schubert
141*7f2fe78bSCy Schubert int encrypt_object;
142*7f2fe78bSCy Schubert CK_MECHANISM_PTR encrypt_mechanism;
143*7f2fe78bSCy Schubert int decrypt_object;
144*7f2fe78bSCy Schubert CK_MECHANISM_PTR decrypt_mechanism;
145*7f2fe78bSCy Schubert int sign_object;
146*7f2fe78bSCy Schubert CK_MECHANISM_PTR sign_mechanism;
147*7f2fe78bSCy Schubert int verify_object;
148*7f2fe78bSCy Schubert CK_MECHANISM_PTR verify_mechanism;
149*7f2fe78bSCy Schubert int digest_object;
150*7f2fe78bSCy Schubert } state[10];
151*7f2fe78bSCy Schubert #define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0]))
152*7f2fe78bSCy Schubert FILE *logfile;
153*7f2fe78bSCy Schubert CK_SESSION_HANDLE next_session_handle;
154*7f2fe78bSCy Schubert } soft_token;
155*7f2fe78bSCy Schubert
156*7f2fe78bSCy Schubert static void
application_error(const char * fmt,...)157*7f2fe78bSCy Schubert application_error(const char *fmt, ...)
158*7f2fe78bSCy Schubert {
159*7f2fe78bSCy Schubert va_list ap;
160*7f2fe78bSCy Schubert va_start(ap, fmt);
161*7f2fe78bSCy Schubert vprintf(fmt, ap);
162*7f2fe78bSCy Schubert va_end(ap);
163*7f2fe78bSCy Schubert if (soft_token.flags.app_error_fatal)
164*7f2fe78bSCy Schubert abort();
165*7f2fe78bSCy Schubert }
166*7f2fe78bSCy Schubert
167*7f2fe78bSCy Schubert static void
st_logf(const char * fmt,...)168*7f2fe78bSCy Schubert st_logf(const char *fmt, ...)
169*7f2fe78bSCy Schubert {
170*7f2fe78bSCy Schubert va_list ap;
171*7f2fe78bSCy Schubert if (soft_token.logfile == NULL)
172*7f2fe78bSCy Schubert return;
173*7f2fe78bSCy Schubert va_start(ap, fmt);
174*7f2fe78bSCy Schubert vfprintf(soft_token.logfile, fmt, ap);
175*7f2fe78bSCy Schubert va_end(ap);
176*7f2fe78bSCy Schubert fflush(soft_token.logfile);
177*7f2fe78bSCy Schubert }
178*7f2fe78bSCy Schubert
179*7f2fe78bSCy Schubert static void
snprintf_fill(char * str,int size,char fillchar,const char * fmt,...)180*7f2fe78bSCy Schubert snprintf_fill(char *str, int size, char fillchar, const char *fmt, ...)
181*7f2fe78bSCy Schubert {
182*7f2fe78bSCy Schubert int len;
183*7f2fe78bSCy Schubert va_list ap;
184*7f2fe78bSCy Schubert va_start(ap, fmt);
185*7f2fe78bSCy Schubert len = vsnprintf(str, size, fmt, ap);
186*7f2fe78bSCy Schubert va_end(ap);
187*7f2fe78bSCy Schubert if (len < 0 || len > size)
188*7f2fe78bSCy Schubert return;
189*7f2fe78bSCy Schubert while(len < size)
190*7f2fe78bSCy Schubert str[len++] = fillchar;
191*7f2fe78bSCy Schubert }
192*7f2fe78bSCy Schubert
193*7f2fe78bSCy Schubert #ifndef TEST_APP
194*7f2fe78bSCy Schubert #define printf error_use_st_logf
195*7f2fe78bSCy Schubert #endif
196*7f2fe78bSCy Schubert
197*7f2fe78bSCy Schubert #define VERIFY_SESSION_HANDLE(s, state) \
198*7f2fe78bSCy Schubert { \
199*7f2fe78bSCy Schubert CK_RV vshret; \
200*7f2fe78bSCy Schubert vshret = verify_session_handle(s, state); \
201*7f2fe78bSCy Schubert if (vshret != CKR_OK) { \
202*7f2fe78bSCy Schubert /* return CKR_OK */; \
203*7f2fe78bSCy Schubert } \
204*7f2fe78bSCy Schubert }
205*7f2fe78bSCy Schubert
206*7f2fe78bSCy Schubert static CK_RV
verify_session_handle(CK_SESSION_HANDLE hSession,struct session_state ** state)207*7f2fe78bSCy Schubert verify_session_handle(CK_SESSION_HANDLE hSession,
208*7f2fe78bSCy Schubert struct session_state **state)
209*7f2fe78bSCy Schubert {
210*7f2fe78bSCy Schubert size_t i;
211*7f2fe78bSCy Schubert
212*7f2fe78bSCy Schubert for (i = 0; i < MAX_NUM_SESSION; i++){
213*7f2fe78bSCy Schubert if (soft_token.state[i].session_handle == hSession)
214*7f2fe78bSCy Schubert break;
215*7f2fe78bSCy Schubert }
216*7f2fe78bSCy Schubert if (i == MAX_NUM_SESSION) {
217*7f2fe78bSCy Schubert application_error("use of invalid handle: 0x%08lx\n",
218*7f2fe78bSCy Schubert (unsigned long)hSession);
219*7f2fe78bSCy Schubert return CKR_SESSION_HANDLE_INVALID;
220*7f2fe78bSCy Schubert }
221*7f2fe78bSCy Schubert if (state)
222*7f2fe78bSCy Schubert *state = &soft_token.state[i];
223*7f2fe78bSCy Schubert return CKR_OK;
224*7f2fe78bSCy Schubert }
225*7f2fe78bSCy Schubert
226*7f2fe78bSCy Schubert static CK_RV
object_handle_to_object(CK_OBJECT_HANDLE handle,struct st_object ** object)227*7f2fe78bSCy Schubert object_handle_to_object(CK_OBJECT_HANDLE handle,
228*7f2fe78bSCy Schubert struct st_object **object)
229*7f2fe78bSCy Schubert {
230*7f2fe78bSCy Schubert int i = HANDLE_OBJECT_ID(handle);
231*7f2fe78bSCy Schubert
232*7f2fe78bSCy Schubert *object = NULL;
233*7f2fe78bSCy Schubert if (i >= soft_token.object.num_objs)
234*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
235*7f2fe78bSCy Schubert if (soft_token.object.objs[i] == NULL)
236*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
237*7f2fe78bSCy Schubert if (soft_token.object.objs[i]->object_handle != handle)
238*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
239*7f2fe78bSCy Schubert *object = soft_token.object.objs[i];
240*7f2fe78bSCy Schubert return CKR_OK;
241*7f2fe78bSCy Schubert }
242*7f2fe78bSCy Schubert
243*7f2fe78bSCy Schubert static int
attributes_match(const struct st_object * obj,const CK_ATTRIBUTE * attributes,CK_ULONG num_attributes)244*7f2fe78bSCy Schubert attributes_match(const struct st_object *obj,
245*7f2fe78bSCy Schubert const CK_ATTRIBUTE *attributes,
246*7f2fe78bSCy Schubert CK_ULONG num_attributes)
247*7f2fe78bSCy Schubert {
248*7f2fe78bSCy Schubert CK_ULONG i;
249*7f2fe78bSCy Schubert int j;
250*7f2fe78bSCy Schubert st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj));
251*7f2fe78bSCy Schubert
252*7f2fe78bSCy Schubert for (i = 0; i < num_attributes; i++) {
253*7f2fe78bSCy Schubert int match = 0;
254*7f2fe78bSCy Schubert for (j = 0; j < obj->num_attributes; j++) {
255*7f2fe78bSCy Schubert if (attributes[i].type == obj->attrs[j].attribute.type &&
256*7f2fe78bSCy Schubert attributes[i].ulValueLen == obj->attrs[j].attribute.ulValueLen &&
257*7f2fe78bSCy Schubert memcmp(attributes[i].pValue, obj->attrs[j].attribute.pValue,
258*7f2fe78bSCy Schubert attributes[i].ulValueLen) == 0) {
259*7f2fe78bSCy Schubert match = 1;
260*7f2fe78bSCy Schubert break;
261*7f2fe78bSCy Schubert }
262*7f2fe78bSCy Schubert }
263*7f2fe78bSCy Schubert if (match == 0) {
264*7f2fe78bSCy Schubert st_logf("type %lu attribute have no match\n", attributes[i].type);
265*7f2fe78bSCy Schubert return 0;
266*7f2fe78bSCy Schubert }
267*7f2fe78bSCy Schubert }
268*7f2fe78bSCy Schubert st_logf("attribute matches\n");
269*7f2fe78bSCy Schubert return 1;
270*7f2fe78bSCy Schubert }
271*7f2fe78bSCy Schubert
272*7f2fe78bSCy Schubert static void
print_attributes(const CK_ATTRIBUTE * attributes,CK_ULONG num_attributes)273*7f2fe78bSCy Schubert print_attributes(const CK_ATTRIBUTE *attributes,
274*7f2fe78bSCy Schubert CK_ULONG num_attributes)
275*7f2fe78bSCy Schubert {
276*7f2fe78bSCy Schubert CK_ULONG i;
277*7f2fe78bSCy Schubert
278*7f2fe78bSCy Schubert st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes);
279*7f2fe78bSCy Schubert
280*7f2fe78bSCy Schubert for (i = 0; i < num_attributes; i++) {
281*7f2fe78bSCy Schubert st_logf(" type: ");
282*7f2fe78bSCy Schubert switch (attributes[i].type) {
283*7f2fe78bSCy Schubert case CKA_TOKEN: {
284*7f2fe78bSCy Schubert CK_BBOOL *ck_true;
285*7f2fe78bSCy Schubert if (attributes[i].ulValueLen != sizeof(CK_BBOOL)) {
286*7f2fe78bSCy Schubert application_error("token attribute wrong length\n");
287*7f2fe78bSCy Schubert break;
288*7f2fe78bSCy Schubert }
289*7f2fe78bSCy Schubert ck_true = attributes[i].pValue;
290*7f2fe78bSCy Schubert st_logf("token: %s", *ck_true ? "TRUE" : "FALSE");
291*7f2fe78bSCy Schubert break;
292*7f2fe78bSCy Schubert }
293*7f2fe78bSCy Schubert case CKA_CLASS: {
294*7f2fe78bSCy Schubert CK_OBJECT_CLASS *class;
295*7f2fe78bSCy Schubert if (attributes[i].ulValueLen != sizeof(CK_ULONG)) {
296*7f2fe78bSCy Schubert application_error("class attribute wrong length\n");
297*7f2fe78bSCy Schubert break;
298*7f2fe78bSCy Schubert }
299*7f2fe78bSCy Schubert class = attributes[i].pValue;
300*7f2fe78bSCy Schubert st_logf("class ");
301*7f2fe78bSCy Schubert switch (*class) {
302*7f2fe78bSCy Schubert case CKO_CERTIFICATE:
303*7f2fe78bSCy Schubert st_logf("certificate");
304*7f2fe78bSCy Schubert break;
305*7f2fe78bSCy Schubert case CKO_PUBLIC_KEY:
306*7f2fe78bSCy Schubert st_logf("public key");
307*7f2fe78bSCy Schubert break;
308*7f2fe78bSCy Schubert case CKO_PRIVATE_KEY:
309*7f2fe78bSCy Schubert st_logf("private key");
310*7f2fe78bSCy Schubert break;
311*7f2fe78bSCy Schubert case CKO_SECRET_KEY:
312*7f2fe78bSCy Schubert st_logf("secret key");
313*7f2fe78bSCy Schubert break;
314*7f2fe78bSCy Schubert case CKO_DOMAIN_PARAMETERS:
315*7f2fe78bSCy Schubert st_logf("domain parameters");
316*7f2fe78bSCy Schubert break;
317*7f2fe78bSCy Schubert default:
318*7f2fe78bSCy Schubert st_logf("[class %lx]", (long unsigned)*class);
319*7f2fe78bSCy Schubert break;
320*7f2fe78bSCy Schubert }
321*7f2fe78bSCy Schubert break;
322*7f2fe78bSCy Schubert }
323*7f2fe78bSCy Schubert case CKA_PRIVATE:
324*7f2fe78bSCy Schubert st_logf("private");
325*7f2fe78bSCy Schubert break;
326*7f2fe78bSCy Schubert case CKA_LABEL:
327*7f2fe78bSCy Schubert st_logf("label");
328*7f2fe78bSCy Schubert break;
329*7f2fe78bSCy Schubert case CKA_APPLICATION:
330*7f2fe78bSCy Schubert st_logf("application");
331*7f2fe78bSCy Schubert break;
332*7f2fe78bSCy Schubert case CKA_VALUE:
333*7f2fe78bSCy Schubert st_logf("value");
334*7f2fe78bSCy Schubert break;
335*7f2fe78bSCy Schubert case CKA_ID:
336*7f2fe78bSCy Schubert st_logf("id");
337*7f2fe78bSCy Schubert break;
338*7f2fe78bSCy Schubert default:
339*7f2fe78bSCy Schubert st_logf("[unknown 0x%08lx]", (unsigned long)attributes[i].type);
340*7f2fe78bSCy Schubert break;
341*7f2fe78bSCy Schubert }
342*7f2fe78bSCy Schubert st_logf("\n");
343*7f2fe78bSCy Schubert }
344*7f2fe78bSCy Schubert }
345*7f2fe78bSCy Schubert
346*7f2fe78bSCy Schubert static void
free_st_object(struct st_object * o)347*7f2fe78bSCy Schubert free_st_object(struct st_object *o)
348*7f2fe78bSCy Schubert {
349*7f2fe78bSCy Schubert int i;
350*7f2fe78bSCy Schubert
351*7f2fe78bSCy Schubert for (i = 0; i < o->num_attributes; i++)
352*7f2fe78bSCy Schubert free(o->attrs[i].attribute.pValue);
353*7f2fe78bSCy Schubert free(o->attrs);
354*7f2fe78bSCy Schubert if (o->type == STO_T_CERTIFICATE) {
355*7f2fe78bSCy Schubert X509_free(o->u.cert);
356*7f2fe78bSCy Schubert } else if (o->type == STO_T_PRIVATE_KEY) {
357*7f2fe78bSCy Schubert free(o->u.private_key.file);
358*7f2fe78bSCy Schubert EVP_PKEY_free(o->u.private_key.key);
359*7f2fe78bSCy Schubert X509_free(o->u.private_key.cert);
360*7f2fe78bSCy Schubert } else if (o->type == STO_T_PUBLIC_KEY) {
361*7f2fe78bSCy Schubert EVP_PKEY_free(o->u.public_key);
362*7f2fe78bSCy Schubert }
363*7f2fe78bSCy Schubert free(o);
364*7f2fe78bSCy Schubert }
365*7f2fe78bSCy Schubert
366*7f2fe78bSCy Schubert static struct st_object *
add_st_object(void)367*7f2fe78bSCy Schubert add_st_object(void)
368*7f2fe78bSCy Schubert {
369*7f2fe78bSCy Schubert struct st_object *o, **objs;
370*7f2fe78bSCy Schubert
371*7f2fe78bSCy Schubert objs = realloc(soft_token.object.objs,
372*7f2fe78bSCy Schubert (soft_token.object.num_objs + 1) *
373*7f2fe78bSCy Schubert sizeof(soft_token.object.objs[0]));
374*7f2fe78bSCy Schubert if (objs == NULL)
375*7f2fe78bSCy Schubert return NULL;
376*7f2fe78bSCy Schubert soft_token.object.objs = objs;
377*7f2fe78bSCy Schubert
378*7f2fe78bSCy Schubert o = calloc(1, sizeof(*o));
379*7f2fe78bSCy Schubert if (o == NULL)
380*7f2fe78bSCy Schubert return NULL;
381*7f2fe78bSCy Schubert o->attrs = NULL;
382*7f2fe78bSCy Schubert o->num_attributes = 0;
383*7f2fe78bSCy Schubert o->object_handle = soft_token.object.num_objs;
384*7f2fe78bSCy Schubert
385*7f2fe78bSCy Schubert soft_token.object.objs[soft_token.object.num_objs++] = o;
386*7f2fe78bSCy Schubert return o;
387*7f2fe78bSCy Schubert }
388*7f2fe78bSCy Schubert
389*7f2fe78bSCy Schubert static CK_RV
add_object_attribute(struct st_object * o,int secret,CK_ATTRIBUTE_TYPE type,CK_VOID_PTR pValue,CK_ULONG ulValueLen)390*7f2fe78bSCy Schubert add_object_attribute(struct st_object *o,
391*7f2fe78bSCy Schubert int secret,
392*7f2fe78bSCy Schubert CK_ATTRIBUTE_TYPE type,
393*7f2fe78bSCy Schubert CK_VOID_PTR pValue,
394*7f2fe78bSCy Schubert CK_ULONG ulValueLen)
395*7f2fe78bSCy Schubert {
396*7f2fe78bSCy Schubert struct st_attr *a;
397*7f2fe78bSCy Schubert int i;
398*7f2fe78bSCy Schubert
399*7f2fe78bSCy Schubert i = o->num_attributes;
400*7f2fe78bSCy Schubert a = realloc(o->attrs, (i + 1) * sizeof(o->attrs[0]));
401*7f2fe78bSCy Schubert if (a == NULL)
402*7f2fe78bSCy Schubert return CKR_DEVICE_MEMORY;
403*7f2fe78bSCy Schubert o->attrs = a;
404*7f2fe78bSCy Schubert o->attrs[i].secret = secret;
405*7f2fe78bSCy Schubert o->attrs[i].attribute.type = type;
406*7f2fe78bSCy Schubert o->attrs[i].attribute.pValue = malloc(ulValueLen);
407*7f2fe78bSCy Schubert if (o->attrs[i].attribute.pValue == NULL && ulValueLen != 0)
408*7f2fe78bSCy Schubert return CKR_DEVICE_MEMORY;
409*7f2fe78bSCy Schubert memcpy(o->attrs[i].attribute.pValue, pValue, ulValueLen);
410*7f2fe78bSCy Schubert o->attrs[i].attribute.ulValueLen = ulValueLen;
411*7f2fe78bSCy Schubert o->num_attributes++;
412*7f2fe78bSCy Schubert
413*7f2fe78bSCy Schubert return CKR_OK;
414*7f2fe78bSCy Schubert }
415*7f2fe78bSCy Schubert
416*7f2fe78bSCy Schubert #ifdef HAVE_EVP_PKEY_GET_BN_PARAM
417*7f2fe78bSCy Schubert
418*7f2fe78bSCy Schubert /* Declare owner pointers since EVP_PKEY_get_bn_param() gives us copies. */
419*7f2fe78bSCy Schubert #define DECLARE_BIGNUM(name) BIGNUM *name = NULL
420*7f2fe78bSCy Schubert #define RELEASE_BIGNUM(bn) BN_clear_free(bn)
421*7f2fe78bSCy Schubert static CK_RV
get_bignums(EVP_PKEY * key,BIGNUM ** n,BIGNUM ** e)422*7f2fe78bSCy Schubert get_bignums(EVP_PKEY *key, BIGNUM **n, BIGNUM **e)
423*7f2fe78bSCy Schubert {
424*7f2fe78bSCy Schubert if (EVP_PKEY_get_bn_param(key, "n", n) == 0 ||
425*7f2fe78bSCy Schubert EVP_PKEY_get_bn_param(key, "e", e) == 0)
426*7f2fe78bSCy Schubert return CKR_DEVICE_ERROR;
427*7f2fe78bSCy Schubert
428*7f2fe78bSCy Schubert return CKR_OK;
429*7f2fe78bSCy Schubert }
430*7f2fe78bSCy Schubert
431*7f2fe78bSCy Schubert #else
432*7f2fe78bSCy Schubert
433*7f2fe78bSCy Schubert /* Declare const pointers since the old API gives us aliases. */
434*7f2fe78bSCy Schubert #define DECLARE_BIGNUM(name) const BIGNUM *name
435*7f2fe78bSCy Schubert #define RELEASE_BIGNUM(bn)
436*7f2fe78bSCy Schubert static CK_RV
get_bignums(EVP_PKEY * key,const BIGNUM ** n,const BIGNUM ** e)437*7f2fe78bSCy Schubert get_bignums(EVP_PKEY *key, const BIGNUM **n, const BIGNUM **e)
438*7f2fe78bSCy Schubert {
439*7f2fe78bSCy Schubert const RSA *rsa;
440*7f2fe78bSCy Schubert
441*7f2fe78bSCy Schubert rsa = EVP_PKEY_get0_RSA(key);
442*7f2fe78bSCy Schubert RSA_get0_key(rsa, n, e, NULL);
443*7f2fe78bSCy Schubert
444*7f2fe78bSCy Schubert return CKR_OK;
445*7f2fe78bSCy Schubert }
446*7f2fe78bSCy Schubert
447*7f2fe78bSCy Schubert #endif
448*7f2fe78bSCy Schubert
449*7f2fe78bSCy Schubert static CK_RV
add_pubkey_info(struct st_object * o,CK_KEY_TYPE key_type,EVP_PKEY * key)450*7f2fe78bSCy Schubert add_pubkey_info(struct st_object *o, CK_KEY_TYPE key_type, EVP_PKEY *key)
451*7f2fe78bSCy Schubert {
452*7f2fe78bSCy Schubert CK_BYTE *modulus = NULL, *exponent = 0;
453*7f2fe78bSCy Schubert size_t modulus_len = 0, exponent_len = 0;
454*7f2fe78bSCy Schubert CK_ULONG modulus_bits = 0;
455*7f2fe78bSCy Schubert CK_RV ret;
456*7f2fe78bSCy Schubert DECLARE_BIGNUM(n);
457*7f2fe78bSCy Schubert DECLARE_BIGNUM(e);
458*7f2fe78bSCy Schubert
459*7f2fe78bSCy Schubert if (key_type != CKK_RSA)
460*7f2fe78bSCy Schubert abort();
461*7f2fe78bSCy Schubert
462*7f2fe78bSCy Schubert ret = get_bignums(key, &n, &e);
463*7f2fe78bSCy Schubert if (ret != CKR_OK)
464*7f2fe78bSCy Schubert goto done;
465*7f2fe78bSCy Schubert
466*7f2fe78bSCy Schubert modulus_bits = BN_num_bits(n);
467*7f2fe78bSCy Schubert modulus_len = BN_num_bytes(n);
468*7f2fe78bSCy Schubert exponent_len = BN_num_bytes(e);
469*7f2fe78bSCy Schubert
470*7f2fe78bSCy Schubert modulus = malloc(modulus_len);
471*7f2fe78bSCy Schubert exponent = malloc(exponent_len);
472*7f2fe78bSCy Schubert if (modulus == NULL || exponent == NULL) {
473*7f2fe78bSCy Schubert ret = CKR_DEVICE_MEMORY;
474*7f2fe78bSCy Schubert goto done;
475*7f2fe78bSCy Schubert }
476*7f2fe78bSCy Schubert
477*7f2fe78bSCy Schubert BN_bn2bin(n, modulus);
478*7f2fe78bSCy Schubert BN_bn2bin(e, exponent);
479*7f2fe78bSCy Schubert
480*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_MODULUS, modulus, modulus_len);
481*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_MODULUS_BITS, &modulus_bits,
482*7f2fe78bSCy Schubert sizeof(modulus_bits));
483*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_PUBLIC_EXPONENT, exponent, exponent_len);
484*7f2fe78bSCy Schubert
485*7f2fe78bSCy Schubert ret = CKR_OK;
486*7f2fe78bSCy Schubert done:
487*7f2fe78bSCy Schubert free(modulus);
488*7f2fe78bSCy Schubert free(exponent);
489*7f2fe78bSCy Schubert RELEASE_BIGNUM(n);
490*7f2fe78bSCy Schubert RELEASE_BIGNUM(e);
491*7f2fe78bSCy Schubert return ret;
492*7f2fe78bSCy Schubert }
493*7f2fe78bSCy Schubert
494*7f2fe78bSCy Schubert static int
pem_callback(char * buf,int num,int w,void * key)495*7f2fe78bSCy Schubert pem_callback(char *buf, int num, int w, void *key)
496*7f2fe78bSCy Schubert {
497*7f2fe78bSCy Schubert return -1;
498*7f2fe78bSCy Schubert }
499*7f2fe78bSCy Schubert
500*7f2fe78bSCy Schubert
501*7f2fe78bSCy Schubert static CK_RV
add_certificate(char * label,const char * cert_file,const char * private_key_file,char * id,int anchor)502*7f2fe78bSCy Schubert add_certificate(char *label,
503*7f2fe78bSCy Schubert const char *cert_file,
504*7f2fe78bSCy Schubert const char *private_key_file,
505*7f2fe78bSCy Schubert char *id,
506*7f2fe78bSCy Schubert int anchor)
507*7f2fe78bSCy Schubert {
508*7f2fe78bSCy Schubert struct st_object *o = NULL;
509*7f2fe78bSCy Schubert CK_BBOOL bool_true = CK_TRUE;
510*7f2fe78bSCy Schubert CK_BBOOL bool_false = CK_FALSE;
511*7f2fe78bSCy Schubert CK_OBJECT_CLASS c;
512*7f2fe78bSCy Schubert CK_CERTIFICATE_TYPE cert_type = CKC_X_509;
513*7f2fe78bSCy Schubert CK_KEY_TYPE key_type;
514*7f2fe78bSCy Schubert CK_MECHANISM_TYPE mech_type;
515*7f2fe78bSCy Schubert void *cert_data = NULL;
516*7f2fe78bSCy Schubert size_t cert_length;
517*7f2fe78bSCy Schubert void *subject_data = NULL;
518*7f2fe78bSCy Schubert size_t subject_length;
519*7f2fe78bSCy Schubert void *issuer_data = NULL;
520*7f2fe78bSCy Schubert size_t issuer_length;
521*7f2fe78bSCy Schubert void *serial_data = NULL;
522*7f2fe78bSCy Schubert size_t serial_length;
523*7f2fe78bSCy Schubert CK_RV ret = CKR_GENERAL_ERROR;
524*7f2fe78bSCy Schubert X509 *cert;
525*7f2fe78bSCy Schubert EVP_PKEY *public_key;
526*7f2fe78bSCy Schubert
527*7f2fe78bSCy Schubert size_t id_len = strlen(id);
528*7f2fe78bSCy Schubert
529*7f2fe78bSCy Schubert {
530*7f2fe78bSCy Schubert FILE *f;
531*7f2fe78bSCy Schubert
532*7f2fe78bSCy Schubert f = fopen(cert_file, "r");
533*7f2fe78bSCy Schubert if (f == NULL) {
534*7f2fe78bSCy Schubert st_logf("failed to open file %s\n", cert_file);
535*7f2fe78bSCy Schubert return CKR_GENERAL_ERROR;
536*7f2fe78bSCy Schubert }
537*7f2fe78bSCy Schubert
538*7f2fe78bSCy Schubert cert = PEM_read_X509(f, NULL, NULL, NULL);
539*7f2fe78bSCy Schubert fclose(f);
540*7f2fe78bSCy Schubert if (cert == NULL) {
541*7f2fe78bSCy Schubert st_logf("failed reading PEM cert\n");
542*7f2fe78bSCy Schubert return CKR_GENERAL_ERROR;
543*7f2fe78bSCy Schubert }
544*7f2fe78bSCy Schubert
545*7f2fe78bSCy Schubert OPENSSL_ASN1_MALLOC_ENCODE(X509, cert_data, cert_length, cert, ret);
546*7f2fe78bSCy Schubert if (ret)
547*7f2fe78bSCy Schubert goto out;
548*7f2fe78bSCy Schubert
549*7f2fe78bSCy Schubert OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, issuer_data, issuer_length,
550*7f2fe78bSCy Schubert X509_get_issuer_name(cert), ret);
551*7f2fe78bSCy Schubert if (ret)
552*7f2fe78bSCy Schubert goto out;
553*7f2fe78bSCy Schubert
554*7f2fe78bSCy Schubert OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, subject_data, subject_length,
555*7f2fe78bSCy Schubert X509_get_subject_name(cert), ret);
556*7f2fe78bSCy Schubert if (ret)
557*7f2fe78bSCy Schubert goto out;
558*7f2fe78bSCy Schubert
559*7f2fe78bSCy Schubert OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, serial_data, serial_length,
560*7f2fe78bSCy Schubert X509_get_serialNumber(cert), ret);
561*7f2fe78bSCy Schubert if (ret)
562*7f2fe78bSCy Schubert goto out;
563*7f2fe78bSCy Schubert
564*7f2fe78bSCy Schubert }
565*7f2fe78bSCy Schubert
566*7f2fe78bSCy Schubert st_logf("done parsing, adding to internal structure\n");
567*7f2fe78bSCy Schubert
568*7f2fe78bSCy Schubert o = add_st_object();
569*7f2fe78bSCy Schubert if (o == NULL) {
570*7f2fe78bSCy Schubert ret = CKR_DEVICE_MEMORY;
571*7f2fe78bSCy Schubert goto out;
572*7f2fe78bSCy Schubert }
573*7f2fe78bSCy Schubert o->type = STO_T_CERTIFICATE;
574*7f2fe78bSCy Schubert o->u.cert = X509_dup(cert);
575*7f2fe78bSCy Schubert if (o->u.cert == NULL) {
576*7f2fe78bSCy Schubert ret = CKR_DEVICE_MEMORY;
577*7f2fe78bSCy Schubert goto out;
578*7f2fe78bSCy Schubert }
579*7f2fe78bSCy Schubert public_key = X509_get_pubkey(o->u.cert);
580*7f2fe78bSCy Schubert
581*7f2fe78bSCy Schubert switch (EVP_PKEY_base_id(public_key)) {
582*7f2fe78bSCy Schubert case EVP_PKEY_RSA:
583*7f2fe78bSCy Schubert key_type = CKK_RSA;
584*7f2fe78bSCy Schubert break;
585*7f2fe78bSCy Schubert case EVP_PKEY_DSA:
586*7f2fe78bSCy Schubert key_type = CKK_DSA;
587*7f2fe78bSCy Schubert break;
588*7f2fe78bSCy Schubert default:
589*7f2fe78bSCy Schubert st_logf("invalid key_type\n");
590*7f2fe78bSCy Schubert ret = CKR_GENERAL_ERROR;
591*7f2fe78bSCy Schubert goto out;
592*7f2fe78bSCy Schubert }
593*7f2fe78bSCy Schubert
594*7f2fe78bSCy Schubert c = CKO_CERTIFICATE;
595*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
596*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
597*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));
598*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
599*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_LABEL, label, strlen(label));
600*7f2fe78bSCy Schubert
601*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_CERTIFICATE_TYPE, &cert_type, sizeof(cert_type));
602*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_ID, id, id_len);
603*7f2fe78bSCy Schubert
604*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length);
605*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_ISSUER, issuer_data, issuer_length);
606*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_SERIAL_NUMBER, serial_data, serial_length);
607*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_VALUE, cert_data, cert_length);
608*7f2fe78bSCy Schubert if (anchor)
609*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true));
610*7f2fe78bSCy Schubert else
611*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_TRUSTED, &bool_false, sizeof(bool_false));
612*7f2fe78bSCy Schubert
613*7f2fe78bSCy Schubert st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o));
614*7f2fe78bSCy Schubert
615*7f2fe78bSCy Schubert o = add_st_object();
616*7f2fe78bSCy Schubert if (o == NULL) {
617*7f2fe78bSCy Schubert ret = CKR_DEVICE_MEMORY;
618*7f2fe78bSCy Schubert goto out;
619*7f2fe78bSCy Schubert }
620*7f2fe78bSCy Schubert o->type = STO_T_PUBLIC_KEY;
621*7f2fe78bSCy Schubert o->u.public_key = public_key;
622*7f2fe78bSCy Schubert
623*7f2fe78bSCy Schubert c = CKO_PUBLIC_KEY;
624*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
625*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
626*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_PRIVATE, &bool_false, sizeof(bool_false));
627*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
628*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_LABEL, label, strlen(label));
629*7f2fe78bSCy Schubert
630*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
631*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_ID, id, id_len);
632*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */
633*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */
634*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
635*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
636*7f2fe78bSCy Schubert mech_type = CKM_RSA_X_509;
637*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));
638*7f2fe78bSCy Schubert
639*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length);
640*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_ENCRYPT, &bool_true, sizeof(bool_true));
641*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_VERIFY, &bool_true, sizeof(bool_true));
642*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_VERIFY_RECOVER, &bool_false, sizeof(bool_false));
643*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_WRAP, &bool_true, sizeof(bool_true));
644*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_TRUSTED, &bool_true, sizeof(bool_true));
645*7f2fe78bSCy Schubert
646*7f2fe78bSCy Schubert add_pubkey_info(o, key_type, public_key);
647*7f2fe78bSCy Schubert
648*7f2fe78bSCy Schubert st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o));
649*7f2fe78bSCy Schubert
650*7f2fe78bSCy Schubert if (private_key_file) {
651*7f2fe78bSCy Schubert CK_FLAGS flags;
652*7f2fe78bSCy Schubert FILE *f;
653*7f2fe78bSCy Schubert
654*7f2fe78bSCy Schubert o = add_st_object();
655*7f2fe78bSCy Schubert if (o == NULL) {
656*7f2fe78bSCy Schubert ret = CKR_DEVICE_MEMORY;
657*7f2fe78bSCy Schubert goto out;
658*7f2fe78bSCy Schubert }
659*7f2fe78bSCy Schubert o->type = STO_T_PRIVATE_KEY;
660*7f2fe78bSCy Schubert o->u.private_key.file = strdup(private_key_file);
661*7f2fe78bSCy Schubert o->u.private_key.key = NULL;
662*7f2fe78bSCy Schubert
663*7f2fe78bSCy Schubert o->u.private_key.cert = X509_dup(cert);
664*7f2fe78bSCy Schubert if (o->u.private_key.cert == NULL) {
665*7f2fe78bSCy Schubert ret = CKR_DEVICE_MEMORY;
666*7f2fe78bSCy Schubert goto out;
667*7f2fe78bSCy Schubert }
668*7f2fe78bSCy Schubert
669*7f2fe78bSCy Schubert c = CKO_PRIVATE_KEY;
670*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_CLASS, &c, sizeof(c));
671*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_TOKEN, &bool_true, sizeof(bool_true));
672*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_PRIVATE, &bool_true, sizeof(bool_false));
673*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_MODIFIABLE, &bool_false, sizeof(bool_false));
674*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_LABEL, label, strlen(label));
675*7f2fe78bSCy Schubert
676*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_KEY_TYPE, &key_type, sizeof(key_type));
677*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_ID, id, id_len);
678*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_START_DATE, "", 1); /* XXX */
679*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_END_DATE, "", 1); /* XXX */
680*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_DERIVE, &bool_false, sizeof(bool_false));
681*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_LOCAL, &bool_false, sizeof(bool_false));
682*7f2fe78bSCy Schubert mech_type = CKM_RSA_X_509;
683*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_KEY_GEN_MECHANISM, &mech_type, sizeof(mech_type));
684*7f2fe78bSCy Schubert
685*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_SUBJECT, subject_data, subject_length);
686*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_SENSITIVE, &bool_true, sizeof(bool_true));
687*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_SECONDARY_AUTH, &bool_false, sizeof(bool_true));
688*7f2fe78bSCy Schubert flags = 0;
689*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_AUTH_PIN_FLAGS, &flags, sizeof(flags));
690*7f2fe78bSCy Schubert
691*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_DECRYPT, &bool_true, sizeof(bool_true));
692*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_SIGN, &bool_true, sizeof(bool_true));
693*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_SIGN_RECOVER, &bool_false, sizeof(bool_false));
694*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_UNWRAP, &bool_true, sizeof(bool_true));
695*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_EXTRACTABLE, &bool_true, sizeof(bool_true));
696*7f2fe78bSCy Schubert add_object_attribute(o, 0, CKA_NEVER_EXTRACTABLE, &bool_false, sizeof(bool_false));
697*7f2fe78bSCy Schubert
698*7f2fe78bSCy Schubert add_pubkey_info(o, key_type, public_key);
699*7f2fe78bSCy Schubert
700*7f2fe78bSCy Schubert f = fopen(private_key_file, "r");
701*7f2fe78bSCy Schubert if (f == NULL) {
702*7f2fe78bSCy Schubert st_logf("failed to open private key\n");
703*7f2fe78bSCy Schubert return CKR_GENERAL_ERROR;
704*7f2fe78bSCy Schubert }
705*7f2fe78bSCy Schubert
706*7f2fe78bSCy Schubert o->u.private_key.key = PEM_read_PrivateKey(f, NULL, pem_callback, NULL);
707*7f2fe78bSCy Schubert fclose(f);
708*7f2fe78bSCy Schubert if (o->u.private_key.key == NULL) {
709*7f2fe78bSCy Schubert st_logf("failed to read private key a startup\n");
710*7f2fe78bSCy Schubert /* don't bother with this failure for now,
711*7f2fe78bSCy Schubert fix it at C_Login time */;
712*7f2fe78bSCy Schubert } else {
713*7f2fe78bSCy Schubert /* XXX verify keytype */
714*7f2fe78bSCy Schubert
715*7f2fe78bSCy Schubert if (X509_check_private_key(cert, o->u.private_key.key) != 1) {
716*7f2fe78bSCy Schubert EVP_PKEY_free(o->u.private_key.key);
717*7f2fe78bSCy Schubert o->u.private_key.key = NULL;
718*7f2fe78bSCy Schubert st_logf("private key doesn't verify\n");
719*7f2fe78bSCy Schubert } else {
720*7f2fe78bSCy Schubert st_logf("private key usable\n");
721*7f2fe78bSCy Schubert soft_token.flags.login_done = 1;
722*7f2fe78bSCy Schubert }
723*7f2fe78bSCy Schubert }
724*7f2fe78bSCy Schubert }
725*7f2fe78bSCy Schubert
726*7f2fe78bSCy Schubert ret = CKR_OK;
727*7f2fe78bSCy Schubert out:
728*7f2fe78bSCy Schubert if (ret != CKR_OK) {
729*7f2fe78bSCy Schubert st_logf("something went wrong when adding cert!\n");
730*7f2fe78bSCy Schubert
731*7f2fe78bSCy Schubert /* XXX wack o */;
732*7f2fe78bSCy Schubert }
733*7f2fe78bSCy Schubert free(cert_data);
734*7f2fe78bSCy Schubert free(serial_data);
735*7f2fe78bSCy Schubert free(issuer_data);
736*7f2fe78bSCy Schubert free(subject_data);
737*7f2fe78bSCy Schubert X509_free(cert);
738*7f2fe78bSCy Schubert
739*7f2fe78bSCy Schubert return ret;
740*7f2fe78bSCy Schubert }
741*7f2fe78bSCy Schubert
742*7f2fe78bSCy Schubert static void
find_object_final(struct session_state * state)743*7f2fe78bSCy Schubert find_object_final(struct session_state *state)
744*7f2fe78bSCy Schubert {
745*7f2fe78bSCy Schubert if (state->find.attributes) {
746*7f2fe78bSCy Schubert CK_ULONG i;
747*7f2fe78bSCy Schubert
748*7f2fe78bSCy Schubert for (i = 0; i < state->find.num_attributes; i++) {
749*7f2fe78bSCy Schubert if (state->find.attributes[i].pValue)
750*7f2fe78bSCy Schubert free(state->find.attributes[i].pValue);
751*7f2fe78bSCy Schubert }
752*7f2fe78bSCy Schubert free(state->find.attributes);
753*7f2fe78bSCy Schubert state->find.attributes = NULL;
754*7f2fe78bSCy Schubert state->find.num_attributes = 0;
755*7f2fe78bSCy Schubert state->find.next_object = -1;
756*7f2fe78bSCy Schubert }
757*7f2fe78bSCy Schubert }
758*7f2fe78bSCy Schubert
759*7f2fe78bSCy Schubert static void
reset_crypto_state(struct session_state * state)760*7f2fe78bSCy Schubert reset_crypto_state(struct session_state *state)
761*7f2fe78bSCy Schubert {
762*7f2fe78bSCy Schubert state->encrypt_object = -1;
763*7f2fe78bSCy Schubert if (state->encrypt_mechanism)
764*7f2fe78bSCy Schubert free(state->encrypt_mechanism);
765*7f2fe78bSCy Schubert state->encrypt_mechanism = NULL_PTR;
766*7f2fe78bSCy Schubert state->decrypt_object = -1;
767*7f2fe78bSCy Schubert if (state->decrypt_mechanism)
768*7f2fe78bSCy Schubert free(state->decrypt_mechanism);
769*7f2fe78bSCy Schubert state->decrypt_mechanism = NULL_PTR;
770*7f2fe78bSCy Schubert state->sign_object = -1;
771*7f2fe78bSCy Schubert if (state->sign_mechanism)
772*7f2fe78bSCy Schubert free(state->sign_mechanism);
773*7f2fe78bSCy Schubert state->sign_mechanism = NULL_PTR;
774*7f2fe78bSCy Schubert state->verify_object = -1;
775*7f2fe78bSCy Schubert if (state->verify_mechanism)
776*7f2fe78bSCy Schubert free(state->verify_mechanism);
777*7f2fe78bSCy Schubert state->verify_mechanism = NULL_PTR;
778*7f2fe78bSCy Schubert state->digest_object = -1;
779*7f2fe78bSCy Schubert }
780*7f2fe78bSCy Schubert
781*7f2fe78bSCy Schubert static void
close_session(struct session_state * state)782*7f2fe78bSCy Schubert close_session(struct session_state *state)
783*7f2fe78bSCy Schubert {
784*7f2fe78bSCy Schubert if (state->find.attributes) {
785*7f2fe78bSCy Schubert application_error("application didn't do C_FindObjectsFinal\n");
786*7f2fe78bSCy Schubert find_object_final(state);
787*7f2fe78bSCy Schubert }
788*7f2fe78bSCy Schubert
789*7f2fe78bSCy Schubert state->session_handle = CK_INVALID_HANDLE;
790*7f2fe78bSCy Schubert soft_token.application = NULL_PTR;
791*7f2fe78bSCy Schubert soft_token.notify = NULL_PTR;
792*7f2fe78bSCy Schubert reset_crypto_state(state);
793*7f2fe78bSCy Schubert }
794*7f2fe78bSCy Schubert
795*7f2fe78bSCy Schubert static const char *
has_session(void)796*7f2fe78bSCy Schubert has_session(void)
797*7f2fe78bSCy Schubert {
798*7f2fe78bSCy Schubert return soft_token.open_sessions > 0 ? "yes" : "no";
799*7f2fe78bSCy Schubert }
800*7f2fe78bSCy Schubert
801*7f2fe78bSCy Schubert static void
read_conf_file(const char * fn)802*7f2fe78bSCy Schubert read_conf_file(const char *fn)
803*7f2fe78bSCy Schubert {
804*7f2fe78bSCy Schubert char buf[1024], *cert, *key, *id, *label, *s, *p;
805*7f2fe78bSCy Schubert int anchor;
806*7f2fe78bSCy Schubert FILE *f;
807*7f2fe78bSCy Schubert
808*7f2fe78bSCy Schubert f = fopen(fn, "r");
809*7f2fe78bSCy Schubert if (f == NULL) {
810*7f2fe78bSCy Schubert st_logf("can't open configuration file %s\n", fn);
811*7f2fe78bSCy Schubert return;
812*7f2fe78bSCy Schubert }
813*7f2fe78bSCy Schubert
814*7f2fe78bSCy Schubert while(fgets(buf, sizeof(buf), f) != NULL) {
815*7f2fe78bSCy Schubert buf[strcspn(buf, "\n")] = '\0';
816*7f2fe78bSCy Schubert
817*7f2fe78bSCy Schubert anchor = 0;
818*7f2fe78bSCy Schubert
819*7f2fe78bSCy Schubert st_logf("line: %s\n", buf);
820*7f2fe78bSCy Schubert
821*7f2fe78bSCy Schubert p = buf;
822*7f2fe78bSCy Schubert while (isspace(*p))
823*7f2fe78bSCy Schubert p++;
824*7f2fe78bSCy Schubert if (*p == '#')
825*7f2fe78bSCy Schubert continue;
826*7f2fe78bSCy Schubert while (isspace(*p))
827*7f2fe78bSCy Schubert p++;
828*7f2fe78bSCy Schubert
829*7f2fe78bSCy Schubert s = NULL;
830*7f2fe78bSCy Schubert id = strtok_r(p, "\t", &s);
831*7f2fe78bSCy Schubert if (id == NULL)
832*7f2fe78bSCy Schubert continue;
833*7f2fe78bSCy Schubert label = strtok_r(NULL, "\t", &s);
834*7f2fe78bSCy Schubert if (label == NULL)
835*7f2fe78bSCy Schubert continue;
836*7f2fe78bSCy Schubert cert = strtok_r(NULL, "\t", &s);
837*7f2fe78bSCy Schubert if (cert == NULL)
838*7f2fe78bSCy Schubert continue;
839*7f2fe78bSCy Schubert key = strtok_r(NULL, "\t", &s);
840*7f2fe78bSCy Schubert
841*7f2fe78bSCy Schubert /* XXX */
842*7f2fe78bSCy Schubert if (strcmp(id, "anchor") == 0) {
843*7f2fe78bSCy Schubert id = "\x00\x00";
844*7f2fe78bSCy Schubert anchor = 1;
845*7f2fe78bSCy Schubert }
846*7f2fe78bSCy Schubert
847*7f2fe78bSCy Schubert st_logf("adding: %s\n", label);
848*7f2fe78bSCy Schubert
849*7f2fe78bSCy Schubert add_certificate(label, cert, key, id, anchor);
850*7f2fe78bSCy Schubert }
851*7f2fe78bSCy Schubert
852*7f2fe78bSCy Schubert fclose(f);
853*7f2fe78bSCy Schubert }
854*7f2fe78bSCy Schubert
855*7f2fe78bSCy Schubert static CK_RV
func_not_supported(void)856*7f2fe78bSCy Schubert func_not_supported(void)
857*7f2fe78bSCy Schubert {
858*7f2fe78bSCy Schubert st_logf("function not supported\n");
859*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
860*7f2fe78bSCy Schubert }
861*7f2fe78bSCy Schubert
862*7f2fe78bSCy Schubert static char *
get_rcfilename()863*7f2fe78bSCy Schubert get_rcfilename()
864*7f2fe78bSCy Schubert {
865*7f2fe78bSCy Schubert struct passwd *pw;
866*7f2fe78bSCy Schubert const char *home = NULL;
867*7f2fe78bSCy Schubert char *fn;
868*7f2fe78bSCy Schubert
869*7f2fe78bSCy Schubert if (getuid() == geteuid()) {
870*7f2fe78bSCy Schubert fn = getenv("SOFTPKCS11RC");
871*7f2fe78bSCy Schubert if (fn != NULL)
872*7f2fe78bSCy Schubert return strdup(fn);
873*7f2fe78bSCy Schubert
874*7f2fe78bSCy Schubert home = getenv("HOME");
875*7f2fe78bSCy Schubert }
876*7f2fe78bSCy Schubert
877*7f2fe78bSCy Schubert if (home == NULL) {
878*7f2fe78bSCy Schubert pw = getpwuid(getuid());
879*7f2fe78bSCy Schubert if (pw != NULL)
880*7f2fe78bSCy Schubert home = pw->pw_dir;
881*7f2fe78bSCy Schubert }
882*7f2fe78bSCy Schubert
883*7f2fe78bSCy Schubert if (home == NULL)
884*7f2fe78bSCy Schubert return strdup("/etc/soft-token.rc");
885*7f2fe78bSCy Schubert
886*7f2fe78bSCy Schubert if (asprintf(&fn, "%s/.soft-token.rc", home) < 0)
887*7f2fe78bSCy Schubert return NULL;
888*7f2fe78bSCy Schubert return fn;
889*7f2fe78bSCy Schubert }
890*7f2fe78bSCy Schubert
891*7f2fe78bSCy Schubert CK_RV
C_Initialize(CK_VOID_PTR a)892*7f2fe78bSCy Schubert C_Initialize(CK_VOID_PTR a)
893*7f2fe78bSCy Schubert {
894*7f2fe78bSCy Schubert CK_C_INITIALIZE_ARGS_PTR args = a;
895*7f2fe78bSCy Schubert size_t i;
896*7f2fe78bSCy Schubert char *fn;
897*7f2fe78bSCy Schubert
898*7f2fe78bSCy Schubert st_logf("Initialize\n");
899*7f2fe78bSCy Schubert
900*7f2fe78bSCy Schubert OpenSSL_add_all_algorithms();
901*7f2fe78bSCy Schubert ERR_load_crypto_strings();
902*7f2fe78bSCy Schubert
903*7f2fe78bSCy Schubert for (i = 0; i < MAX_NUM_SESSION; i++) {
904*7f2fe78bSCy Schubert soft_token.state[i].session_handle = CK_INVALID_HANDLE;
905*7f2fe78bSCy Schubert soft_token.state[i].find.attributes = NULL;
906*7f2fe78bSCy Schubert soft_token.state[i].find.num_attributes = 0;
907*7f2fe78bSCy Schubert soft_token.state[i].find.next_object = -1;
908*7f2fe78bSCy Schubert reset_crypto_state(&soft_token.state[i]);
909*7f2fe78bSCy Schubert }
910*7f2fe78bSCy Schubert
911*7f2fe78bSCy Schubert soft_token.flags.hardware_slot = 1;
912*7f2fe78bSCy Schubert soft_token.flags.app_error_fatal = 0;
913*7f2fe78bSCy Schubert soft_token.flags.login_done = 0;
914*7f2fe78bSCy Schubert
915*7f2fe78bSCy Schubert soft_token.object.objs = NULL;
916*7f2fe78bSCy Schubert soft_token.object.num_objs = 0;
917*7f2fe78bSCy Schubert
918*7f2fe78bSCy Schubert soft_token.logfile = NULL;
919*7f2fe78bSCy Schubert #if 0
920*7f2fe78bSCy Schubert soft_token.logfile = stdout;
921*7f2fe78bSCy Schubert #endif
922*7f2fe78bSCy Schubert #if 0
923*7f2fe78bSCy Schubert soft_token.logfile = fopen("/tmp/log-pkcs11.txt", "a");
924*7f2fe78bSCy Schubert #endif
925*7f2fe78bSCy Schubert
926*7f2fe78bSCy Schubert if (a != NULL_PTR) {
927*7f2fe78bSCy Schubert st_logf("\tCreateMutex:\t%p\n", args->CreateMutex);
928*7f2fe78bSCy Schubert st_logf("\tDestroyMutext\t%p\n", args->DestroyMutex);
929*7f2fe78bSCy Schubert st_logf("\tLockMutext\t%p\n", args->LockMutex);
930*7f2fe78bSCy Schubert st_logf("\tUnlockMutext\t%p\n", args->UnlockMutex);
931*7f2fe78bSCy Schubert st_logf("\tFlags\t%04x\n", (unsigned int)args->flags);
932*7f2fe78bSCy Schubert }
933*7f2fe78bSCy Schubert
934*7f2fe78bSCy Schubert soft_token.next_session_handle = 1;
935*7f2fe78bSCy Schubert
936*7f2fe78bSCy Schubert fn = get_rcfilename();
937*7f2fe78bSCy Schubert if (fn == NULL)
938*7f2fe78bSCy Schubert return CKR_DEVICE_MEMORY;
939*7f2fe78bSCy Schubert read_conf_file(fn);
940*7f2fe78bSCy Schubert free(fn);
941*7f2fe78bSCy Schubert return CKR_OK;
942*7f2fe78bSCy Schubert }
943*7f2fe78bSCy Schubert
944*7f2fe78bSCy Schubert CK_RV
C_Finalize(CK_VOID_PTR args)945*7f2fe78bSCy Schubert C_Finalize(CK_VOID_PTR args)
946*7f2fe78bSCy Schubert {
947*7f2fe78bSCy Schubert size_t i;
948*7f2fe78bSCy Schubert int j;
949*7f2fe78bSCy Schubert
950*7f2fe78bSCy Schubert st_logf("Finalize\n");
951*7f2fe78bSCy Schubert
952*7f2fe78bSCy Schubert for (i = 0; i < MAX_NUM_SESSION; i++) {
953*7f2fe78bSCy Schubert if (soft_token.state[i].session_handle != CK_INVALID_HANDLE) {
954*7f2fe78bSCy Schubert application_error("application finalized without "
955*7f2fe78bSCy Schubert "closing session\n");
956*7f2fe78bSCy Schubert close_session(&soft_token.state[i]);
957*7f2fe78bSCy Schubert }
958*7f2fe78bSCy Schubert }
959*7f2fe78bSCy Schubert
960*7f2fe78bSCy Schubert for (j = 0; j < soft_token.object.num_objs; j++)
961*7f2fe78bSCy Schubert free_st_object(soft_token.object.objs[j]);
962*7f2fe78bSCy Schubert free(soft_token.object.objs);
963*7f2fe78bSCy Schubert soft_token.object.objs = NULL;
964*7f2fe78bSCy Schubert soft_token.object.num_objs = 0;
965*7f2fe78bSCy Schubert
966*7f2fe78bSCy Schubert return CKR_OK;
967*7f2fe78bSCy Schubert }
968*7f2fe78bSCy Schubert
969*7f2fe78bSCy Schubert CK_RV
C_GetInfo(CK_INFO_PTR args)970*7f2fe78bSCy Schubert C_GetInfo(CK_INFO_PTR args)
971*7f2fe78bSCy Schubert {
972*7f2fe78bSCy Schubert st_logf("GetInfo\n");
973*7f2fe78bSCy Schubert
974*7f2fe78bSCy Schubert memset(args, 17, sizeof(*args));
975*7f2fe78bSCy Schubert args->cryptokiVersion.major = 2;
976*7f2fe78bSCy Schubert args->cryptokiVersion.minor = 10;
977*7f2fe78bSCy Schubert snprintf_fill((char *)args->manufacturerID,
978*7f2fe78bSCy Schubert sizeof(args->manufacturerID),
979*7f2fe78bSCy Schubert ' ',
980*7f2fe78bSCy Schubert "SoftToken");
981*7f2fe78bSCy Schubert snprintf_fill((char *)args->libraryDescription,
982*7f2fe78bSCy Schubert sizeof(args->libraryDescription), ' ',
983*7f2fe78bSCy Schubert "SoftToken");
984*7f2fe78bSCy Schubert args->libraryVersion.major = 1;
985*7f2fe78bSCy Schubert args->libraryVersion.minor = 8;
986*7f2fe78bSCy Schubert
987*7f2fe78bSCy Schubert return CKR_OK;
988*7f2fe78bSCy Schubert }
989*7f2fe78bSCy Schubert
990*7f2fe78bSCy Schubert extern CK_FUNCTION_LIST funcs;
991*7f2fe78bSCy Schubert
992*7f2fe78bSCy Schubert CK_RV
C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)993*7f2fe78bSCy Schubert C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList)
994*7f2fe78bSCy Schubert {
995*7f2fe78bSCy Schubert *ppFunctionList = &funcs;
996*7f2fe78bSCy Schubert return CKR_OK;
997*7f2fe78bSCy Schubert }
998*7f2fe78bSCy Schubert
999*7f2fe78bSCy Schubert CK_RV
C_GetSlotList(CK_BBOOL tokenPresent,CK_SLOT_ID_PTR pSlotList,CK_ULONG_PTR pulCount)1000*7f2fe78bSCy Schubert C_GetSlotList(CK_BBOOL tokenPresent,
1001*7f2fe78bSCy Schubert CK_SLOT_ID_PTR pSlotList,
1002*7f2fe78bSCy Schubert CK_ULONG_PTR pulCount)
1003*7f2fe78bSCy Schubert {
1004*7f2fe78bSCy Schubert st_logf("GetSlotList: %s\n",
1005*7f2fe78bSCy Schubert tokenPresent ? "tokenPresent" : "token not Present");
1006*7f2fe78bSCy Schubert if (pSlotList)
1007*7f2fe78bSCy Schubert pSlotList[0] = 1;
1008*7f2fe78bSCy Schubert *pulCount = 1;
1009*7f2fe78bSCy Schubert return CKR_OK;
1010*7f2fe78bSCy Schubert }
1011*7f2fe78bSCy Schubert
1012*7f2fe78bSCy Schubert CK_RV
C_GetSlotInfo(CK_SLOT_ID slotID,CK_SLOT_INFO_PTR pInfo)1013*7f2fe78bSCy Schubert C_GetSlotInfo(CK_SLOT_ID slotID,
1014*7f2fe78bSCy Schubert CK_SLOT_INFO_PTR pInfo)
1015*7f2fe78bSCy Schubert {
1016*7f2fe78bSCy Schubert st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID, has_session());
1017*7f2fe78bSCy Schubert
1018*7f2fe78bSCy Schubert memset(pInfo, 18, sizeof(*pInfo));
1019*7f2fe78bSCy Schubert
1020*7f2fe78bSCy Schubert if (slotID != 1)
1021*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1022*7f2fe78bSCy Schubert
1023*7f2fe78bSCy Schubert snprintf_fill((char *)pInfo->slotDescription,
1024*7f2fe78bSCy Schubert sizeof(pInfo->slotDescription),
1025*7f2fe78bSCy Schubert ' ',
1026*7f2fe78bSCy Schubert "SoftToken (slot)");
1027*7f2fe78bSCy Schubert snprintf_fill((char *)pInfo->manufacturerID,
1028*7f2fe78bSCy Schubert sizeof(pInfo->manufacturerID),
1029*7f2fe78bSCy Schubert ' ',
1030*7f2fe78bSCy Schubert "SoftToken (slot)");
1031*7f2fe78bSCy Schubert pInfo->flags = CKF_TOKEN_PRESENT;
1032*7f2fe78bSCy Schubert if (soft_token.flags.hardware_slot)
1033*7f2fe78bSCy Schubert pInfo->flags |= CKF_HW_SLOT;
1034*7f2fe78bSCy Schubert pInfo->hardwareVersion.major = 1;
1035*7f2fe78bSCy Schubert pInfo->hardwareVersion.minor = 0;
1036*7f2fe78bSCy Schubert pInfo->firmwareVersion.major = 1;
1037*7f2fe78bSCy Schubert pInfo->firmwareVersion.minor = 0;
1038*7f2fe78bSCy Schubert
1039*7f2fe78bSCy Schubert return CKR_OK;
1040*7f2fe78bSCy Schubert }
1041*7f2fe78bSCy Schubert
1042*7f2fe78bSCy Schubert CK_RV
C_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)1043*7f2fe78bSCy Schubert C_GetTokenInfo(CK_SLOT_ID slotID,
1044*7f2fe78bSCy Schubert CK_TOKEN_INFO_PTR pInfo)
1045*7f2fe78bSCy Schubert {
1046*7f2fe78bSCy Schubert st_logf("GetTokenInfo: %s\n", has_session());
1047*7f2fe78bSCy Schubert
1048*7f2fe78bSCy Schubert memset(pInfo, 19, sizeof(*pInfo));
1049*7f2fe78bSCy Schubert
1050*7f2fe78bSCy Schubert snprintf_fill((char *)pInfo->label,
1051*7f2fe78bSCy Schubert sizeof(pInfo->label),
1052*7f2fe78bSCy Schubert ' ',
1053*7f2fe78bSCy Schubert "SoftToken (token)");
1054*7f2fe78bSCy Schubert snprintf_fill((char *)pInfo->manufacturerID,
1055*7f2fe78bSCy Schubert sizeof(pInfo->manufacturerID),
1056*7f2fe78bSCy Schubert ' ',
1057*7f2fe78bSCy Schubert "SoftToken (token)");
1058*7f2fe78bSCy Schubert snprintf_fill((char *)pInfo->model,
1059*7f2fe78bSCy Schubert sizeof(pInfo->model),
1060*7f2fe78bSCy Schubert ' ',
1061*7f2fe78bSCy Schubert "SoftToken (token)");
1062*7f2fe78bSCy Schubert snprintf_fill((char *)pInfo->serialNumber,
1063*7f2fe78bSCy Schubert sizeof(pInfo->serialNumber),
1064*7f2fe78bSCy Schubert ' ',
1065*7f2fe78bSCy Schubert "4711");
1066*7f2fe78bSCy Schubert pInfo->flags =
1067*7f2fe78bSCy Schubert CKF_TOKEN_INITIALIZED |
1068*7f2fe78bSCy Schubert CKF_USER_PIN_INITIALIZED;
1069*7f2fe78bSCy Schubert
1070*7f2fe78bSCy Schubert if (soft_token.flags.login_done == 0)
1071*7f2fe78bSCy Schubert pInfo->flags |= CKF_LOGIN_REQUIRED;
1072*7f2fe78bSCy Schubert
1073*7f2fe78bSCy Schubert /* CFK_RNG |
1074*7f2fe78bSCy Schubert CKF_RESTORE_KEY_NOT_NEEDED |
1075*7f2fe78bSCy Schubert */
1076*7f2fe78bSCy Schubert pInfo->ulMaxSessionCount = MAX_NUM_SESSION;
1077*7f2fe78bSCy Schubert pInfo->ulSessionCount = soft_token.open_sessions;
1078*7f2fe78bSCy Schubert pInfo->ulMaxRwSessionCount = MAX_NUM_SESSION;
1079*7f2fe78bSCy Schubert pInfo->ulRwSessionCount = soft_token.open_sessions;
1080*7f2fe78bSCy Schubert pInfo->ulMaxPinLen = 1024;
1081*7f2fe78bSCy Schubert pInfo->ulMinPinLen = 0;
1082*7f2fe78bSCy Schubert pInfo->ulTotalPublicMemory = 4711;
1083*7f2fe78bSCy Schubert pInfo->ulFreePublicMemory = 4712;
1084*7f2fe78bSCy Schubert pInfo->ulTotalPrivateMemory = 4713;
1085*7f2fe78bSCy Schubert pInfo->ulFreePrivateMemory = 4714;
1086*7f2fe78bSCy Schubert pInfo->hardwareVersion.major = 2;
1087*7f2fe78bSCy Schubert pInfo->hardwareVersion.minor = 0;
1088*7f2fe78bSCy Schubert pInfo->firmwareVersion.major = 2;
1089*7f2fe78bSCy Schubert pInfo->firmwareVersion.minor = 0;
1090*7f2fe78bSCy Schubert
1091*7f2fe78bSCy Schubert return CKR_OK;
1092*7f2fe78bSCy Schubert }
1093*7f2fe78bSCy Schubert
1094*7f2fe78bSCy Schubert CK_RV
C_GetMechanismList(CK_SLOT_ID slotID,CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)1095*7f2fe78bSCy Schubert C_GetMechanismList(CK_SLOT_ID slotID,
1096*7f2fe78bSCy Schubert CK_MECHANISM_TYPE_PTR pMechanismList,
1097*7f2fe78bSCy Schubert CK_ULONG_PTR pulCount)
1098*7f2fe78bSCy Schubert {
1099*7f2fe78bSCy Schubert st_logf("GetMechanismList\n");
1100*7f2fe78bSCy Schubert
1101*7f2fe78bSCy Schubert *pulCount = 2;
1102*7f2fe78bSCy Schubert if (pMechanismList == NULL_PTR)
1103*7f2fe78bSCy Schubert return CKR_OK;
1104*7f2fe78bSCy Schubert pMechanismList[0] = CKM_RSA_X_509;
1105*7f2fe78bSCy Schubert pMechanismList[1] = CKM_RSA_PKCS;
1106*7f2fe78bSCy Schubert
1107*7f2fe78bSCy Schubert return CKR_OK;
1108*7f2fe78bSCy Schubert }
1109*7f2fe78bSCy Schubert
1110*7f2fe78bSCy Schubert CK_RV
C_GetMechanismInfo(CK_SLOT_ID slotID,CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)1111*7f2fe78bSCy Schubert C_GetMechanismInfo(CK_SLOT_ID slotID,
1112*7f2fe78bSCy Schubert CK_MECHANISM_TYPE type,
1113*7f2fe78bSCy Schubert CK_MECHANISM_INFO_PTR pInfo)
1114*7f2fe78bSCy Schubert {
1115*7f2fe78bSCy Schubert st_logf("GetMechanismInfo: slot %d type: %d\n",
1116*7f2fe78bSCy Schubert (int)slotID, (int)type);
1117*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1118*7f2fe78bSCy Schubert }
1119*7f2fe78bSCy Schubert
1120*7f2fe78bSCy Schubert CK_RV
C_InitToken(CK_SLOT_ID slotID,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel)1121*7f2fe78bSCy Schubert C_InitToken(CK_SLOT_ID slotID,
1122*7f2fe78bSCy Schubert CK_UTF8CHAR_PTR pPin,
1123*7f2fe78bSCy Schubert CK_ULONG ulPinLen,
1124*7f2fe78bSCy Schubert CK_UTF8CHAR_PTR pLabel)
1125*7f2fe78bSCy Schubert {
1126*7f2fe78bSCy Schubert st_logf("InitToken: slot %d\n", (int)slotID);
1127*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1128*7f2fe78bSCy Schubert }
1129*7f2fe78bSCy Schubert
1130*7f2fe78bSCy Schubert CK_RV
C_OpenSession(CK_SLOT_ID slotID,CK_FLAGS flags,CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession)1131*7f2fe78bSCy Schubert C_OpenSession(CK_SLOT_ID slotID,
1132*7f2fe78bSCy Schubert CK_FLAGS flags,
1133*7f2fe78bSCy Schubert CK_VOID_PTR pApplication,
1134*7f2fe78bSCy Schubert CK_NOTIFY Notify,
1135*7f2fe78bSCy Schubert CK_SESSION_HANDLE_PTR phSession)
1136*7f2fe78bSCy Schubert {
1137*7f2fe78bSCy Schubert size_t i;
1138*7f2fe78bSCy Schubert
1139*7f2fe78bSCy Schubert st_logf("OpenSession: slot: %d\n", (int)slotID);
1140*7f2fe78bSCy Schubert
1141*7f2fe78bSCy Schubert if (soft_token.open_sessions == MAX_NUM_SESSION)
1142*7f2fe78bSCy Schubert return CKR_SESSION_COUNT;
1143*7f2fe78bSCy Schubert
1144*7f2fe78bSCy Schubert soft_token.application = pApplication;
1145*7f2fe78bSCy Schubert soft_token.notify = Notify;
1146*7f2fe78bSCy Schubert
1147*7f2fe78bSCy Schubert for (i = 0; i < MAX_NUM_SESSION; i++)
1148*7f2fe78bSCy Schubert if (soft_token.state[i].session_handle == CK_INVALID_HANDLE)
1149*7f2fe78bSCy Schubert break;
1150*7f2fe78bSCy Schubert if (i == MAX_NUM_SESSION)
1151*7f2fe78bSCy Schubert abort();
1152*7f2fe78bSCy Schubert
1153*7f2fe78bSCy Schubert soft_token.open_sessions++;
1154*7f2fe78bSCy Schubert
1155*7f2fe78bSCy Schubert soft_token.state[i].session_handle = soft_token.next_session_handle++;
1156*7f2fe78bSCy Schubert *phSession = soft_token.state[i].session_handle;
1157*7f2fe78bSCy Schubert
1158*7f2fe78bSCy Schubert return CKR_OK;
1159*7f2fe78bSCy Schubert }
1160*7f2fe78bSCy Schubert
1161*7f2fe78bSCy Schubert CK_RV
C_CloseSession(CK_SESSION_HANDLE hSession)1162*7f2fe78bSCy Schubert C_CloseSession(CK_SESSION_HANDLE hSession)
1163*7f2fe78bSCy Schubert {
1164*7f2fe78bSCy Schubert struct session_state *state;
1165*7f2fe78bSCy Schubert st_logf("CloseSession\n");
1166*7f2fe78bSCy Schubert
1167*7f2fe78bSCy Schubert if (verify_session_handle(hSession, &state) != CKR_OK)
1168*7f2fe78bSCy Schubert application_error("closed session not open");
1169*7f2fe78bSCy Schubert else
1170*7f2fe78bSCy Schubert close_session(state);
1171*7f2fe78bSCy Schubert
1172*7f2fe78bSCy Schubert return CKR_OK;
1173*7f2fe78bSCy Schubert }
1174*7f2fe78bSCy Schubert
1175*7f2fe78bSCy Schubert CK_RV
C_CloseAllSessions(CK_SLOT_ID slotID)1176*7f2fe78bSCy Schubert C_CloseAllSessions(CK_SLOT_ID slotID)
1177*7f2fe78bSCy Schubert {
1178*7f2fe78bSCy Schubert size_t i;
1179*7f2fe78bSCy Schubert
1180*7f2fe78bSCy Schubert st_logf("CloseAllSessions\n");
1181*7f2fe78bSCy Schubert
1182*7f2fe78bSCy Schubert for (i = 0; i < MAX_NUM_SESSION; i++)
1183*7f2fe78bSCy Schubert if (soft_token.state[i].session_handle != CK_INVALID_HANDLE)
1184*7f2fe78bSCy Schubert close_session(&soft_token.state[i]);
1185*7f2fe78bSCy Schubert
1186*7f2fe78bSCy Schubert return CKR_OK;
1187*7f2fe78bSCy Schubert }
1188*7f2fe78bSCy Schubert
1189*7f2fe78bSCy Schubert CK_RV
C_GetSessionInfo(CK_SESSION_HANDLE hSession,CK_SESSION_INFO_PTR pInfo)1190*7f2fe78bSCy Schubert C_GetSessionInfo(CK_SESSION_HANDLE hSession,
1191*7f2fe78bSCy Schubert CK_SESSION_INFO_PTR pInfo)
1192*7f2fe78bSCy Schubert {
1193*7f2fe78bSCy Schubert st_logf("GetSessionInfo\n");
1194*7f2fe78bSCy Schubert
1195*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1196*7f2fe78bSCy Schubert
1197*7f2fe78bSCy Schubert memset(pInfo, 20, sizeof(*pInfo));
1198*7f2fe78bSCy Schubert
1199*7f2fe78bSCy Schubert pInfo->slotID = 1;
1200*7f2fe78bSCy Schubert if (soft_token.flags.login_done)
1201*7f2fe78bSCy Schubert pInfo->state = CKS_RO_USER_FUNCTIONS;
1202*7f2fe78bSCy Schubert else
1203*7f2fe78bSCy Schubert pInfo->state = CKS_RO_PUBLIC_SESSION;
1204*7f2fe78bSCy Schubert pInfo->flags = CKF_SERIAL_SESSION;
1205*7f2fe78bSCy Schubert pInfo->ulDeviceError = 0;
1206*7f2fe78bSCy Schubert
1207*7f2fe78bSCy Schubert return CKR_OK;
1208*7f2fe78bSCy Schubert }
1209*7f2fe78bSCy Schubert
1210*7f2fe78bSCy Schubert CK_RV
C_Login(CK_SESSION_HANDLE hSession,CK_USER_TYPE userType,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)1211*7f2fe78bSCy Schubert C_Login(CK_SESSION_HANDLE hSession,
1212*7f2fe78bSCy Schubert CK_USER_TYPE userType,
1213*7f2fe78bSCy Schubert CK_UTF8CHAR_PTR pPin,
1214*7f2fe78bSCy Schubert CK_ULONG ulPinLen)
1215*7f2fe78bSCy Schubert {
1216*7f2fe78bSCy Schubert char *pin = NULL;
1217*7f2fe78bSCy Schubert int i;
1218*7f2fe78bSCy Schubert
1219*7f2fe78bSCy Schubert st_logf("Login\n");
1220*7f2fe78bSCy Schubert
1221*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1222*7f2fe78bSCy Schubert
1223*7f2fe78bSCy Schubert if (pPin != NULL_PTR) {
1224*7f2fe78bSCy Schubert if (asprintf(&pin, "%.*s", (int)ulPinLen, pPin) < 0)
1225*7f2fe78bSCy Schubert return CKR_DEVICE_MEMORY;
1226*7f2fe78bSCy Schubert st_logf("type: %d password: %s\n", (int)userType, pin);
1227*7f2fe78bSCy Schubert }
1228*7f2fe78bSCy Schubert
1229*7f2fe78bSCy Schubert for (i = 0; i < soft_token.object.num_objs; i++) {
1230*7f2fe78bSCy Schubert struct st_object *o = soft_token.object.objs[i];
1231*7f2fe78bSCy Schubert FILE *f;
1232*7f2fe78bSCy Schubert
1233*7f2fe78bSCy Schubert if (o->type != STO_T_PRIVATE_KEY)
1234*7f2fe78bSCy Schubert continue;
1235*7f2fe78bSCy Schubert
1236*7f2fe78bSCy Schubert if (o->u.private_key.key)
1237*7f2fe78bSCy Schubert continue;
1238*7f2fe78bSCy Schubert
1239*7f2fe78bSCy Schubert f = fopen(o->u.private_key.file, "r");
1240*7f2fe78bSCy Schubert if (f == NULL) {
1241*7f2fe78bSCy Schubert st_logf("can't open private file: %s\n", o->u.private_key.file);
1242*7f2fe78bSCy Schubert continue;
1243*7f2fe78bSCy Schubert }
1244*7f2fe78bSCy Schubert
1245*7f2fe78bSCy Schubert o->u.private_key.key = PEM_read_PrivateKey(f, NULL, NULL, pin);
1246*7f2fe78bSCy Schubert fclose(f);
1247*7f2fe78bSCy Schubert if (o->u.private_key.key == NULL) {
1248*7f2fe78bSCy Schubert st_logf("failed to read key: %s error: %s\n",
1249*7f2fe78bSCy Schubert o->u.private_key.file,
1250*7f2fe78bSCy Schubert ERR_error_string(ERR_get_error(), NULL));
1251*7f2fe78bSCy Schubert /* just ignore failure */;
1252*7f2fe78bSCy Schubert continue;
1253*7f2fe78bSCy Schubert }
1254*7f2fe78bSCy Schubert
1255*7f2fe78bSCy Schubert /* XXX check keytype */
1256*7f2fe78bSCy Schubert
1257*7f2fe78bSCy Schubert if (X509_check_private_key(o->u.private_key.cert, o->u.private_key.key) != 1) {
1258*7f2fe78bSCy Schubert EVP_PKEY_free(o->u.private_key.key);
1259*7f2fe78bSCy Schubert o->u.private_key.key = NULL;
1260*7f2fe78bSCy Schubert st_logf("private key %s doesn't verify\n", o->u.private_key.file);
1261*7f2fe78bSCy Schubert continue;
1262*7f2fe78bSCy Schubert }
1263*7f2fe78bSCy Schubert
1264*7f2fe78bSCy Schubert soft_token.flags.login_done = 1;
1265*7f2fe78bSCy Schubert }
1266*7f2fe78bSCy Schubert free(pin);
1267*7f2fe78bSCy Schubert
1268*7f2fe78bSCy Schubert return soft_token.flags.login_done ? CKR_OK : CKR_PIN_INCORRECT;
1269*7f2fe78bSCy Schubert }
1270*7f2fe78bSCy Schubert
1271*7f2fe78bSCy Schubert CK_RV
C_Logout(CK_SESSION_HANDLE hSession)1272*7f2fe78bSCy Schubert C_Logout(CK_SESSION_HANDLE hSession)
1273*7f2fe78bSCy Schubert {
1274*7f2fe78bSCy Schubert st_logf("Logout\n");
1275*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1276*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1277*7f2fe78bSCy Schubert }
1278*7f2fe78bSCy Schubert
1279*7f2fe78bSCy Schubert CK_RV
C_GetObjectSize(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize)1280*7f2fe78bSCy Schubert C_GetObjectSize(CK_SESSION_HANDLE hSession,
1281*7f2fe78bSCy Schubert CK_OBJECT_HANDLE hObject,
1282*7f2fe78bSCy Schubert CK_ULONG_PTR pulSize)
1283*7f2fe78bSCy Schubert {
1284*7f2fe78bSCy Schubert st_logf("GetObjectSize\n");
1285*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1286*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1287*7f2fe78bSCy Schubert }
1288*7f2fe78bSCy Schubert
1289*7f2fe78bSCy Schubert CK_RV
C_GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1290*7f2fe78bSCy Schubert C_GetAttributeValue(CK_SESSION_HANDLE hSession,
1291*7f2fe78bSCy Schubert CK_OBJECT_HANDLE hObject,
1292*7f2fe78bSCy Schubert CK_ATTRIBUTE_PTR pTemplate,
1293*7f2fe78bSCy Schubert CK_ULONG ulCount)
1294*7f2fe78bSCy Schubert {
1295*7f2fe78bSCy Schubert struct session_state *state;
1296*7f2fe78bSCy Schubert struct st_object *obj;
1297*7f2fe78bSCy Schubert CK_ULONG i;
1298*7f2fe78bSCy Schubert CK_RV ret;
1299*7f2fe78bSCy Schubert int j;
1300*7f2fe78bSCy Schubert
1301*7f2fe78bSCy Schubert st_logf("GetAttributeValue: %lx\n",
1302*7f2fe78bSCy Schubert (unsigned long)HANDLE_OBJECT_ID(hObject));
1303*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1304*7f2fe78bSCy Schubert
1305*7f2fe78bSCy Schubert if ((ret = object_handle_to_object(hObject, &obj)) != CKR_OK) {
1306*7f2fe78bSCy Schubert st_logf("object not found: %lx\n",
1307*7f2fe78bSCy Schubert (unsigned long)HANDLE_OBJECT_ID(hObject));
1308*7f2fe78bSCy Schubert return ret;
1309*7f2fe78bSCy Schubert }
1310*7f2fe78bSCy Schubert
1311*7f2fe78bSCy Schubert for (i = 0; i < ulCount; i++) {
1312*7f2fe78bSCy Schubert st_logf(" getting 0x%08lx\n", (unsigned long)pTemplate[i].type);
1313*7f2fe78bSCy Schubert for (j = 0; j < obj->num_attributes; j++) {
1314*7f2fe78bSCy Schubert if (obj->attrs[j].secret) {
1315*7f2fe78bSCy Schubert pTemplate[i].ulValueLen = (CK_ULONG)-1;
1316*7f2fe78bSCy Schubert break;
1317*7f2fe78bSCy Schubert }
1318*7f2fe78bSCy Schubert if (pTemplate[i].type == obj->attrs[j].attribute.type) {
1319*7f2fe78bSCy Schubert if (pTemplate[i].pValue != NULL_PTR && obj->attrs[j].secret == 0) {
1320*7f2fe78bSCy Schubert if (pTemplate[i].ulValueLen >= obj->attrs[j].attribute.ulValueLen)
1321*7f2fe78bSCy Schubert memcpy(pTemplate[i].pValue, obj->attrs[j].attribute.pValue,
1322*7f2fe78bSCy Schubert obj->attrs[j].attribute.ulValueLen);
1323*7f2fe78bSCy Schubert }
1324*7f2fe78bSCy Schubert pTemplate[i].ulValueLen = obj->attrs[j].attribute.ulValueLen;
1325*7f2fe78bSCy Schubert break;
1326*7f2fe78bSCy Schubert }
1327*7f2fe78bSCy Schubert }
1328*7f2fe78bSCy Schubert if (j == obj->num_attributes) {
1329*7f2fe78bSCy Schubert st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate[i].type);
1330*7f2fe78bSCy Schubert pTemplate[i].ulValueLen = (CK_ULONG)-1;
1331*7f2fe78bSCy Schubert }
1332*7f2fe78bSCy Schubert
1333*7f2fe78bSCy Schubert }
1334*7f2fe78bSCy Schubert return CKR_OK;
1335*7f2fe78bSCy Schubert }
1336*7f2fe78bSCy Schubert
1337*7f2fe78bSCy Schubert CK_RV
C_FindObjectsInit(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)1338*7f2fe78bSCy Schubert C_FindObjectsInit(CK_SESSION_HANDLE hSession,
1339*7f2fe78bSCy Schubert CK_ATTRIBUTE_PTR pTemplate,
1340*7f2fe78bSCy Schubert CK_ULONG ulCount)
1341*7f2fe78bSCy Schubert {
1342*7f2fe78bSCy Schubert struct session_state *state;
1343*7f2fe78bSCy Schubert
1344*7f2fe78bSCy Schubert st_logf("FindObjectsInit\n");
1345*7f2fe78bSCy Schubert
1346*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1347*7f2fe78bSCy Schubert
1348*7f2fe78bSCy Schubert if (state->find.next_object != -1) {
1349*7f2fe78bSCy Schubert application_error("application didn't do C_FindObjectsFinal\n");
1350*7f2fe78bSCy Schubert find_object_final(state);
1351*7f2fe78bSCy Schubert }
1352*7f2fe78bSCy Schubert if (ulCount) {
1353*7f2fe78bSCy Schubert CK_ULONG i;
1354*7f2fe78bSCy Schubert
1355*7f2fe78bSCy Schubert print_attributes(pTemplate, ulCount);
1356*7f2fe78bSCy Schubert
1357*7f2fe78bSCy Schubert state->find.attributes =
1358*7f2fe78bSCy Schubert calloc(1, ulCount * sizeof(state->find.attributes[0]));
1359*7f2fe78bSCy Schubert if (state->find.attributes == NULL)
1360*7f2fe78bSCy Schubert return CKR_DEVICE_MEMORY;
1361*7f2fe78bSCy Schubert for (i = 0; i < ulCount; i++) {
1362*7f2fe78bSCy Schubert state->find.attributes[i].pValue =
1363*7f2fe78bSCy Schubert malloc(pTemplate[i].ulValueLen);
1364*7f2fe78bSCy Schubert if (state->find.attributes[i].pValue == NULL) {
1365*7f2fe78bSCy Schubert find_object_final(state);
1366*7f2fe78bSCy Schubert return CKR_DEVICE_MEMORY;
1367*7f2fe78bSCy Schubert }
1368*7f2fe78bSCy Schubert memcpy(state->find.attributes[i].pValue,
1369*7f2fe78bSCy Schubert pTemplate[i].pValue, pTemplate[i].ulValueLen);
1370*7f2fe78bSCy Schubert state->find.attributes[i].type = pTemplate[i].type;
1371*7f2fe78bSCy Schubert state->find.attributes[i].ulValueLen = pTemplate[i].ulValueLen;
1372*7f2fe78bSCy Schubert }
1373*7f2fe78bSCy Schubert state->find.num_attributes = ulCount;
1374*7f2fe78bSCy Schubert state->find.next_object = 0;
1375*7f2fe78bSCy Schubert } else {
1376*7f2fe78bSCy Schubert st_logf("find all objects\n");
1377*7f2fe78bSCy Schubert state->find.attributes = NULL;
1378*7f2fe78bSCy Schubert state->find.num_attributes = 0;
1379*7f2fe78bSCy Schubert state->find.next_object = 0;
1380*7f2fe78bSCy Schubert }
1381*7f2fe78bSCy Schubert
1382*7f2fe78bSCy Schubert return CKR_OK;
1383*7f2fe78bSCy Schubert }
1384*7f2fe78bSCy Schubert
1385*7f2fe78bSCy Schubert CK_RV
C_FindObjects(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount)1386*7f2fe78bSCy Schubert C_FindObjects(CK_SESSION_HANDLE hSession,
1387*7f2fe78bSCy Schubert CK_OBJECT_HANDLE_PTR phObject,
1388*7f2fe78bSCy Schubert CK_ULONG ulMaxObjectCount,
1389*7f2fe78bSCy Schubert CK_ULONG_PTR pulObjectCount)
1390*7f2fe78bSCy Schubert {
1391*7f2fe78bSCy Schubert struct session_state *state;
1392*7f2fe78bSCy Schubert int i;
1393*7f2fe78bSCy Schubert
1394*7f2fe78bSCy Schubert st_logf("FindObjects\n");
1395*7f2fe78bSCy Schubert
1396*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1397*7f2fe78bSCy Schubert
1398*7f2fe78bSCy Schubert if (state->find.next_object == -1) {
1399*7f2fe78bSCy Schubert application_error("application didn't do C_FindObjectsInit\n");
1400*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1401*7f2fe78bSCy Schubert }
1402*7f2fe78bSCy Schubert if (ulMaxObjectCount == 0) {
1403*7f2fe78bSCy Schubert application_error("application asked for 0 objects\n");
1404*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1405*7f2fe78bSCy Schubert }
1406*7f2fe78bSCy Schubert *pulObjectCount = 0;
1407*7f2fe78bSCy Schubert for (i = state->find.next_object; i < soft_token.object.num_objs; i++) {
1408*7f2fe78bSCy Schubert st_logf("FindObjects: %d\n", i);
1409*7f2fe78bSCy Schubert state->find.next_object = i + 1;
1410*7f2fe78bSCy Schubert if (attributes_match(soft_token.object.objs[i],
1411*7f2fe78bSCy Schubert state->find.attributes,
1412*7f2fe78bSCy Schubert state->find.num_attributes)) {
1413*7f2fe78bSCy Schubert *phObject++ = soft_token.object.objs[i]->object_handle;
1414*7f2fe78bSCy Schubert ulMaxObjectCount--;
1415*7f2fe78bSCy Schubert (*pulObjectCount)++;
1416*7f2fe78bSCy Schubert if (ulMaxObjectCount == 0)
1417*7f2fe78bSCy Schubert break;
1418*7f2fe78bSCy Schubert }
1419*7f2fe78bSCy Schubert }
1420*7f2fe78bSCy Schubert return CKR_OK;
1421*7f2fe78bSCy Schubert }
1422*7f2fe78bSCy Schubert
1423*7f2fe78bSCy Schubert CK_RV
C_FindObjectsFinal(CK_SESSION_HANDLE hSession)1424*7f2fe78bSCy Schubert C_FindObjectsFinal(CK_SESSION_HANDLE hSession)
1425*7f2fe78bSCy Schubert {
1426*7f2fe78bSCy Schubert struct session_state *state;
1427*7f2fe78bSCy Schubert
1428*7f2fe78bSCy Schubert st_logf("FindObjectsFinal\n");
1429*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1430*7f2fe78bSCy Schubert find_object_final(state);
1431*7f2fe78bSCy Schubert return CKR_OK;
1432*7f2fe78bSCy Schubert }
1433*7f2fe78bSCy Schubert
1434*7f2fe78bSCy Schubert static CK_RV
commonInit(CK_ATTRIBUTE * attr_match,int attr_match_len,const CK_MECHANISM_TYPE * mechs,int mechs_len,const CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey,struct st_object ** o)1435*7f2fe78bSCy Schubert commonInit(CK_ATTRIBUTE *attr_match, int attr_match_len,
1436*7f2fe78bSCy Schubert const CK_MECHANISM_TYPE *mechs, int mechs_len,
1437*7f2fe78bSCy Schubert const CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey,
1438*7f2fe78bSCy Schubert struct st_object **o)
1439*7f2fe78bSCy Schubert {
1440*7f2fe78bSCy Schubert CK_RV ret;
1441*7f2fe78bSCy Schubert int i;
1442*7f2fe78bSCy Schubert
1443*7f2fe78bSCy Schubert *o = NULL;
1444*7f2fe78bSCy Schubert if ((ret = object_handle_to_object(hKey, o)) != CKR_OK)
1445*7f2fe78bSCy Schubert return ret;
1446*7f2fe78bSCy Schubert
1447*7f2fe78bSCy Schubert ret = attributes_match(*o, attr_match, attr_match_len);
1448*7f2fe78bSCy Schubert if (!ret) {
1449*7f2fe78bSCy Schubert application_error("called commonInit on key that doesn't "
1450*7f2fe78bSCy Schubert "support required attr");
1451*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1452*7f2fe78bSCy Schubert }
1453*7f2fe78bSCy Schubert
1454*7f2fe78bSCy Schubert for (i = 0; i < mechs_len; i++)
1455*7f2fe78bSCy Schubert if (mechs[i] == pMechanism->mechanism)
1456*7f2fe78bSCy Schubert break;
1457*7f2fe78bSCy Schubert if (i == mechs_len) {
1458*7f2fe78bSCy Schubert application_error("called mech (%08lx) not supported\n",
1459*7f2fe78bSCy Schubert pMechanism->mechanism);
1460*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1461*7f2fe78bSCy Schubert }
1462*7f2fe78bSCy Schubert return CKR_OK;
1463*7f2fe78bSCy Schubert }
1464*7f2fe78bSCy Schubert
1465*7f2fe78bSCy Schubert
1466*7f2fe78bSCy Schubert static CK_RV
dup_mechanism(CK_MECHANISM_PTR * dup,const CK_MECHANISM_PTR pMechanism)1467*7f2fe78bSCy Schubert dup_mechanism(CK_MECHANISM_PTR *dup, const CK_MECHANISM_PTR pMechanism)
1468*7f2fe78bSCy Schubert {
1469*7f2fe78bSCy Schubert CK_MECHANISM_PTR p;
1470*7f2fe78bSCy Schubert
1471*7f2fe78bSCy Schubert p = malloc(sizeof(*p));
1472*7f2fe78bSCy Schubert if (p == NULL)
1473*7f2fe78bSCy Schubert return CKR_DEVICE_MEMORY;
1474*7f2fe78bSCy Schubert
1475*7f2fe78bSCy Schubert if (*dup)
1476*7f2fe78bSCy Schubert free(*dup);
1477*7f2fe78bSCy Schubert *dup = p;
1478*7f2fe78bSCy Schubert memcpy(p, pMechanism, sizeof(*p));
1479*7f2fe78bSCy Schubert
1480*7f2fe78bSCy Schubert return CKR_OK;
1481*7f2fe78bSCy Schubert }
1482*7f2fe78bSCy Schubert
1483*7f2fe78bSCy Schubert
1484*7f2fe78bSCy Schubert CK_RV
C_EncryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1485*7f2fe78bSCy Schubert C_EncryptInit(CK_SESSION_HANDLE hSession,
1486*7f2fe78bSCy Schubert CK_MECHANISM_PTR pMechanism,
1487*7f2fe78bSCy Schubert CK_OBJECT_HANDLE hKey)
1488*7f2fe78bSCy Schubert {
1489*7f2fe78bSCy Schubert struct session_state *state;
1490*7f2fe78bSCy Schubert CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
1491*7f2fe78bSCy Schubert CK_BBOOL bool_true = CK_TRUE;
1492*7f2fe78bSCy Schubert CK_ATTRIBUTE attr[] = {
1493*7f2fe78bSCy Schubert { CKA_ENCRYPT, &bool_true, sizeof(bool_true) }
1494*7f2fe78bSCy Schubert };
1495*7f2fe78bSCy Schubert struct st_object *o;
1496*7f2fe78bSCy Schubert CK_RV ret;
1497*7f2fe78bSCy Schubert
1498*7f2fe78bSCy Schubert st_logf("EncryptInit\n");
1499*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1500*7f2fe78bSCy Schubert
1501*7f2fe78bSCy Schubert ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1502*7f2fe78bSCy Schubert mechs, sizeof(mechs)/sizeof(mechs[0]),
1503*7f2fe78bSCy Schubert pMechanism, hKey, &o);
1504*7f2fe78bSCy Schubert if (ret)
1505*7f2fe78bSCy Schubert return ret;
1506*7f2fe78bSCy Schubert
1507*7f2fe78bSCy Schubert ret = dup_mechanism(&state->encrypt_mechanism, pMechanism);
1508*7f2fe78bSCy Schubert if (ret == CKR_OK)
1509*7f2fe78bSCy Schubert state->encrypt_object = OBJECT_ID(o);
1510*7f2fe78bSCy Schubert
1511*7f2fe78bSCy Schubert return ret;
1512*7f2fe78bSCy Schubert }
1513*7f2fe78bSCy Schubert
1514*7f2fe78bSCy Schubert CK_RV
C_Encrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)1515*7f2fe78bSCy Schubert C_Encrypt(CK_SESSION_HANDLE hSession,
1516*7f2fe78bSCy Schubert CK_BYTE_PTR pData,
1517*7f2fe78bSCy Schubert CK_ULONG ulDataLen,
1518*7f2fe78bSCy Schubert CK_BYTE_PTR pEncryptedData,
1519*7f2fe78bSCy Schubert CK_ULONG_PTR pulEncryptedDataLen)
1520*7f2fe78bSCy Schubert {
1521*7f2fe78bSCy Schubert struct session_state *state;
1522*7f2fe78bSCy Schubert struct st_object *o;
1523*7f2fe78bSCy Schubert void *buffer = NULL;
1524*7f2fe78bSCy Schubert CK_RV ret;
1525*7f2fe78bSCy Schubert size_t buffer_len = 0;
1526*7f2fe78bSCy Schubert int padding;
1527*7f2fe78bSCy Schubert EVP_PKEY_CTX *ctx = NULL;
1528*7f2fe78bSCy Schubert
1529*7f2fe78bSCy Schubert st_logf("Encrypt\n");
1530*7f2fe78bSCy Schubert
1531*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1532*7f2fe78bSCy Schubert
1533*7f2fe78bSCy Schubert if (state->encrypt_object == -1)
1534*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1535*7f2fe78bSCy Schubert
1536*7f2fe78bSCy Schubert o = soft_token.object.objs[state->encrypt_object];
1537*7f2fe78bSCy Schubert
1538*7f2fe78bSCy Schubert if (o->u.public_key == NULL) {
1539*7f2fe78bSCy Schubert st_logf("public key NULL\n");
1540*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1541*7f2fe78bSCy Schubert }
1542*7f2fe78bSCy Schubert
1543*7f2fe78bSCy Schubert if (pulEncryptedDataLen == NULL) {
1544*7f2fe78bSCy Schubert st_logf("pulEncryptedDataLen NULL\n");
1545*7f2fe78bSCy Schubert ret = CKR_ARGUMENTS_BAD;
1546*7f2fe78bSCy Schubert goto out;
1547*7f2fe78bSCy Schubert }
1548*7f2fe78bSCy Schubert
1549*7f2fe78bSCy Schubert if (pData == NULL) {
1550*7f2fe78bSCy Schubert st_logf("data NULL\n");
1551*7f2fe78bSCy Schubert ret = CKR_ARGUMENTS_BAD;
1552*7f2fe78bSCy Schubert goto out;
1553*7f2fe78bSCy Schubert }
1554*7f2fe78bSCy Schubert
1555*7f2fe78bSCy Schubert switch(state->encrypt_mechanism->mechanism) {
1556*7f2fe78bSCy Schubert case CKM_RSA_PKCS:
1557*7f2fe78bSCy Schubert padding = RSA_PKCS1_PADDING;
1558*7f2fe78bSCy Schubert break;
1559*7f2fe78bSCy Schubert case CKM_RSA_X_509:
1560*7f2fe78bSCy Schubert padding = RSA_NO_PADDING;
1561*7f2fe78bSCy Schubert break;
1562*7f2fe78bSCy Schubert default:
1563*7f2fe78bSCy Schubert ret = CKR_FUNCTION_NOT_SUPPORTED;
1564*7f2fe78bSCy Schubert goto out;
1565*7f2fe78bSCy Schubert }
1566*7f2fe78bSCy Schubert
1567*7f2fe78bSCy Schubert ctx = EVP_PKEY_CTX_new(o->u.public_key, NULL);
1568*7f2fe78bSCy Schubert if (ctx == NULL || EVP_PKEY_encrypt_init(ctx) <= 0 ||
1569*7f2fe78bSCy Schubert EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
1570*7f2fe78bSCy Schubert EVP_PKEY_encrypt(ctx, NULL, &buffer_len, pData, ulDataLen) <= 0) {
1571*7f2fe78bSCy Schubert ret = CKR_DEVICE_ERROR;
1572*7f2fe78bSCy Schubert goto out;
1573*7f2fe78bSCy Schubert }
1574*7f2fe78bSCy Schubert
1575*7f2fe78bSCy Schubert buffer = OPENSSL_malloc(buffer_len);
1576*7f2fe78bSCy Schubert if (buffer == NULL) {
1577*7f2fe78bSCy Schubert ret = CKR_DEVICE_MEMORY;
1578*7f2fe78bSCy Schubert goto out;
1579*7f2fe78bSCy Schubert }
1580*7f2fe78bSCy Schubert
1581*7f2fe78bSCy Schubert if (EVP_PKEY_encrypt(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) {
1582*7f2fe78bSCy Schubert ret = CKR_DEVICE_ERROR;
1583*7f2fe78bSCy Schubert goto out;
1584*7f2fe78bSCy Schubert }
1585*7f2fe78bSCy Schubert st_logf("Encrypt done\n");
1586*7f2fe78bSCy Schubert
1587*7f2fe78bSCy Schubert if (pEncryptedData != NULL)
1588*7f2fe78bSCy Schubert memcpy(pEncryptedData, buffer, buffer_len);
1589*7f2fe78bSCy Schubert *pulEncryptedDataLen = buffer_len;
1590*7f2fe78bSCy Schubert
1591*7f2fe78bSCy Schubert ret = CKR_OK;
1592*7f2fe78bSCy Schubert out:
1593*7f2fe78bSCy Schubert OPENSSL_cleanse(buffer, buffer_len);
1594*7f2fe78bSCy Schubert OPENSSL_free(buffer);
1595*7f2fe78bSCy Schubert EVP_PKEY_CTX_free(ctx);
1596*7f2fe78bSCy Schubert return ret;
1597*7f2fe78bSCy Schubert }
1598*7f2fe78bSCy Schubert
1599*7f2fe78bSCy Schubert CK_RV
C_EncryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen,CK_BYTE_PTR pEncryptedPart,CK_ULONG_PTR pulEncryptedPartLen)1600*7f2fe78bSCy Schubert C_EncryptUpdate(CK_SESSION_HANDLE hSession,
1601*7f2fe78bSCy Schubert CK_BYTE_PTR pPart,
1602*7f2fe78bSCy Schubert CK_ULONG ulPartLen,
1603*7f2fe78bSCy Schubert CK_BYTE_PTR pEncryptedPart,
1604*7f2fe78bSCy Schubert CK_ULONG_PTR pulEncryptedPartLen)
1605*7f2fe78bSCy Schubert {
1606*7f2fe78bSCy Schubert st_logf("EncryptUpdate\n");
1607*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1608*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1609*7f2fe78bSCy Schubert }
1610*7f2fe78bSCy Schubert
1611*7f2fe78bSCy Schubert
1612*7f2fe78bSCy Schubert CK_RV
C_EncryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pLastEncryptedPart,CK_ULONG_PTR pulLastEncryptedPartLen)1613*7f2fe78bSCy Schubert C_EncryptFinal(CK_SESSION_HANDLE hSession,
1614*7f2fe78bSCy Schubert CK_BYTE_PTR pLastEncryptedPart,
1615*7f2fe78bSCy Schubert CK_ULONG_PTR pulLastEncryptedPartLen)
1616*7f2fe78bSCy Schubert {
1617*7f2fe78bSCy Schubert st_logf("EncryptFinal\n");
1618*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1619*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1620*7f2fe78bSCy Schubert }
1621*7f2fe78bSCy Schubert
1622*7f2fe78bSCy Schubert
1623*7f2fe78bSCy Schubert /* C_DecryptInit initializes a decryption operation. */
1624*7f2fe78bSCy Schubert CK_RV
C_DecryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1625*7f2fe78bSCy Schubert C_DecryptInit(CK_SESSION_HANDLE hSession,
1626*7f2fe78bSCy Schubert CK_MECHANISM_PTR pMechanism,
1627*7f2fe78bSCy Schubert CK_OBJECT_HANDLE hKey)
1628*7f2fe78bSCy Schubert {
1629*7f2fe78bSCy Schubert struct session_state *state;
1630*7f2fe78bSCy Schubert CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
1631*7f2fe78bSCy Schubert CK_BBOOL bool_true = CK_TRUE;
1632*7f2fe78bSCy Schubert CK_ATTRIBUTE attr[] = {
1633*7f2fe78bSCy Schubert { CKA_DECRYPT, &bool_true, sizeof(bool_true) }
1634*7f2fe78bSCy Schubert };
1635*7f2fe78bSCy Schubert struct st_object *o;
1636*7f2fe78bSCy Schubert CK_RV ret;
1637*7f2fe78bSCy Schubert
1638*7f2fe78bSCy Schubert st_logf("DecryptInit\n");
1639*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1640*7f2fe78bSCy Schubert
1641*7f2fe78bSCy Schubert ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1642*7f2fe78bSCy Schubert mechs, sizeof(mechs)/sizeof(mechs[0]),
1643*7f2fe78bSCy Schubert pMechanism, hKey, &o);
1644*7f2fe78bSCy Schubert if (ret)
1645*7f2fe78bSCy Schubert return ret;
1646*7f2fe78bSCy Schubert
1647*7f2fe78bSCy Schubert ret = dup_mechanism(&state->decrypt_mechanism, pMechanism);
1648*7f2fe78bSCy Schubert if (ret == CKR_OK)
1649*7f2fe78bSCy Schubert state->decrypt_object = OBJECT_ID(o);
1650*7f2fe78bSCy Schubert
1651*7f2fe78bSCy Schubert return CKR_OK;
1652*7f2fe78bSCy Schubert }
1653*7f2fe78bSCy Schubert
1654*7f2fe78bSCy Schubert
1655*7f2fe78bSCy Schubert CK_RV
C_Decrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)1656*7f2fe78bSCy Schubert C_Decrypt(CK_SESSION_HANDLE hSession,
1657*7f2fe78bSCy Schubert CK_BYTE_PTR pEncryptedData,
1658*7f2fe78bSCy Schubert CK_ULONG ulEncryptedDataLen,
1659*7f2fe78bSCy Schubert CK_BYTE_PTR pData,
1660*7f2fe78bSCy Schubert CK_ULONG_PTR pulDataLen)
1661*7f2fe78bSCy Schubert {
1662*7f2fe78bSCy Schubert struct session_state *state;
1663*7f2fe78bSCy Schubert struct st_object *o;
1664*7f2fe78bSCy Schubert void *buffer = NULL;
1665*7f2fe78bSCy Schubert CK_RV ret;
1666*7f2fe78bSCy Schubert size_t buffer_len = 0;
1667*7f2fe78bSCy Schubert int padding;
1668*7f2fe78bSCy Schubert EVP_PKEY_CTX *ctx = NULL;
1669*7f2fe78bSCy Schubert
1670*7f2fe78bSCy Schubert st_logf("Decrypt\n");
1671*7f2fe78bSCy Schubert
1672*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1673*7f2fe78bSCy Schubert
1674*7f2fe78bSCy Schubert if (state->decrypt_object == -1)
1675*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1676*7f2fe78bSCy Schubert
1677*7f2fe78bSCy Schubert o = soft_token.object.objs[state->decrypt_object];
1678*7f2fe78bSCy Schubert
1679*7f2fe78bSCy Schubert if (o->u.private_key.key == NULL) {
1680*7f2fe78bSCy Schubert st_logf("private key NULL\n");
1681*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1682*7f2fe78bSCy Schubert }
1683*7f2fe78bSCy Schubert
1684*7f2fe78bSCy Schubert if (pulDataLen == NULL) {
1685*7f2fe78bSCy Schubert st_logf("pulDataLen NULL\n");
1686*7f2fe78bSCy Schubert ret = CKR_ARGUMENTS_BAD;
1687*7f2fe78bSCy Schubert goto out;
1688*7f2fe78bSCy Schubert }
1689*7f2fe78bSCy Schubert
1690*7f2fe78bSCy Schubert if (pEncryptedData == NULL_PTR) {
1691*7f2fe78bSCy Schubert st_logf("data NULL\n");
1692*7f2fe78bSCy Schubert ret = CKR_ARGUMENTS_BAD;
1693*7f2fe78bSCy Schubert goto out;
1694*7f2fe78bSCy Schubert }
1695*7f2fe78bSCy Schubert
1696*7f2fe78bSCy Schubert switch(state->decrypt_mechanism->mechanism) {
1697*7f2fe78bSCy Schubert case CKM_RSA_PKCS:
1698*7f2fe78bSCy Schubert padding = RSA_PKCS1_PADDING;
1699*7f2fe78bSCy Schubert break;
1700*7f2fe78bSCy Schubert case CKM_RSA_X_509:
1701*7f2fe78bSCy Schubert padding = RSA_NO_PADDING;
1702*7f2fe78bSCy Schubert break;
1703*7f2fe78bSCy Schubert default:
1704*7f2fe78bSCy Schubert ret = CKR_FUNCTION_NOT_SUPPORTED;
1705*7f2fe78bSCy Schubert goto out;
1706*7f2fe78bSCy Schubert }
1707*7f2fe78bSCy Schubert
1708*7f2fe78bSCy Schubert ctx = EVP_PKEY_CTX_new(o->u.private_key.key, NULL);
1709*7f2fe78bSCy Schubert if (ctx == NULL || EVP_PKEY_decrypt_init(ctx) <= 0 ||
1710*7f2fe78bSCy Schubert EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
1711*7f2fe78bSCy Schubert EVP_PKEY_decrypt(ctx, NULL, &buffer_len, pEncryptedData,
1712*7f2fe78bSCy Schubert ulEncryptedDataLen) <= 0) {
1713*7f2fe78bSCy Schubert ret = CKR_DEVICE_ERROR;
1714*7f2fe78bSCy Schubert goto out;
1715*7f2fe78bSCy Schubert }
1716*7f2fe78bSCy Schubert
1717*7f2fe78bSCy Schubert buffer = OPENSSL_malloc(buffer_len);
1718*7f2fe78bSCy Schubert if (buffer == NULL) {
1719*7f2fe78bSCy Schubert ret = CKR_DEVICE_MEMORY;
1720*7f2fe78bSCy Schubert goto out;
1721*7f2fe78bSCy Schubert }
1722*7f2fe78bSCy Schubert
1723*7f2fe78bSCy Schubert if (EVP_PKEY_decrypt(ctx, buffer, &buffer_len, pEncryptedData,
1724*7f2fe78bSCy Schubert ulEncryptedDataLen) <= 0) {
1725*7f2fe78bSCy Schubert ret = CKR_DEVICE_ERROR;
1726*7f2fe78bSCy Schubert goto out;
1727*7f2fe78bSCy Schubert }
1728*7f2fe78bSCy Schubert st_logf("Decrypt done\n");
1729*7f2fe78bSCy Schubert
1730*7f2fe78bSCy Schubert if (pData != NULL_PTR)
1731*7f2fe78bSCy Schubert memcpy(pData, buffer, buffer_len);
1732*7f2fe78bSCy Schubert *pulDataLen = buffer_len;
1733*7f2fe78bSCy Schubert
1734*7f2fe78bSCy Schubert ret = CKR_OK;
1735*7f2fe78bSCy Schubert out:
1736*7f2fe78bSCy Schubert OPENSSL_cleanse(buffer, buffer_len);
1737*7f2fe78bSCy Schubert OPENSSL_free(buffer);
1738*7f2fe78bSCy Schubert EVP_PKEY_CTX_free(ctx);
1739*7f2fe78bSCy Schubert return ret;
1740*7f2fe78bSCy Schubert }
1741*7f2fe78bSCy Schubert
1742*7f2fe78bSCy Schubert
1743*7f2fe78bSCy Schubert CK_RV
C_DecryptUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedPart,CK_ULONG ulEncryptedPartLen,CK_BYTE_PTR pPart,CK_ULONG_PTR pulPartLen)1744*7f2fe78bSCy Schubert C_DecryptUpdate(CK_SESSION_HANDLE hSession,
1745*7f2fe78bSCy Schubert CK_BYTE_PTR pEncryptedPart,
1746*7f2fe78bSCy Schubert CK_ULONG ulEncryptedPartLen,
1747*7f2fe78bSCy Schubert CK_BYTE_PTR pPart,
1748*7f2fe78bSCy Schubert CK_ULONG_PTR pulPartLen)
1749*7f2fe78bSCy Schubert
1750*7f2fe78bSCy Schubert {
1751*7f2fe78bSCy Schubert st_logf("DecryptUpdate\n");
1752*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1753*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1754*7f2fe78bSCy Schubert }
1755*7f2fe78bSCy Schubert
1756*7f2fe78bSCy Schubert
1757*7f2fe78bSCy Schubert CK_RV
C_DecryptFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pLastPart,CK_ULONG_PTR pulLastPartLen)1758*7f2fe78bSCy Schubert C_DecryptFinal(CK_SESSION_HANDLE hSession,
1759*7f2fe78bSCy Schubert CK_BYTE_PTR pLastPart,
1760*7f2fe78bSCy Schubert CK_ULONG_PTR pulLastPartLen)
1761*7f2fe78bSCy Schubert {
1762*7f2fe78bSCy Schubert st_logf("DecryptFinal\n");
1763*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1764*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1765*7f2fe78bSCy Schubert }
1766*7f2fe78bSCy Schubert
1767*7f2fe78bSCy Schubert CK_RV
C_DigestInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism)1768*7f2fe78bSCy Schubert C_DigestInit(CK_SESSION_HANDLE hSession,
1769*7f2fe78bSCy Schubert CK_MECHANISM_PTR pMechanism)
1770*7f2fe78bSCy Schubert {
1771*7f2fe78bSCy Schubert st_logf("DigestInit\n");
1772*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1773*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1774*7f2fe78bSCy Schubert }
1775*7f2fe78bSCy Schubert
1776*7f2fe78bSCy Schubert CK_RV
C_SignInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1777*7f2fe78bSCy Schubert C_SignInit(CK_SESSION_HANDLE hSession,
1778*7f2fe78bSCy Schubert CK_MECHANISM_PTR pMechanism,
1779*7f2fe78bSCy Schubert CK_OBJECT_HANDLE hKey)
1780*7f2fe78bSCy Schubert {
1781*7f2fe78bSCy Schubert struct session_state *state;
1782*7f2fe78bSCy Schubert CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
1783*7f2fe78bSCy Schubert CK_BBOOL bool_true = CK_TRUE;
1784*7f2fe78bSCy Schubert CK_ATTRIBUTE attr[] = {
1785*7f2fe78bSCy Schubert { CKA_SIGN, &bool_true, sizeof(bool_true) }
1786*7f2fe78bSCy Schubert };
1787*7f2fe78bSCy Schubert struct st_object *o;
1788*7f2fe78bSCy Schubert CK_RV ret;
1789*7f2fe78bSCy Schubert
1790*7f2fe78bSCy Schubert st_logf("SignInit\n");
1791*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1792*7f2fe78bSCy Schubert
1793*7f2fe78bSCy Schubert ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1794*7f2fe78bSCy Schubert mechs, sizeof(mechs)/sizeof(mechs[0]),
1795*7f2fe78bSCy Schubert pMechanism, hKey, &o);
1796*7f2fe78bSCy Schubert if (ret)
1797*7f2fe78bSCy Schubert return ret;
1798*7f2fe78bSCy Schubert
1799*7f2fe78bSCy Schubert ret = dup_mechanism(&state->sign_mechanism, pMechanism);
1800*7f2fe78bSCy Schubert if (ret == CKR_OK)
1801*7f2fe78bSCy Schubert state->sign_object = OBJECT_ID(o);
1802*7f2fe78bSCy Schubert
1803*7f2fe78bSCy Schubert return CKR_OK;
1804*7f2fe78bSCy Schubert }
1805*7f2fe78bSCy Schubert
1806*7f2fe78bSCy Schubert CK_RV
C_Sign(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)1807*7f2fe78bSCy Schubert C_Sign(CK_SESSION_HANDLE hSession,
1808*7f2fe78bSCy Schubert CK_BYTE_PTR pData,
1809*7f2fe78bSCy Schubert CK_ULONG ulDataLen,
1810*7f2fe78bSCy Schubert CK_BYTE_PTR pSignature,
1811*7f2fe78bSCy Schubert CK_ULONG_PTR pulSignatureLen)
1812*7f2fe78bSCy Schubert {
1813*7f2fe78bSCy Schubert struct session_state *state;
1814*7f2fe78bSCy Schubert struct st_object *o;
1815*7f2fe78bSCy Schubert void *buffer = NULL;
1816*7f2fe78bSCy Schubert CK_RV ret;
1817*7f2fe78bSCy Schubert int padding;
1818*7f2fe78bSCy Schubert size_t buffer_len = 0;
1819*7f2fe78bSCy Schubert EVP_PKEY_CTX *ctx = NULL;
1820*7f2fe78bSCy Schubert
1821*7f2fe78bSCy Schubert st_logf("Sign\n");
1822*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1823*7f2fe78bSCy Schubert
1824*7f2fe78bSCy Schubert if (state->sign_object == -1)
1825*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1826*7f2fe78bSCy Schubert
1827*7f2fe78bSCy Schubert o = soft_token.object.objs[state->sign_object];
1828*7f2fe78bSCy Schubert
1829*7f2fe78bSCy Schubert if (o->u.private_key.key == NULL) {
1830*7f2fe78bSCy Schubert st_logf("private key NULL\n");
1831*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1832*7f2fe78bSCy Schubert }
1833*7f2fe78bSCy Schubert
1834*7f2fe78bSCy Schubert if (pulSignatureLen == NULL) {
1835*7f2fe78bSCy Schubert st_logf("signature len NULL\n");
1836*7f2fe78bSCy Schubert ret = CKR_ARGUMENTS_BAD;
1837*7f2fe78bSCy Schubert goto out;
1838*7f2fe78bSCy Schubert }
1839*7f2fe78bSCy Schubert
1840*7f2fe78bSCy Schubert if (pData == NULL_PTR) {
1841*7f2fe78bSCy Schubert st_logf("data NULL\n");
1842*7f2fe78bSCy Schubert ret = CKR_ARGUMENTS_BAD;
1843*7f2fe78bSCy Schubert goto out;
1844*7f2fe78bSCy Schubert }
1845*7f2fe78bSCy Schubert
1846*7f2fe78bSCy Schubert switch(state->sign_mechanism->mechanism) {
1847*7f2fe78bSCy Schubert case CKM_RSA_PKCS:
1848*7f2fe78bSCy Schubert padding = RSA_PKCS1_PADDING;
1849*7f2fe78bSCy Schubert break;
1850*7f2fe78bSCy Schubert case CKM_RSA_X_509:
1851*7f2fe78bSCy Schubert padding = RSA_NO_PADDING;
1852*7f2fe78bSCy Schubert break;
1853*7f2fe78bSCy Schubert default:
1854*7f2fe78bSCy Schubert ret = CKR_FUNCTION_NOT_SUPPORTED;
1855*7f2fe78bSCy Schubert goto out;
1856*7f2fe78bSCy Schubert }
1857*7f2fe78bSCy Schubert
1858*7f2fe78bSCy Schubert ctx = EVP_PKEY_CTX_new(o->u.private_key.key, NULL);
1859*7f2fe78bSCy Schubert if (ctx == NULL || EVP_PKEY_sign_init(ctx) <= 0 ||
1860*7f2fe78bSCy Schubert EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
1861*7f2fe78bSCy Schubert EVP_PKEY_sign(ctx, NULL, &buffer_len, pData, ulDataLen) <= 0) {
1862*7f2fe78bSCy Schubert ret = CKR_DEVICE_ERROR;
1863*7f2fe78bSCy Schubert goto out;
1864*7f2fe78bSCy Schubert }
1865*7f2fe78bSCy Schubert
1866*7f2fe78bSCy Schubert buffer = OPENSSL_malloc(buffer_len);
1867*7f2fe78bSCy Schubert if (buffer == NULL) {
1868*7f2fe78bSCy Schubert ret = CKR_DEVICE_MEMORY;
1869*7f2fe78bSCy Schubert goto out;
1870*7f2fe78bSCy Schubert }
1871*7f2fe78bSCy Schubert
1872*7f2fe78bSCy Schubert if (EVP_PKEY_sign(ctx, buffer, &buffer_len, pData, ulDataLen) <= 0) {
1873*7f2fe78bSCy Schubert ret = CKR_DEVICE_ERROR;
1874*7f2fe78bSCy Schubert goto out;
1875*7f2fe78bSCy Schubert }
1876*7f2fe78bSCy Schubert st_logf("Sign done\n");
1877*7f2fe78bSCy Schubert
1878*7f2fe78bSCy Schubert if (pSignature != NULL)
1879*7f2fe78bSCy Schubert memcpy(pSignature, buffer, buffer_len);
1880*7f2fe78bSCy Schubert *pulSignatureLen = buffer_len;
1881*7f2fe78bSCy Schubert
1882*7f2fe78bSCy Schubert ret = CKR_OK;
1883*7f2fe78bSCy Schubert out:
1884*7f2fe78bSCy Schubert OPENSSL_cleanse(buffer, buffer_len);
1885*7f2fe78bSCy Schubert OPENSSL_free(buffer);
1886*7f2fe78bSCy Schubert EVP_PKEY_CTX_free(ctx);
1887*7f2fe78bSCy Schubert return ret;
1888*7f2fe78bSCy Schubert }
1889*7f2fe78bSCy Schubert
1890*7f2fe78bSCy Schubert CK_RV
C_SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)1891*7f2fe78bSCy Schubert C_SignUpdate(CK_SESSION_HANDLE hSession,
1892*7f2fe78bSCy Schubert CK_BYTE_PTR pPart,
1893*7f2fe78bSCy Schubert CK_ULONG ulPartLen)
1894*7f2fe78bSCy Schubert {
1895*7f2fe78bSCy Schubert st_logf("SignUpdate\n");
1896*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1897*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1898*7f2fe78bSCy Schubert }
1899*7f2fe78bSCy Schubert
1900*7f2fe78bSCy Schubert
1901*7f2fe78bSCy Schubert CK_RV
C_SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)1902*7f2fe78bSCy Schubert C_SignFinal(CK_SESSION_HANDLE hSession,
1903*7f2fe78bSCy Schubert CK_BYTE_PTR pSignature,
1904*7f2fe78bSCy Schubert CK_ULONG_PTR pulSignatureLen)
1905*7f2fe78bSCy Schubert {
1906*7f2fe78bSCy Schubert st_logf("SignUpdate\n");
1907*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
1908*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
1909*7f2fe78bSCy Schubert }
1910*7f2fe78bSCy Schubert
1911*7f2fe78bSCy Schubert CK_RV
C_VerifyInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)1912*7f2fe78bSCy Schubert C_VerifyInit(CK_SESSION_HANDLE hSession,
1913*7f2fe78bSCy Schubert CK_MECHANISM_PTR pMechanism,
1914*7f2fe78bSCy Schubert CK_OBJECT_HANDLE hKey)
1915*7f2fe78bSCy Schubert {
1916*7f2fe78bSCy Schubert struct session_state *state;
1917*7f2fe78bSCy Schubert CK_MECHANISM_TYPE mechs[] = { CKM_RSA_PKCS, CKM_RSA_X_509 };
1918*7f2fe78bSCy Schubert CK_BBOOL bool_true = CK_TRUE;
1919*7f2fe78bSCy Schubert CK_ATTRIBUTE attr[] = {
1920*7f2fe78bSCy Schubert { CKA_VERIFY, &bool_true, sizeof(bool_true) }
1921*7f2fe78bSCy Schubert };
1922*7f2fe78bSCy Schubert struct st_object *o;
1923*7f2fe78bSCy Schubert CK_RV ret;
1924*7f2fe78bSCy Schubert
1925*7f2fe78bSCy Schubert st_logf("VerifyInit\n");
1926*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1927*7f2fe78bSCy Schubert
1928*7f2fe78bSCy Schubert ret = commonInit(attr, sizeof(attr)/sizeof(attr[0]),
1929*7f2fe78bSCy Schubert mechs, sizeof(mechs)/sizeof(mechs[0]),
1930*7f2fe78bSCy Schubert pMechanism, hKey, &o);
1931*7f2fe78bSCy Schubert if (ret)
1932*7f2fe78bSCy Schubert return ret;
1933*7f2fe78bSCy Schubert
1934*7f2fe78bSCy Schubert ret = dup_mechanism(&state->verify_mechanism, pMechanism);
1935*7f2fe78bSCy Schubert if (ret == CKR_OK)
1936*7f2fe78bSCy Schubert state->verify_object = OBJECT_ID(o);
1937*7f2fe78bSCy Schubert
1938*7f2fe78bSCy Schubert return ret;
1939*7f2fe78bSCy Schubert }
1940*7f2fe78bSCy Schubert
1941*7f2fe78bSCy Schubert CK_RV
C_Verify(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)1942*7f2fe78bSCy Schubert C_Verify(CK_SESSION_HANDLE hSession,
1943*7f2fe78bSCy Schubert CK_BYTE_PTR pData,
1944*7f2fe78bSCy Schubert CK_ULONG ulDataLen,
1945*7f2fe78bSCy Schubert CK_BYTE_PTR pSignature,
1946*7f2fe78bSCy Schubert CK_ULONG ulSignatureLen)
1947*7f2fe78bSCy Schubert {
1948*7f2fe78bSCy Schubert struct session_state *state;
1949*7f2fe78bSCy Schubert struct st_object *o;
1950*7f2fe78bSCy Schubert CK_RV ret;
1951*7f2fe78bSCy Schubert int padding;
1952*7f2fe78bSCy Schubert EVP_PKEY_CTX *ctx = NULL;
1953*7f2fe78bSCy Schubert
1954*7f2fe78bSCy Schubert st_logf("Verify\n");
1955*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, &state);
1956*7f2fe78bSCy Schubert
1957*7f2fe78bSCy Schubert if (state->verify_object == -1)
1958*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1959*7f2fe78bSCy Schubert
1960*7f2fe78bSCy Schubert o = soft_token.object.objs[state->verify_object];
1961*7f2fe78bSCy Schubert
1962*7f2fe78bSCy Schubert if (o->u.public_key == NULL) {
1963*7f2fe78bSCy Schubert st_logf("public key NULL\n");
1964*7f2fe78bSCy Schubert return CKR_ARGUMENTS_BAD;
1965*7f2fe78bSCy Schubert }
1966*7f2fe78bSCy Schubert
1967*7f2fe78bSCy Schubert if (pSignature == NULL) {
1968*7f2fe78bSCy Schubert st_logf("signature NULL\n");
1969*7f2fe78bSCy Schubert ret = CKR_ARGUMENTS_BAD;
1970*7f2fe78bSCy Schubert goto out;
1971*7f2fe78bSCy Schubert }
1972*7f2fe78bSCy Schubert
1973*7f2fe78bSCy Schubert if (pData == NULL_PTR) {
1974*7f2fe78bSCy Schubert st_logf("data NULL\n");
1975*7f2fe78bSCy Schubert ret = CKR_ARGUMENTS_BAD;
1976*7f2fe78bSCy Schubert goto out;
1977*7f2fe78bSCy Schubert }
1978*7f2fe78bSCy Schubert
1979*7f2fe78bSCy Schubert switch(state->verify_mechanism->mechanism) {
1980*7f2fe78bSCy Schubert case CKM_RSA_PKCS:
1981*7f2fe78bSCy Schubert padding = RSA_PKCS1_PADDING;
1982*7f2fe78bSCy Schubert break;
1983*7f2fe78bSCy Schubert case CKM_RSA_X_509:
1984*7f2fe78bSCy Schubert padding = RSA_NO_PADDING;
1985*7f2fe78bSCy Schubert break;
1986*7f2fe78bSCy Schubert default:
1987*7f2fe78bSCy Schubert ret = CKR_FUNCTION_NOT_SUPPORTED;
1988*7f2fe78bSCy Schubert goto out;
1989*7f2fe78bSCy Schubert }
1990*7f2fe78bSCy Schubert
1991*7f2fe78bSCy Schubert ctx = EVP_PKEY_CTX_new(o->u.public_key, NULL);
1992*7f2fe78bSCy Schubert if (ctx == NULL || EVP_PKEY_verify_init(ctx) <= 0 ||
1993*7f2fe78bSCy Schubert EVP_PKEY_CTX_set_rsa_padding(ctx, padding) <= 0 ||
1994*7f2fe78bSCy Schubert EVP_PKEY_verify(ctx, pSignature, ulSignatureLen, pData,
1995*7f2fe78bSCy Schubert ulDataLen) <= 0) {
1996*7f2fe78bSCy Schubert ret = CKR_DEVICE_ERROR;
1997*7f2fe78bSCy Schubert goto out;
1998*7f2fe78bSCy Schubert }
1999*7f2fe78bSCy Schubert st_logf("Verify done\n");
2000*7f2fe78bSCy Schubert
2001*7f2fe78bSCy Schubert ret = CKR_OK;
2002*7f2fe78bSCy Schubert out:
2003*7f2fe78bSCy Schubert EVP_PKEY_CTX_free(ctx);
2004*7f2fe78bSCy Schubert return ret;
2005*7f2fe78bSCy Schubert }
2006*7f2fe78bSCy Schubert
2007*7f2fe78bSCy Schubert CK_RV
C_VerifyUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)2008*7f2fe78bSCy Schubert C_VerifyUpdate(CK_SESSION_HANDLE hSession,
2009*7f2fe78bSCy Schubert CK_BYTE_PTR pPart,
2010*7f2fe78bSCy Schubert CK_ULONG ulPartLen)
2011*7f2fe78bSCy Schubert {
2012*7f2fe78bSCy Schubert st_logf("VerifyUpdate\n");
2013*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
2014*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
2015*7f2fe78bSCy Schubert }
2016*7f2fe78bSCy Schubert
2017*7f2fe78bSCy Schubert CK_RV
C_VerifyFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)2018*7f2fe78bSCy Schubert C_VerifyFinal(CK_SESSION_HANDLE hSession,
2019*7f2fe78bSCy Schubert CK_BYTE_PTR pSignature,
2020*7f2fe78bSCy Schubert CK_ULONG ulSignatureLen)
2021*7f2fe78bSCy Schubert {
2022*7f2fe78bSCy Schubert st_logf("VerifyFinal\n");
2023*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
2024*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
2025*7f2fe78bSCy Schubert }
2026*7f2fe78bSCy Schubert
2027*7f2fe78bSCy Schubert CK_RV
C_GenerateRandom(CK_SESSION_HANDLE hSession,CK_BYTE_PTR RandomData,CK_ULONG ulRandomLen)2028*7f2fe78bSCy Schubert C_GenerateRandom(CK_SESSION_HANDLE hSession,
2029*7f2fe78bSCy Schubert CK_BYTE_PTR RandomData,
2030*7f2fe78bSCy Schubert CK_ULONG ulRandomLen)
2031*7f2fe78bSCy Schubert {
2032*7f2fe78bSCy Schubert st_logf("GenerateRandom\n");
2033*7f2fe78bSCy Schubert VERIFY_SESSION_HANDLE(hSession, NULL);
2034*7f2fe78bSCy Schubert return CKR_FUNCTION_NOT_SUPPORTED;
2035*7f2fe78bSCy Schubert }
2036*7f2fe78bSCy Schubert
2037*7f2fe78bSCy Schubert CK_FUNCTION_LIST funcs = {
2038*7f2fe78bSCy Schubert { 2, 11 },
2039*7f2fe78bSCy Schubert C_Initialize,
2040*7f2fe78bSCy Schubert C_Finalize,
2041*7f2fe78bSCy Schubert C_GetInfo,
2042*7f2fe78bSCy Schubert C_GetFunctionList,
2043*7f2fe78bSCy Schubert C_GetSlotList,
2044*7f2fe78bSCy Schubert C_GetSlotInfo,
2045*7f2fe78bSCy Schubert C_GetTokenInfo,
2046*7f2fe78bSCy Schubert C_GetMechanismList,
2047*7f2fe78bSCy Schubert C_GetMechanismInfo,
2048*7f2fe78bSCy Schubert C_InitToken,
2049*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_InitPIN */
2050*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_SetPIN */
2051*7f2fe78bSCy Schubert C_OpenSession,
2052*7f2fe78bSCy Schubert C_CloseSession,
2053*7f2fe78bSCy Schubert C_CloseAllSessions,
2054*7f2fe78bSCy Schubert C_GetSessionInfo,
2055*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_GetOperationState */
2056*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_SetOperationState */
2057*7f2fe78bSCy Schubert C_Login,
2058*7f2fe78bSCy Schubert C_Logout,
2059*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_CreateObject */
2060*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_CopyObject */
2061*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_DestroyObject */
2062*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_GetObjectSize */
2063*7f2fe78bSCy Schubert C_GetAttributeValue,
2064*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_SetAttributeValue */
2065*7f2fe78bSCy Schubert C_FindObjectsInit,
2066*7f2fe78bSCy Schubert C_FindObjects,
2067*7f2fe78bSCy Schubert C_FindObjectsFinal,
2068*7f2fe78bSCy Schubert C_EncryptInit,
2069*7f2fe78bSCy Schubert C_Encrypt,
2070*7f2fe78bSCy Schubert C_EncryptUpdate,
2071*7f2fe78bSCy Schubert C_EncryptFinal,
2072*7f2fe78bSCy Schubert C_DecryptInit,
2073*7f2fe78bSCy Schubert C_Decrypt,
2074*7f2fe78bSCy Schubert C_DecryptUpdate,
2075*7f2fe78bSCy Schubert C_DecryptFinal,
2076*7f2fe78bSCy Schubert C_DigestInit,
2077*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_Digest */
2078*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_DigestUpdate */
2079*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_DigestKey */
2080*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_DigestFinal */
2081*7f2fe78bSCy Schubert C_SignInit,
2082*7f2fe78bSCy Schubert C_Sign,
2083*7f2fe78bSCy Schubert C_SignUpdate,
2084*7f2fe78bSCy Schubert C_SignFinal,
2085*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_SignRecoverInit */
2086*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_SignRecover */
2087*7f2fe78bSCy Schubert C_VerifyInit,
2088*7f2fe78bSCy Schubert C_Verify,
2089*7f2fe78bSCy Schubert C_VerifyUpdate,
2090*7f2fe78bSCy Schubert C_VerifyFinal,
2091*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_VerifyRecoverInit */
2092*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_VerifyRecover */
2093*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_DigestEncryptUpdate */
2094*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_DecryptDigestUpdate */
2095*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_SignEncryptUpdate */
2096*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_DecryptVerifyUpdate */
2097*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_GenerateKey */
2098*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_GenerateKeyPair */
2099*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_WrapKey */
2100*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_UnwrapKey */
2101*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_DeriveKey */
2102*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_SeedRandom */
2103*7f2fe78bSCy Schubert C_GenerateRandom,
2104*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_GetFunctionStatus */
2105*7f2fe78bSCy Schubert (void *)func_not_supported, /* C_CancelFunction */
2106*7f2fe78bSCy Schubert (void *)func_not_supported /* C_WaitForSlotEvent */
2107*7f2fe78bSCy Schubert };
2108