2 * Copyright (c) 2004 - 2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #define CRYPTOKI_EXPORTS 1
39 #define OBJECT_ID_MASK 0xfff
40 #define HANDLE_OBJECT_ID(h) ((h) & OBJECT_ID_MASK)
41 #define OBJECT_ID(obj) HANDLE_OBJECT_ID((obj)->object_handle)
44 #define random() rand()
45 #define srandom(s) srand(s)
53 CK_ATTRIBUTE attribute
;
58 CK_OBJECT_HANDLE object_handle
;
59 struct st_attr
*attrs
;
64 static struct soft_token
{
65 CK_VOID_PTR application
;
70 struct st_object
**objs
;
79 struct session_state
{
80 CK_SESSION_HANDLE session_handle
;
83 CK_ATTRIBUTE
*attributes
;
84 CK_ULONG num_attributes
;
89 CK_MECHANISM_PTR sign_mechanism
;
91 CK_MECHANISM_PTR verify_mechanism
;
93 #define MAX_NUM_SESSION (sizeof(soft_token.state)/sizeof(soft_token.state[0]))
97 static hx509_context context
;
100 application_error(const char *fmt
, ...)
106 if (soft_token
.flags
.app_error_fatal
)
111 st_logf(const char *fmt
, ...)
114 if (soft_token
.logfile
== NULL
)
117 vfprintf(soft_token
.logfile
, fmt
, ap
);
119 fflush(soft_token
.logfile
);
125 if (context
== NULL
) {
126 int ret
= hx509_context_init(&context
);
128 return CKR_GENERAL_ERROR
;
133 #define INIT_CONTEXT() { CK_RV icret = init_context(); if (icret) return icret; }
136 snprintf_fill(char *str
, size_t size
, char fillchar
, const char *fmt
, ...)
141 len
= vsnprintf(str
, size
, fmt
, ap
);
143 if (len
< 0 || (size_t)len
> size
)
145 while ((size_t)len
< size
)
146 str
[len
++] = fillchar
;
150 #define printf error_use_st_logf
153 #define VERIFY_SESSION_HANDLE(s, state) \
156 xret = verify_session_handle(s, state); \
157 if (xret != CKR_OK) { \
158 /* return CKR_OK */; \
163 verify_session_handle(CK_SESSION_HANDLE hSession
,
164 struct session_state
**state
)
168 for (i
= 0; i
< MAX_NUM_SESSION
; i
++){
169 if (soft_token
.state
[i
].session_handle
== hSession
)
172 if (i
== MAX_NUM_SESSION
) {
173 application_error("use of invalid handle: 0x%08lx\n",
174 (unsigned long)hSession
);
175 return CKR_SESSION_HANDLE_INVALID
;
178 *state
= &soft_token
.state
[i
];
183 object_handle_to_object(CK_OBJECT_HANDLE handle
,
184 struct st_object
**object
)
186 int i
= HANDLE_OBJECT_ID(handle
);
189 if (i
>= soft_token
.object
.num_objs
)
190 return CKR_ARGUMENTS_BAD
;
191 if (soft_token
.object
.objs
[i
] == NULL
)
192 return CKR_ARGUMENTS_BAD
;
193 if (soft_token
.object
.objs
[i
]->object_handle
!= handle
)
194 return CKR_ARGUMENTS_BAD
;
195 *object
= soft_token
.object
.objs
[i
];
200 attributes_match(const struct st_object
*obj
,
201 const CK_ATTRIBUTE
*attributes
,
202 CK_ULONG num_attributes
)
207 st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj
));
209 for (i
= 0; i
< num_attributes
; i
++) {
211 for (j
= 0; j
< obj
->num_attributes
; j
++) {
212 if (attributes
[i
].type
== obj
->attrs
[j
].attribute
.type
&&
213 attributes
[i
].ulValueLen
== obj
->attrs
[j
].attribute
.ulValueLen
&&
214 memcmp(attributes
[i
].pValue
, obj
->attrs
[j
].attribute
.pValue
,
215 attributes
[i
].ulValueLen
) == 0) {
221 st_logf("type %d attribute have no match\n", attributes
[i
].type
);
225 st_logf("attribute matches\n");
230 print_attributes(const CK_ATTRIBUTE
*attributes
,
231 CK_ULONG num_attributes
)
235 st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes
);
237 for (i
= 0; i
< num_attributes
; i
++) {
239 switch (attributes
[i
].type
) {
242 if (attributes
[i
].ulValueLen
!= sizeof(CK_BBOOL
)) {
243 application_error("token attribute wrong length\n");
246 ck_true
= attributes
[i
].pValue
;
247 st_logf("token: %s", *ck_true
? "TRUE" : "FALSE");
251 CK_OBJECT_CLASS
*class;
252 if (attributes
[i
].ulValueLen
!= sizeof(CK_ULONG
)) {
253 application_error("class attribute wrong length\n");
256 class = attributes
[i
].pValue
;
259 case CKO_CERTIFICATE
:
260 st_logf("certificate");
263 st_logf("public key");
265 case CKO_PRIVATE_KEY
:
266 st_logf("private key");
269 st_logf("secret key");
271 case CKO_DOMAIN_PARAMETERS
:
272 st_logf("domain parameters");
275 st_logf("[class %lx]", (long unsigned)*class);
286 case CKA_APPLICATION
:
287 st_logf("application");
296 st_logf("[unknown 0x%08lx]", (unsigned long)attributes
[i
].type
);
303 static struct st_object
*
306 struct st_object
*o
, **objs
;
309 o
= calloc(1, sizeof(*o
));
313 for (i
= 0; i
< soft_token
.object
.num_objs
; i
++) {
314 if (soft_token
.object
.objs
== NULL
) {
315 soft_token
.object
.objs
[i
] = o
;
319 if (i
== soft_token
.object
.num_objs
) {
320 objs
= realloc(soft_token
.object
.objs
,
321 (soft_token
.object
.num_objs
+ 1) * sizeof(soft_token
.object
.objs
[0]));
326 soft_token
.object
.objs
= objs
;
327 soft_token
.object
.objs
[soft_token
.object
.num_objs
++] = o
;
329 soft_token
.object
.objs
[i
]->object_handle
=
330 (random() & (~OBJECT_ID_MASK
)) | i
;
336 add_object_attribute(struct st_object
*o
,
338 CK_ATTRIBUTE_TYPE type
,
345 i
= o
->num_attributes
;
346 a
= realloc(o
->attrs
, (i
+ 1) * sizeof(o
->attrs
[0]));
348 return CKR_DEVICE_MEMORY
;
350 o
->attrs
[i
].secret
= secret
;
351 o
->attrs
[i
].attribute
.type
= type
;
352 o
->attrs
[i
].attribute
.pValue
= malloc(ulValueLen
);
353 if (o
->attrs
[i
].attribute
.pValue
== NULL
&& ulValueLen
!= 0)
354 return CKR_DEVICE_MEMORY
;
355 memcpy(o
->attrs
[i
].attribute
.pValue
, pValue
, ulValueLen
);
356 o
->attrs
[i
].attribute
.ulValueLen
= ulValueLen
;
363 add_pubkey_info(hx509_context hxctx
, struct st_object
*o
,
364 CK_KEY_TYPE key_type
, hx509_cert cert
)
367 CK_BYTE
*modulus
= NULL
;
368 size_t modulus_len
= 0;
369 CK_ULONG modulus_bits
= 0;
370 CK_BYTE
*exponent
= NULL
;
371 size_t exponent_len
= 0;
373 if (key_type
!= CKK_RSA
)
375 if (_hx509_cert_private_key(cert
) == NULL
)
378 num
= _hx509_private_key_get_internal(context
,
379 _hx509_cert_private_key(cert
),
382 return CKR_GENERAL_ERROR
;
383 modulus_bits
= BN_num_bits(num
);
385 modulus_len
= BN_num_bytes(num
);
386 modulus
= malloc(modulus_len
);
387 BN_bn2bin(num
, modulus
);
390 add_object_attribute(o
, 0, CKA_MODULUS
, modulus
, modulus_len
);
391 add_object_attribute(o
, 0, CKA_MODULUS_BITS
,
392 &modulus_bits
, sizeof(modulus_bits
));
396 num
= _hx509_private_key_get_internal(context
,
397 _hx509_cert_private_key(cert
),
400 return CKR_GENERAL_ERROR
;
402 exponent_len
= BN_num_bytes(num
);
403 exponent
= malloc(exponent_len
);
404 BN_bn2bin(num
, exponent
);
407 add_object_attribute(o
, 0, CKA_PUBLIC_EXPONENT
,
408 exponent
, exponent_len
);
422 add_cert(hx509_context hxctx
, void *ctx
, hx509_cert cert
)
424 static char empty
[] = "";
425 struct foo
*foo
= (struct foo
*)ctx
;
426 struct st_object
*o
= NULL
;
427 CK_OBJECT_CLASS type
;
428 CK_BBOOL bool_true
= CK_TRUE
;
429 CK_BBOOL bool_false
= CK_FALSE
;
430 CK_CERTIFICATE_TYPE cert_type
= CKC_X_509
;
431 CK_KEY_TYPE key_type
;
432 CK_MECHANISM_TYPE mech_type
;
433 CK_RV ret
= CKR_GENERAL_ERROR
;
435 heim_octet_string cert_data
, subject_data
, issuer_data
, serial_data
;
437 st_logf("adding certificate\n");
439 serial_data
.data
= NULL
;
440 serial_data
.length
= 0;
441 cert_data
= subject_data
= issuer_data
= serial_data
;
443 hret
= hx509_cert_binary(hxctx
, cert
, &cert_data
);
450 hret
= hx509_cert_get_issuer(cert
, &name
);
453 hret
= hx509_name_binary(name
, &issuer_data
);
454 hx509_name_free(&name
);
458 hret
= hx509_cert_get_subject(cert
, &name
);
461 hret
= hx509_name_binary(name
, &subject_data
);
462 hx509_name_free(&name
);
468 AlgorithmIdentifier alg
;
470 hret
= hx509_cert_get_SPKI_AlgorithmIdentifier(context
, cert
, &alg
);
472 ret
= CKR_DEVICE_MEMORY
;
476 key_type
= CKK_RSA
; /* XXX */
478 free_AlgorithmIdentifier(&alg
);
482 type
= CKO_CERTIFICATE
;
485 ret
= CKR_DEVICE_MEMORY
;
489 o
->cert
= hx509_cert_ref(cert
);
491 add_object_attribute(o
, 0, CKA_CLASS
, &type
, sizeof(type
));
492 add_object_attribute(o
, 0, CKA_TOKEN
, &bool_true
, sizeof(bool_true
));
493 add_object_attribute(o
, 0, CKA_PRIVATE
, &bool_false
, sizeof(bool_false
));
494 add_object_attribute(o
, 0, CKA_MODIFIABLE
, &bool_false
, sizeof(bool_false
));
495 add_object_attribute(o
, 0, CKA_LABEL
, foo
->label
, strlen(foo
->label
));
497 add_object_attribute(o
, 0, CKA_CERTIFICATE_TYPE
, &cert_type
, sizeof(cert_type
));
498 add_object_attribute(o
, 0, CKA_ID
, foo
->id
, strlen(foo
->id
));
500 add_object_attribute(o
, 0, CKA_SUBJECT
, subject_data
.data
, subject_data
.length
);
501 add_object_attribute(o
, 0, CKA_ISSUER
, issuer_data
.data
, issuer_data
.length
);
502 add_object_attribute(o
, 0, CKA_SERIAL_NUMBER
, serial_data
.data
, serial_data
.length
);
503 add_object_attribute(o
, 0, CKA_VALUE
, cert_data
.data
, cert_data
.length
);
504 add_object_attribute(o
, 0, CKA_TRUSTED
, &bool_false
, sizeof(bool_false
));
506 st_logf("add cert ok: %lx\n", (unsigned long)OBJECT_ID(o
));
508 type
= CKO_PUBLIC_KEY
;
511 ret
= CKR_DEVICE_MEMORY
;
514 o
->cert
= hx509_cert_ref(cert
);
516 add_object_attribute(o
, 0, CKA_CLASS
, &type
, sizeof(type
));
517 add_object_attribute(o
, 0, CKA_TOKEN
, &bool_true
, sizeof(bool_true
));
518 add_object_attribute(o
, 0, CKA_PRIVATE
, &bool_false
, sizeof(bool_false
));
519 add_object_attribute(o
, 0, CKA_MODIFIABLE
, &bool_false
, sizeof(bool_false
));
520 add_object_attribute(o
, 0, CKA_LABEL
, foo
->label
, strlen(foo
->label
));
522 add_object_attribute(o
, 0, CKA_KEY_TYPE
, &key_type
, sizeof(key_type
));
523 add_object_attribute(o
, 0, CKA_ID
, foo
->id
, strlen(foo
->id
));
524 add_object_attribute(o
, 0, CKA_START_DATE
, empty
, 1); /* XXX */
525 add_object_attribute(o
, 0, CKA_END_DATE
, empty
, 1); /* XXX */
526 add_object_attribute(o
, 0, CKA_DERIVE
, &bool_false
, sizeof(bool_false
));
527 add_object_attribute(o
, 0, CKA_LOCAL
, &bool_false
, sizeof(bool_false
));
528 mech_type
= CKM_RSA_X_509
;
529 add_object_attribute(o
, 0, CKA_KEY_GEN_MECHANISM
, &mech_type
, sizeof(mech_type
));
531 add_object_attribute(o
, 0, CKA_SUBJECT
, subject_data
.data
, subject_data
.length
);
532 add_object_attribute(o
, 0, CKA_ENCRYPT
, &bool_true
, sizeof(bool_true
));
533 add_object_attribute(o
, 0, CKA_VERIFY
, &bool_true
, sizeof(bool_true
));
534 add_object_attribute(o
, 0, CKA_VERIFY_RECOVER
, &bool_false
, sizeof(bool_false
));
535 add_object_attribute(o
, 0, CKA_WRAP
, &bool_true
, sizeof(bool_true
));
536 add_object_attribute(o
, 0, CKA_TRUSTED
, &bool_true
, sizeof(bool_true
));
538 add_pubkey_info(hxctx
, o
, key_type
, cert
);
540 st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o
));
542 if (hx509_cert_have_private_key(cert
)) {
545 type
= CKO_PRIVATE_KEY
;
548 ret
= CKR_DEVICE_MEMORY
;
551 o
->cert
= hx509_cert_ref(cert
);
553 add_object_attribute(o
, 0, CKA_CLASS
, &type
, sizeof(type
));
554 add_object_attribute(o
, 0, CKA_TOKEN
, &bool_true
, sizeof(bool_true
));
555 add_object_attribute(o
, 0, CKA_PRIVATE
, &bool_true
, sizeof(bool_false
));
556 add_object_attribute(o
, 0, CKA_MODIFIABLE
, &bool_false
, sizeof(bool_false
));
557 add_object_attribute(o
, 0, CKA_LABEL
, foo
->label
, strlen(foo
->label
));
559 add_object_attribute(o
, 0, CKA_KEY_TYPE
, &key_type
, sizeof(key_type
));
560 add_object_attribute(o
, 0, CKA_ID
, foo
->id
, strlen(foo
->id
));
561 add_object_attribute(o
, 0, CKA_START_DATE
, empty
, 1); /* XXX */
562 add_object_attribute(o
, 0, CKA_END_DATE
, empty
, 1); /* XXX */
563 add_object_attribute(o
, 0, CKA_DERIVE
, &bool_false
, sizeof(bool_false
));
564 add_object_attribute(o
, 0, CKA_LOCAL
, &bool_false
, sizeof(bool_false
));
565 mech_type
= CKM_RSA_X_509
;
566 add_object_attribute(o
, 0, CKA_KEY_GEN_MECHANISM
, &mech_type
, sizeof(mech_type
));
568 add_object_attribute(o
, 0, CKA_SUBJECT
, subject_data
.data
, subject_data
.length
);
569 add_object_attribute(o
, 0, CKA_SENSITIVE
, &bool_true
, sizeof(bool_true
));
570 add_object_attribute(o
, 0, CKA_SECONDARY_AUTH
, &bool_false
, sizeof(bool_true
));
572 add_object_attribute(o
, 0, CKA_AUTH_PIN_FLAGS
, &flags
, sizeof(flags
));
574 add_object_attribute(o
, 0, CKA_DECRYPT
, &bool_true
, sizeof(bool_true
));
575 add_object_attribute(o
, 0, CKA_SIGN
, &bool_true
, sizeof(bool_true
));
576 add_object_attribute(o
, 0, CKA_SIGN_RECOVER
, &bool_false
, sizeof(bool_false
));
577 add_object_attribute(o
, 0, CKA_UNWRAP
, &bool_true
, sizeof(bool_true
));
578 add_object_attribute(o
, 0, CKA_EXTRACTABLE
, &bool_true
, sizeof(bool_true
));
579 add_object_attribute(o
, 0, CKA_NEVER_EXTRACTABLE
, &bool_false
, sizeof(bool_false
));
581 add_pubkey_info(hxctx
, o
, key_type
, cert
);
587 st_logf("something went wrong when adding cert!\n");
591 hx509_xfree(cert_data
.data
);
592 hx509_xfree(serial_data
.data
);
593 hx509_xfree(issuer_data
.data
);
594 hx509_xfree(subject_data
.data
);
600 add_certificate(const char *cert_file
,
606 hx509_lock lock
= NULL
;
614 flags
|= HX509_CERTS_UNPROTECT_ALL
;
618 ret
= asprintf(&str
, "PASS:%s", pin
);
619 if (ret
== -1 || !str
) {
620 st_logf("failed to allocate memory\n");
621 return CKR_GENERAL_ERROR
;
624 hx509_lock_init(context
, &lock
);
625 hx509_lock_command_string(lock
, str
);
627 memset(str
, 0, strlen(str
));
631 ret
= hx509_certs_init(context
, cert_file
, flags
, lock
, &certs
);
633 st_logf("failed to open file %s\n", cert_file
);
634 return CKR_GENERAL_ERROR
;
637 ret
= hx509_certs_iter_f(context
, certs
, add_cert
, &foo
);
638 hx509_certs_free(&certs
);
640 st_logf("failed adding certs from file %s\n", cert_file
);
641 return CKR_GENERAL_ERROR
;
648 find_object_final(struct session_state
*state
)
650 if (state
->find
.attributes
) {
653 for (i
= 0; i
< state
->find
.num_attributes
; i
++) {
654 if (state
->find
.attributes
[i
].pValue
)
655 free(state
->find
.attributes
[i
].pValue
);
657 free(state
->find
.attributes
);
658 state
->find
.attributes
= NULL
;
659 state
->find
.num_attributes
= 0;
660 state
->find
.next_object
= -1;
665 reset_crypto_state(struct session_state
*state
)
667 state
->sign_object
= -1;
668 if (state
->sign_mechanism
)
669 free(state
->sign_mechanism
);
670 state
->sign_mechanism
= NULL_PTR
;
671 state
->verify_object
= -1;
672 if (state
->verify_mechanism
)
673 free(state
->verify_mechanism
);
674 state
->verify_mechanism
= NULL_PTR
;
678 close_session(struct session_state
*state
)
680 if (state
->find
.attributes
) {
681 application_error("application didn't do C_FindObjectsFinal\n");
682 find_object_final(state
);
685 state
->session_handle
= CK_INVALID_HANDLE
;
686 soft_token
.application
= NULL_PTR
;
687 soft_token
.notify
= NULL_PTR
;
688 reset_crypto_state(state
);
694 return soft_token
.open_sessions
> 0 ? "yes" : "no";
698 read_conf_file(const char *fn
, CK_USER_TYPE userType
, const char *pin
)
700 char buf
[1024], *type
, *s
, *p
;
703 CK_RV failed
= CKR_OK
;
706 st_logf("Can't open configuration file. No file specified\n");
707 return CKR_GENERAL_ERROR
;
712 st_logf("can't open configuration file %s\n", fn
);
713 return CKR_GENERAL_ERROR
;
717 while(fgets(buf
, sizeof(buf
), f
) != NULL
) {
718 buf
[strcspn(buf
, "\n")] = '\0';
720 st_logf("line: %s\n", buf
);
723 while (isspace((unsigned char)*p
))
727 while (isspace((unsigned char)*p
))
731 type
= strtok_r(p
, "\t", &s
);
735 if (strcasecmp("certificate", type
) == 0) {
736 char *cert
, *id
, *label
;
738 id
= strtok_r(NULL
, "\t", &s
);
743 st_logf("id: %s\n", id
);
744 label
= strtok_r(NULL
, "\t", &s
);
746 st_logf("no label\n");
749 cert
= strtok_r(NULL
, "\t", &s
);
751 st_logf("no certfiicate store\n");
755 st_logf("adding: %s: %s in file %s\n", id
, label
, cert
);
757 ret
= add_certificate(cert
, pin
, id
, label
);
760 } else if (strcasecmp("debug", type
) == 0) {
763 name
= strtok_r(NULL
, "\t", &s
);
765 st_logf("no filename\n");
769 if (soft_token
.logfile
)
770 fclose(soft_token
.logfile
);
772 if (strcasecmp(name
, "stdout") == 0)
773 soft_token
.logfile
= stdout
;
775 soft_token
.logfile
= fopen(name
, "a");
776 if (soft_token
.logfile
)
777 rk_cloexec_file(soft_token
.logfile
);
779 if (soft_token
.logfile
== NULL
)
780 st_logf("failed to open file: %s\n", name
);
782 } else if (strcasecmp("app-fatal", type
) == 0) {
785 name
= strtok_r(NULL
, "\t", &s
);
787 st_logf("argument to app-fatal\n");
791 if (strcmp(name
, "true") == 0 || strcmp(name
, "on") == 0)
792 soft_token
.flags
.app_error_fatal
= 1;
793 else if (strcmp(name
, "false") == 0 || strcmp(name
, "off") == 0)
794 soft_token
.flags
.app_error_fatal
= 0;
796 st_logf("unknown app-fatal: %s\n", name
);
799 st_logf("unknown type: %s\n", type
);
809 func_not_supported(void)
811 st_logf("function not supported\n");
812 return CKR_FUNCTION_NOT_SUPPORTED
;
816 get_config_file_for_user(void)
825 fn
= getenv("SOFTPKCS11RC");
828 home
= getenv("HOME");
830 if (fn
== NULL
&& home
== NULL
) {
831 struct passwd
*pw
= getpwuid(getuid());
837 ret
= asprintf(&fn
, "%s/.soft-token.rc", home
);
841 fn
= strdup("/etc/soft-token.rc");
845 char appdatafolder
[MAX_PATH
];
847 fn
= getenv("SOFTPKCS11RC");
849 /* Retrieve the roaming AppData folder for the current user. The
850 current user is the user account represented by the current
854 SUCCEEDED(SHGetFolderPath(NULL
, CSIDL_APPDATA
, NULL
, SHGFP_TYPE_CURRENT
, appdatafolder
))) {
856 asprintf(&fn
, "%s\\.soft-token.rc", appdatafolder
);
866 C_Initialize(CK_VOID_PTR a
)
868 CK_C_INITIALIZE_ARGS_PTR args
= a
;
872 st_logf("Initialize\n");
876 OpenSSL_add_all_algorithms();
878 srandom(getpid() ^ (int) time(NULL
));
880 for (i
= 0; i
< MAX_NUM_SESSION
; i
++) {
881 soft_token
.state
[i
].session_handle
= CK_INVALID_HANDLE
;
882 soft_token
.state
[i
].find
.attributes
= NULL
;
883 soft_token
.state
[i
].find
.num_attributes
= 0;
884 soft_token
.state
[i
].find
.next_object
= -1;
885 reset_crypto_state(&soft_token
.state
[i
]);
888 soft_token
.flags
.hardware_slot
= 1;
889 soft_token
.flags
.app_error_fatal
= 0;
890 soft_token
.flags
.login_done
= 0;
892 soft_token
.object
.objs
= NULL
;
893 soft_token
.object
.num_objs
= 0;
895 soft_token
.logfile
= NULL
;
897 soft_token
.logfile
= stdout
;
900 soft_token
.logfile
= fopen("/tmp/log-pkcs11.txt", "a");
904 st_logf("\tCreateMutex:\t%p\n", args
->CreateMutex
);
905 st_logf("\tDestroyMutext\t%p\n", args
->DestroyMutex
);
906 st_logf("\tLockMutext\t%p\n", args
->LockMutex
);
907 st_logf("\tUnlockMutext\t%p\n", args
->UnlockMutex
);
908 st_logf("\tFlags\t%04x\n", (unsigned int)args
->flags
);
911 soft_token
.config_file
= get_config_file_for_user();
914 * This operations doesn't return CKR_OK if any of the
915 * certificates failes to be unparsed (ie password protected).
917 ret
= read_conf_file(soft_token
.config_file
, CKU_USER
, NULL
);
919 soft_token
.flags
.login_done
= 1;
925 C_Finalize(CK_VOID_PTR args
)
931 st_logf("Finalize\n");
933 for (i
= 0; i
< MAX_NUM_SESSION
; i
++) {
934 if (soft_token
.state
[i
].session_handle
!= CK_INVALID_HANDLE
) {
935 application_error("application finalized without "
936 "closing session\n");
937 close_session(&soft_token
.state
[i
]);
945 C_GetInfo(CK_INFO_PTR args
)
949 st_logf("GetInfo\n");
951 memset(args
, 17, sizeof(*args
));
952 args
->cryptokiVersion
.major
= 2;
953 args
->cryptokiVersion
.minor
= 10;
954 snprintf_fill((char *)args
->manufacturerID
,
955 sizeof(args
->manufacturerID
),
957 "Heimdal hx509 SoftToken");
958 snprintf_fill((char *)args
->libraryDescription
,
959 sizeof(args
->libraryDescription
), ' ',
960 "Heimdal hx509 SoftToken");
961 args
->libraryVersion
.major
= 2;
962 args
->libraryVersion
.minor
= 0;
967 extern CK_FUNCTION_LIST funcs
;
970 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList
)
974 *ppFunctionList
= &funcs
;
979 C_GetSlotList(CK_BBOOL tokenPresent
,
980 CK_SLOT_ID_PTR pSlotList
,
981 CK_ULONG_PTR pulCount
)
984 st_logf("GetSlotList: %s\n",
985 tokenPresent
? "tokenPresent" : "token not Present");
993 C_GetSlotInfo(CK_SLOT_ID slotID
,
994 CK_SLOT_INFO_PTR pInfo
)
997 st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID
, has_session());
999 memset(pInfo
, 18, sizeof(*pInfo
));
1002 return CKR_ARGUMENTS_BAD
;
1004 snprintf_fill((char *)pInfo
->slotDescription
,
1005 sizeof(pInfo
->slotDescription
),
1007 "Heimdal hx509 SoftToken (slot)");
1008 snprintf_fill((char *)pInfo
->manufacturerID
,
1009 sizeof(pInfo
->manufacturerID
),
1011 "Heimdal hx509 SoftToken (slot)");
1012 pInfo
->flags
= CKF_TOKEN_PRESENT
;
1013 if (soft_token
.flags
.hardware_slot
)
1014 pInfo
->flags
|= CKF_HW_SLOT
;
1015 pInfo
->hardwareVersion
.major
= 1;
1016 pInfo
->hardwareVersion
.minor
= 0;
1017 pInfo
->firmwareVersion
.major
= 1;
1018 pInfo
->firmwareVersion
.minor
= 0;
1024 C_GetTokenInfo(CK_SLOT_ID slotID
,
1025 CK_TOKEN_INFO_PTR pInfo
)
1028 st_logf("GetTokenInfo: %s\n", has_session());
1030 memset(pInfo
, 19, sizeof(*pInfo
));
1032 snprintf_fill((char *)pInfo
->label
,
1033 sizeof(pInfo
->label
),
1035 "Heimdal hx509 SoftToken (token)");
1036 snprintf_fill((char *)pInfo
->manufacturerID
,
1037 sizeof(pInfo
->manufacturerID
),
1039 "Heimdal hx509 SoftToken (token)");
1040 snprintf_fill((char *)pInfo
->model
,
1041 sizeof(pInfo
->model
),
1043 "Heimdal hx509 SoftToken (token)");
1044 snprintf_fill((char *)pInfo
->serialNumber
,
1045 sizeof(pInfo
->serialNumber
),
1049 CKF_TOKEN_INITIALIZED
|
1050 CKF_USER_PIN_INITIALIZED
;
1052 if (soft_token
.flags
.login_done
== 0)
1053 pInfo
->flags
|= CKF_LOGIN_REQUIRED
;
1056 CKF_RESTORE_KEY_NOT_NEEDED |
1058 pInfo
->ulMaxSessionCount
= MAX_NUM_SESSION
;
1059 pInfo
->ulSessionCount
= soft_token
.open_sessions
;
1060 pInfo
->ulMaxRwSessionCount
= MAX_NUM_SESSION
;
1061 pInfo
->ulRwSessionCount
= soft_token
.open_sessions
;
1062 pInfo
->ulMaxPinLen
= 1024;
1063 pInfo
->ulMinPinLen
= 0;
1064 pInfo
->ulTotalPublicMemory
= 4711;
1065 pInfo
->ulFreePublicMemory
= 4712;
1066 pInfo
->ulTotalPrivateMemory
= 4713;
1067 pInfo
->ulFreePrivateMemory
= 4714;
1068 pInfo
->hardwareVersion
.major
= 2;
1069 pInfo
->hardwareVersion
.minor
= 0;
1070 pInfo
->firmwareVersion
.major
= 2;
1071 pInfo
->firmwareVersion
.minor
= 0;
1077 C_GetMechanismList(CK_SLOT_ID slotID
,
1078 CK_MECHANISM_TYPE_PTR pMechanismList
,
1079 CK_ULONG_PTR pulCount
)
1082 st_logf("GetMechanismList\n");
1085 if (pMechanismList
== NULL_PTR
)
1087 pMechanismList
[1] = CKM_RSA_PKCS
;
1093 C_GetMechanismInfo(CK_SLOT_ID slotID
,
1094 CK_MECHANISM_TYPE type
,
1095 CK_MECHANISM_INFO_PTR pInfo
)
1098 st_logf("GetMechanismInfo: slot %d type: %d\n",
1099 (int)slotID
, (int)type
);
1100 memset(pInfo
, 0, sizeof(*pInfo
));
1106 C_InitToken(CK_SLOT_ID slotID
,
1107 CK_UTF8CHAR_PTR pPin
,
1109 CK_UTF8CHAR_PTR pLabel
)
1112 st_logf("InitToken: slot %d\n", (int)slotID
);
1113 return CKR_FUNCTION_NOT_SUPPORTED
;
1117 C_OpenSession(CK_SLOT_ID slotID
,
1119 CK_VOID_PTR pApplication
,
1121 CK_SESSION_HANDLE_PTR phSession
)
1125 st_logf("OpenSession: slot: %d\n", (int)slotID
);
1127 if (soft_token
.open_sessions
== MAX_NUM_SESSION
)
1128 return CKR_SESSION_COUNT
;
1130 soft_token
.application
= pApplication
;
1131 soft_token
.notify
= Notify
;
1133 for (i
= 0; i
< MAX_NUM_SESSION
; i
++)
1134 if (soft_token
.state
[i
].session_handle
== CK_INVALID_HANDLE
)
1136 if (i
== MAX_NUM_SESSION
)
1139 soft_token
.open_sessions
++;
1141 soft_token
.state
[i
].session_handle
=
1142 (CK_SESSION_HANDLE
)(random() & 0xfffff);
1143 *phSession
= soft_token
.state
[i
].session_handle
;
1149 C_CloseSession(CK_SESSION_HANDLE hSession
)
1151 struct session_state
*state
;
1153 st_logf("CloseSession\n");
1155 if (verify_session_handle(hSession
, &state
) != CKR_OK
)
1156 application_error("closed session not open");
1158 close_session(state
);
1164 C_CloseAllSessions(CK_SLOT_ID slotID
)
1169 st_logf("CloseAllSessions\n");
1171 for (i
= 0; i
< MAX_NUM_SESSION
; i
++)
1172 if (soft_token
.state
[i
].session_handle
!= CK_INVALID_HANDLE
)
1173 close_session(&soft_token
.state
[i
]);
1179 C_GetSessionInfo(CK_SESSION_HANDLE hSession
,
1180 CK_SESSION_INFO_PTR pInfo
)
1182 st_logf("GetSessionInfo\n");
1185 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1187 memset(pInfo
, 20, sizeof(*pInfo
));
1190 if (soft_token
.flags
.login_done
)
1191 pInfo
->state
= CKS_RO_USER_FUNCTIONS
;
1193 pInfo
->state
= CKS_RO_PUBLIC_SESSION
;
1194 pInfo
->flags
= CKF_SERIAL_SESSION
;
1195 pInfo
->ulDeviceError
= 0;
1201 C_Login(CK_SESSION_HANDLE hSession
,
1202 CK_USER_TYPE userType
,
1203 CK_UTF8CHAR_PTR pPin
,
1212 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1214 if (pPin
!= NULL_PTR
) {
1217 aret
= asprintf(&pin
, "%.*s", (int)ulPinLen
, pPin
);
1218 if (aret
!= -1 && pin
)
1219 st_logf("type: %d password: %s\n", (int)userType
, pin
);
1221 st_logf("memory error: asprintf failed\n");
1228 ret
= read_conf_file(soft_token
.config_file
, userType
, pin
);
1230 soft_token
.flags
.login_done
= 1;
1234 return soft_token
.flags
.login_done
? CKR_OK
: CKR_PIN_INCORRECT
;
1238 C_Logout(CK_SESSION_HANDLE hSession
)
1240 st_logf("Logout\n");
1243 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1244 return CKR_FUNCTION_NOT_SUPPORTED
;
1248 C_GetObjectSize(CK_SESSION_HANDLE hSession
,
1249 CK_OBJECT_HANDLE hObject
,
1250 CK_ULONG_PTR pulSize
)
1252 st_logf("GetObjectSize\n");
1255 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1256 return CKR_FUNCTION_NOT_SUPPORTED
;
1260 C_GetAttributeValue(CK_SESSION_HANDLE hSession
,
1261 CK_OBJECT_HANDLE hObject
,
1262 CK_ATTRIBUTE_PTR pTemplate
,
1265 struct session_state
*state
;
1266 struct st_object
*obj
;
1273 st_logf("GetAttributeValue: %lx\n",
1274 (unsigned long)HANDLE_OBJECT_ID(hObject
));
1275 VERIFY_SESSION_HANDLE(hSession
, &state
);
1277 if ((ret
= object_handle_to_object(hObject
, &obj
)) != CKR_OK
) {
1278 st_logf("object not found: %lx\n",
1279 (unsigned long)HANDLE_OBJECT_ID(hObject
));
1283 for (i
= 0; i
< ulCount
; i
++) {
1284 st_logf(" getting 0x%08lx\n", (unsigned long)pTemplate
[i
].type
);
1285 for (j
= 0; j
< obj
->num_attributes
; j
++) {
1286 if (obj
->attrs
[j
].secret
) {
1287 pTemplate
[i
].ulValueLen
= (CK_ULONG
)-1;
1290 if (pTemplate
[i
].type
== obj
->attrs
[j
].attribute
.type
) {
1291 if (pTemplate
[i
].pValue
!= NULL_PTR
&& obj
->attrs
[j
].secret
== 0) {
1292 if (pTemplate
[i
].ulValueLen
>= obj
->attrs
[j
].attribute
.ulValueLen
)
1293 memcpy(pTemplate
[i
].pValue
, obj
->attrs
[j
].attribute
.pValue
,
1294 obj
->attrs
[j
].attribute
.ulValueLen
);
1296 pTemplate
[i
].ulValueLen
= obj
->attrs
[j
].attribute
.ulValueLen
;
1300 if (j
== obj
->num_attributes
) {
1301 st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate
[i
].type
);
1302 pTemplate
[i
].ulValueLen
= (CK_ULONG
)-1;
1310 C_FindObjectsInit(CK_SESSION_HANDLE hSession
,
1311 CK_ATTRIBUTE_PTR pTemplate
,
1314 struct session_state
*state
;
1316 st_logf("FindObjectsInit\n");
1320 VERIFY_SESSION_HANDLE(hSession
, &state
);
1322 if (state
->find
.next_object
!= -1) {
1323 application_error("application didn't do C_FindObjectsFinal\n");
1324 find_object_final(state
);
1329 print_attributes(pTemplate
, ulCount
);
1331 state
->find
.attributes
=
1332 calloc(1, ulCount
* sizeof(state
->find
.attributes
[0]));
1333 if (state
->find
.attributes
== NULL
)
1334 return CKR_DEVICE_MEMORY
;
1335 for (i
= 0; i
< ulCount
; i
++) {
1336 state
->find
.attributes
[i
].pValue
=
1337 malloc(pTemplate
[i
].ulValueLen
);
1338 if (state
->find
.attributes
[i
].pValue
== NULL
) {
1339 find_object_final(state
);
1340 return CKR_DEVICE_MEMORY
;
1342 memcpy(state
->find
.attributes
[i
].pValue
,
1343 pTemplate
[i
].pValue
, pTemplate
[i
].ulValueLen
);
1344 state
->find
.attributes
[i
].type
= pTemplate
[i
].type
;
1345 state
->find
.attributes
[i
].ulValueLen
= pTemplate
[i
].ulValueLen
;
1347 state
->find
.num_attributes
= ulCount
;
1348 state
->find
.next_object
= 0;
1350 st_logf("find all objects\n");
1351 state
->find
.attributes
= NULL
;
1352 state
->find
.num_attributes
= 0;
1353 state
->find
.next_object
= 0;
1360 C_FindObjects(CK_SESSION_HANDLE hSession
,
1361 CK_OBJECT_HANDLE_PTR phObject
,
1362 CK_ULONG ulMaxObjectCount
,
1363 CK_ULONG_PTR pulObjectCount
)
1365 struct session_state
*state
;
1370 st_logf("FindObjects\n");
1372 VERIFY_SESSION_HANDLE(hSession
, &state
);
1374 if (state
->find
.next_object
== -1) {
1375 application_error("application didn't do C_FindObjectsInit\n");
1376 return CKR_ARGUMENTS_BAD
;
1378 if (ulMaxObjectCount
== 0) {
1379 application_error("application asked for 0 objects\n");
1380 return CKR_ARGUMENTS_BAD
;
1382 *pulObjectCount
= 0;
1383 for (i
= state
->find
.next_object
; i
< soft_token
.object
.num_objs
; i
++) {
1384 st_logf("FindObjects: %d\n", i
);
1385 state
->find
.next_object
= i
+ 1;
1386 if (attributes_match(soft_token
.object
.objs
[i
],
1387 state
->find
.attributes
,
1388 state
->find
.num_attributes
)) {
1389 *phObject
++ = soft_token
.object
.objs
[i
]->object_handle
;
1391 (*pulObjectCount
)++;
1392 if (ulMaxObjectCount
== 0)
1400 C_FindObjectsFinal(CK_SESSION_HANDLE hSession
)
1402 struct session_state
*state
;
1406 st_logf("FindObjectsFinal\n");
1407 VERIFY_SESSION_HANDLE(hSession
, &state
);
1408 find_object_final(state
);
1413 commonInit(CK_ATTRIBUTE
*attr_match
, int attr_match_len
,
1414 const CK_MECHANISM_TYPE
*mechs
, int mechs_len
,
1415 const CK_MECHANISM_PTR pMechanism
, CK_OBJECT_HANDLE hKey
,
1416 struct st_object
**o
)
1422 if ((ret
= object_handle_to_object(hKey
, o
)) != CKR_OK
)
1425 ret
= attributes_match(*o
, attr_match
, attr_match_len
);
1427 application_error("called commonInit on key that doesn't "
1428 "support required attr");
1429 return CKR_ARGUMENTS_BAD
;
1432 for (i
= 0; i
< mechs_len
; i
++)
1433 if (mechs
[i
] == pMechanism
->mechanism
)
1435 if (i
== mechs_len
) {
1436 application_error("called mech (%08lx) not supported\n",
1437 pMechanism
->mechanism
);
1438 return CKR_ARGUMENTS_BAD
;
1445 dup_mechanism(CK_MECHANISM_PTR
*dp
, const CK_MECHANISM_PTR pMechanism
)
1449 p
= malloc(sizeof(*p
));
1451 return CKR_DEVICE_MEMORY
;
1456 memcpy(p
, pMechanism
, sizeof(*p
));
1462 C_DigestInit(CK_SESSION_HANDLE hSession
,
1463 CK_MECHANISM_PTR pMechanism
)
1465 st_logf("DigestInit\n");
1467 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1468 return CKR_FUNCTION_NOT_SUPPORTED
;
1472 C_SignInit(CK_SESSION_HANDLE hSession
,
1473 CK_MECHANISM_PTR pMechanism
,
1474 CK_OBJECT_HANDLE hKey
)
1476 struct session_state
*state
;
1477 CK_MECHANISM_TYPE mechs
[] = { CKM_RSA_PKCS
};
1478 CK_BBOOL bool_true
= CK_TRUE
;
1479 CK_ATTRIBUTE attr
[] = {
1480 { CKA_SIGN
, &bool_true
, sizeof(bool_true
) }
1482 struct st_object
*o
;
1486 st_logf("SignInit\n");
1487 VERIFY_SESSION_HANDLE(hSession
, &state
);
1489 ret
= commonInit(attr
, sizeof(attr
)/sizeof(attr
[0]),
1490 mechs
, sizeof(mechs
)/sizeof(mechs
[0]),
1491 pMechanism
, hKey
, &o
);
1495 ret
= dup_mechanism(&state
->sign_mechanism
, pMechanism
);
1497 state
->sign_object
= OBJECT_ID(o
);
1503 C_Sign(CK_SESSION_HANDLE hSession
,
1506 CK_BYTE_PTR pSignature
,
1507 CK_ULONG_PTR pulSignatureLen
)
1509 struct session_state
*state
;
1510 struct st_object
*o
;
1513 const AlgorithmIdentifier
*alg
;
1514 heim_octet_string sig
, data
;
1518 VERIFY_SESSION_HANDLE(hSession
, &state
);
1523 if (state
->sign_object
== -1)
1524 return CKR_ARGUMENTS_BAD
;
1526 if (pulSignatureLen
== NULL
) {
1527 st_logf("signature len NULL\n");
1528 ret
= CKR_ARGUMENTS_BAD
;
1532 if (pData
== NULL_PTR
) {
1533 st_logf("data NULL\n");
1534 ret
= CKR_ARGUMENTS_BAD
;
1538 o
= soft_token
.object
.objs
[state
->sign_object
];
1540 if (hx509_cert_have_private_key(o
->cert
) == 0) {
1541 st_logf("private key NULL\n");
1542 return CKR_ARGUMENTS_BAD
;
1545 switch(state
->sign_mechanism
->mechanism
) {
1547 alg
= hx509_signature_rsa_pkcs1_x509();
1550 ret
= CKR_FUNCTION_NOT_SUPPORTED
;
1555 data
.length
= ulDataLen
;
1557 hret
= _hx509_create_signature(context
,
1558 _hx509_cert_private_key(o
->cert
),
1564 ret
= CKR_DEVICE_ERROR
;
1567 *pulSignatureLen
= sig
.length
;
1569 if (pSignature
!= NULL_PTR
)
1570 memcpy(pSignature
, sig
.data
, sig
.length
);
1575 memset(sig
.data
, 0, sig
.length
);
1576 der_free_octet_string(&sig
);
1582 C_SignUpdate(CK_SESSION_HANDLE hSession
,
1587 st_logf("SignUpdate\n");
1588 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1589 return CKR_FUNCTION_NOT_SUPPORTED
;
1594 C_SignFinal(CK_SESSION_HANDLE hSession
,
1595 CK_BYTE_PTR pSignature
,
1596 CK_ULONG_PTR pulSignatureLen
)
1599 st_logf("SignUpdate\n");
1600 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1601 return CKR_FUNCTION_NOT_SUPPORTED
;
1605 C_VerifyInit(CK_SESSION_HANDLE hSession
,
1606 CK_MECHANISM_PTR pMechanism
,
1607 CK_OBJECT_HANDLE hKey
)
1609 struct session_state
*state
;
1610 CK_MECHANISM_TYPE mechs
[] = { CKM_RSA_PKCS
};
1611 CK_BBOOL bool_true
= CK_TRUE
;
1612 CK_ATTRIBUTE attr
[] = {
1613 { CKA_VERIFY
, &bool_true
, sizeof(bool_true
) }
1615 struct st_object
*o
;
1619 st_logf("VerifyInit\n");
1620 VERIFY_SESSION_HANDLE(hSession
, &state
);
1622 ret
= commonInit(attr
, sizeof(attr
)/sizeof(attr
[0]),
1623 mechs
, sizeof(mechs
)/sizeof(mechs
[0]),
1624 pMechanism
, hKey
, &o
);
1628 ret
= dup_mechanism(&state
->verify_mechanism
, pMechanism
);
1630 state
->verify_object
= OBJECT_ID(o
);
1636 C_Verify(CK_SESSION_HANDLE hSession
,
1639 CK_BYTE_PTR pSignature
,
1640 CK_ULONG ulSignatureLen
)
1642 struct session_state
*state
;
1643 struct st_object
*o
;
1644 const AlgorithmIdentifier
*alg
;
1647 heim_octet_string data
, sig
;
1650 st_logf("Verify\n");
1651 VERIFY_SESSION_HANDLE(hSession
, &state
);
1653 if (state
->verify_object
== -1)
1654 return CKR_ARGUMENTS_BAD
;
1656 o
= soft_token
.object
.objs
[state
->verify_object
];
1658 switch(state
->verify_mechanism
->mechanism
) {
1660 alg
= hx509_signature_rsa_pkcs1_x509();
1663 ret
= CKR_FUNCTION_NOT_SUPPORTED
;
1668 sig
.length
= ulDataLen
;
1669 data
.data
= pSignature
;
1670 data
.length
= ulSignatureLen
;
1672 hret
= _hx509_verify_signature(context
,
1678 ret
= CKR_GENERAL_ERROR
;
1689 C_VerifyUpdate(CK_SESSION_HANDLE hSession
,
1694 st_logf("VerifyUpdate\n");
1695 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1696 return CKR_FUNCTION_NOT_SUPPORTED
;
1700 C_VerifyFinal(CK_SESSION_HANDLE hSession
,
1701 CK_BYTE_PTR pSignature
,
1702 CK_ULONG ulSignatureLen
)
1705 st_logf("VerifyFinal\n");
1706 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1707 return CKR_FUNCTION_NOT_SUPPORTED
;
1711 C_GenerateRandom(CK_SESSION_HANDLE hSession
,
1712 CK_BYTE_PTR RandomData
,
1713 CK_ULONG ulRandomLen
)
1716 st_logf("GenerateRandom\n");
1717 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1718 return CKR_FUNCTION_NOT_SUPPORTED
;
1722 CK_FUNCTION_LIST funcs
= {
1734 (void *)func_not_supported
, /* C_InitPIN */
1735 (void *)func_not_supported
, /* C_SetPIN */
1740 (void *)func_not_supported
, /* C_GetOperationState */
1741 (void *)func_not_supported
, /* C_SetOperationState */
1744 (void *)func_not_supported
, /* C_CreateObject */
1745 (void *)func_not_supported
, /* C_CopyObject */
1746 (void *)func_not_supported
, /* C_DestroyObject */
1747 (void *)func_not_supported
, /* C_GetObjectSize */
1748 C_GetAttributeValue
,
1749 (void *)func_not_supported
, /* C_SetAttributeValue */
1753 (void *)func_not_supported
, /* C_EncryptInit, */
1754 (void *)func_not_supported
, /* C_Encrypt, */
1755 (void *)func_not_supported
, /* C_EncryptUpdate, */
1756 (void *)func_not_supported
, /* C_EncryptFinal, */
1757 (void *)func_not_supported
, /* C_DecryptInit, */
1758 (void *)func_not_supported
, /* C_Decrypt, */
1759 (void *)func_not_supported
, /* C_DecryptUpdate, */
1760 (void *)func_not_supported
, /* C_DecryptFinal, */
1762 (void *)func_not_supported
, /* C_Digest */
1763 (void *)func_not_supported
, /* C_DigestUpdate */
1764 (void *)func_not_supported
, /* C_DigestKey */
1765 (void *)func_not_supported
, /* C_DigestFinal */
1770 (void *)func_not_supported
, /* C_SignRecoverInit */
1771 (void *)func_not_supported
, /* C_SignRecover */
1776 (void *)func_not_supported
, /* C_VerifyRecoverInit */
1777 (void *)func_not_supported
, /* C_VerifyRecover */
1778 (void *)func_not_supported
, /* C_DigestEncryptUpdate */
1779 (void *)func_not_supported
, /* C_DecryptDigestUpdate */
1780 (void *)func_not_supported
, /* C_SignEncryptUpdate */
1781 (void *)func_not_supported
, /* C_DecryptVerifyUpdate */
1782 (void *)func_not_supported
, /* C_GenerateKey */
1783 (void *)func_not_supported
, /* C_GenerateKeyPair */
1784 (void *)func_not_supported
, /* C_WrapKey */
1785 (void *)func_not_supported
, /* C_UnwrapKey */
1786 (void *)func_not_supported
, /* C_DeriveKey */
1787 (void *)func_not_supported
, /* C_SeedRandom */
1789 (void *)func_not_supported
, /* C_GetFunctionStatus */
1790 (void *)func_not_supported
, /* C_CancelFunction */
1791 (void *)func_not_supported
/* C_WaitForSlotEvent */