xref: /freebsd/crypto/krb5/src/tests/softpkcs11/main.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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