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
37 #define OBJECT_ID_MASK 0xfff
38 #define HANDLE_OBJECT_ID(h) ((h) & OBJECT_ID_MASK)
39 #define OBJECT_ID(obj) HANDLE_OBJECT_ID((obj)->object_handle)
43 CK_ATTRIBUTE attribute
;
48 CK_OBJECT_HANDLE object_handle
;
49 struct st_attr
*attrs
;
59 static struct soft_token
{
60 CK_VOID_PTR application
;
65 struct st_object
**objs
;
74 struct session_state
{
75 CK_SESSION_HANDLE session_handle
;
78 CK_ATTRIBUTE
*attributes
;
79 CK_ULONG num_attributes
;
84 CK_MECHANISM_PTR encrypt_mechanism
;
86 CK_MECHANISM_PTR decrypt_mechanism
;
88 CK_MECHANISM_PTR sign_mechanism
;
90 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
, ...)
140 len
= vsnprintf(str
, size
, fmt
, ap
);
142 if (len
< 0 || len
> size
)
145 str
[len
++] = fillchar
;
149 #define printf error_use_st_logf
152 #define VERIFY_SESSION_HANDLE(s, state) \
155 ret = verify_session_handle(s, state); \
156 if (ret != CKR_OK) { \
157 /* return CKR_OK */; \
162 verify_session_handle(CK_SESSION_HANDLE hSession
,
163 struct session_state
**state
)
167 for (i
= 0; i
< MAX_NUM_SESSION
; i
++){
168 if (soft_token
.state
[i
].session_handle
== hSession
)
171 if (i
== MAX_NUM_SESSION
) {
172 application_error("use of invalid handle: 0x%08lx\n",
173 (unsigned long)hSession
);
174 return CKR_SESSION_HANDLE_INVALID
;
177 *state
= &soft_token
.state
[i
];
182 object_handle_to_object(CK_OBJECT_HANDLE handle
,
183 struct st_object
**object
)
185 int i
= HANDLE_OBJECT_ID(handle
);
188 if (i
>= soft_token
.object
.num_objs
)
189 return CKR_ARGUMENTS_BAD
;
190 if (soft_token
.object
.objs
[i
] == NULL
)
191 return CKR_ARGUMENTS_BAD
;
192 if (soft_token
.object
.objs
[i
]->object_handle
!= handle
)
193 return CKR_ARGUMENTS_BAD
;
194 *object
= soft_token
.object
.objs
[i
];
199 attributes_match(const struct st_object
*obj
,
200 const CK_ATTRIBUTE
*attributes
,
201 CK_ULONG num_attributes
)
205 st_logf("attributes_match: %ld\n", (unsigned long)OBJECT_ID(obj
));
207 for (i
= 0; i
< num_attributes
; i
++) {
209 for (j
= 0; j
< obj
->num_attributes
; j
++) {
210 if (attributes
[i
].type
== obj
->attrs
[j
].attribute
.type
&&
211 attributes
[i
].ulValueLen
== obj
->attrs
[j
].attribute
.ulValueLen
&&
212 memcmp(attributes
[i
].pValue
, obj
->attrs
[j
].attribute
.pValue
,
213 attributes
[i
].ulValueLen
) == 0) {
219 st_logf("type %d attribute have no match\n", attributes
[i
].type
);
223 st_logf("attribute matches\n");
228 print_attributes(const CK_ATTRIBUTE
*attributes
,
229 CK_ULONG num_attributes
)
233 st_logf("find objects: attrs: %lu\n", (unsigned long)num_attributes
);
235 for (i
= 0; i
< num_attributes
; i
++) {
237 switch (attributes
[i
].type
) {
240 if (attributes
[i
].ulValueLen
!= sizeof(CK_BBOOL
)) {
241 application_error("token attribute wrong length\n");
244 ck_true
= attributes
[i
].pValue
;
245 st_logf("token: %s", *ck_true
? "TRUE" : "FALSE");
249 CK_OBJECT_CLASS
*class;
250 if (attributes
[i
].ulValueLen
!= sizeof(CK_ULONG
)) {
251 application_error("class attribute wrong length\n");
254 class = attributes
[i
].pValue
;
257 case CKO_CERTIFICATE
:
258 st_logf("certificate");
261 st_logf("public key");
263 case CKO_PRIVATE_KEY
:
264 st_logf("private key");
267 st_logf("secret key");
269 case CKO_DOMAIN_PARAMETERS
:
270 st_logf("domain parameters");
273 st_logf("[class %lx]", (long unsigned)*class);
284 case CKA_APPLICATION
:
285 st_logf("application");
294 st_logf("[unknown 0x%08lx]", (unsigned long)attributes
[i
].type
);
301 static struct st_object
*
304 struct st_object
*o
, **objs
;
307 o
= malloc(sizeof(*o
));
310 memset(o
, 0, sizeof(*o
));
312 o
->num_attributes
= 0;
314 for (i
= 0; i
< soft_token
.object
.num_objs
; i
++) {
315 if (soft_token
.object
.objs
== NULL
) {
316 soft_token
.object
.objs
[i
] = o
;
320 if (i
== soft_token
.object
.num_objs
) {
321 objs
= realloc(soft_token
.object
.objs
,
322 (soft_token
.object
.num_objs
+ 1) * sizeof(soft_token
.object
.objs
[0]));
327 soft_token
.object
.objs
= objs
;
328 soft_token
.object
.objs
[soft_token
.object
.num_objs
++] = o
;
330 soft_token
.object
.objs
[i
]->object_handle
=
331 (random() & (~OBJECT_ID_MASK
)) | i
;
337 add_object_attribute(struct st_object
*o
,
339 CK_ATTRIBUTE_TYPE type
,
346 i
= o
->num_attributes
;
347 a
= realloc(o
->attrs
, (i
+ 1) * sizeof(o
->attrs
[0]));
349 return CKR_DEVICE_MEMORY
;
351 o
->attrs
[i
].secret
= secret
;
352 o
->attrs
[i
].attribute
.type
= type
;
353 o
->attrs
[i
].attribute
.pValue
= malloc(ulValueLen
);
354 if (o
->attrs
[i
].attribute
.pValue
== NULL
&& ulValueLen
!= 0)
355 return CKR_DEVICE_MEMORY
;
356 memcpy(o
->attrs
[i
].attribute
.pValue
, pValue
, ulValueLen
);
357 o
->attrs
[i
].attribute
.ulValueLen
= ulValueLen
;
364 add_pubkey_info(hx509_context hxctx
, struct st_object
*o
,
365 CK_KEY_TYPE key_type
, hx509_cert cert
)
368 CK_BYTE
*modulus
= NULL
;
369 size_t modulus_len
= 0;
370 CK_ULONG modulus_bits
= 0;
371 CK_BYTE
*exponent
= NULL
;
372 size_t exponent_len
= 0;
374 if (key_type
!= CKK_RSA
)
377 num
= _hx509_private_key_get_internal(context
,
378 _hx509_cert_private_key(cert
),
381 return CKR_GENERAL_ERROR
;
382 modulus_bits
= BN_num_bits(num
);
384 modulus_len
= BN_num_bytes(num
);
385 modulus
= malloc(modulus_len
);
386 BN_bn2bin(num
, modulus
);
389 add_object_attribute(o
, 0, CKA_MODULUS
, modulus
, modulus_len
);
390 add_object_attribute(o
, 0, CKA_MODULUS_BITS
,
391 &modulus_bits
, sizeof(modulus_bits
));
395 num
= _hx509_private_key_get_internal(context
,
396 _hx509_cert_private_key(cert
),
399 return CKR_GENERAL_ERROR
;
401 exponent_len
= BN_num_bytes(num
);
402 exponent
= malloc(exponent_len
);
403 BN_bn2bin(num
, exponent
);
406 add_object_attribute(o
, 0, CKA_PUBLIC_EXPONENT
,
407 exponent
, exponent_len
);
421 add_cert(hx509_context hxctx
, void *ctx
, hx509_cert cert
)
423 struct foo
*foo
= (struct foo
*)ctx
;
424 struct st_object
*o
= NULL
;
425 CK_BBOOL bool_true
= CK_TRUE
;
426 CK_BBOOL bool_false
= CK_FALSE
;
428 CK_CERTIFICATE_TYPE cert_type
= CKC_X_509
;
429 CK_KEY_TYPE key_type
;
430 CK_MECHANISM_TYPE mech_type
;
431 CK_RV ret
= CKR_GENERAL_ERROR
;
433 heim_octet_string cert_data
, subject_data
, issuer_data
, serial_data
;
435 st_logf("adding certificate\n");
437 serial_data
.data
= NULL
;
438 serial_data
.length
= 0;
439 cert_data
= subject_data
= issuer_data
= serial_data
;
441 hret
= hx509_cert_binary(hxctx
, cert
, &cert_data
);
448 hret
= hx509_cert_get_issuer(cert
, &name
);
451 hret
= hx509_name_binary(name
, &issuer_data
);
452 hx509_name_free(&name
);
456 hret
= hx509_cert_get_subject(cert
, &name
);
459 hret
= hx509_name_binary(name
, &subject_data
);
460 hx509_name_free(&name
);
468 ret
= CKR_DEVICE_MEMORY
;
471 o
->type
= STO_T_CERTIFICATE
;
472 o
->cert
= hx509_cert_ref(cert
);
474 key_type
= CKK_RSA
; /* XXX */
477 switch (EVP_PKEY_type(public_key
->type
)) {
491 add_object_attribute(o
, 0, CKA_CLASS
, &c
, sizeof(c
));
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
));
510 ret
= CKR_DEVICE_MEMORY
;
513 o
->type
= STO_T_PUBLIC_KEY
;
514 o
->cert
= hx509_cert_ref(cert
);
517 add_object_attribute(o
, 0, CKA_CLASS
, &c
, sizeof(c
));
518 add_object_attribute(o
, 0, CKA_TOKEN
, &bool_true
, sizeof(bool_true
));
519 add_object_attribute(o
, 0, CKA_PRIVATE
, &bool_false
, sizeof(bool_false
));
520 add_object_attribute(o
, 0, CKA_MODIFIABLE
, &bool_false
, sizeof(bool_false
));
521 add_object_attribute(o
, 0, CKA_LABEL
, foo
->label
, strlen(foo
->label
));
523 add_object_attribute(o
, 0, CKA_KEY_TYPE
, &key_type
, sizeof(key_type
));
524 add_object_attribute(o
, 0, CKA_ID
, foo
->id
, strlen(foo
->id
));
525 add_object_attribute(o
, 0, CKA_START_DATE
, "", 1); /* XXX */
526 add_object_attribute(o
, 0, CKA_END_DATE
, "", 1); /* XXX */
527 add_object_attribute(o
, 0, CKA_DERIVE
, &bool_false
, sizeof(bool_false
));
528 add_object_attribute(o
, 0, CKA_LOCAL
, &bool_false
, sizeof(bool_false
));
529 mech_type
= CKM_RSA_X_509
;
530 add_object_attribute(o
, 0, CKA_KEY_GEN_MECHANISM
, &mech_type
, sizeof(mech_type
));
532 add_object_attribute(o
, 0, CKA_SUBJECT
, subject_data
.data
, subject_data
.length
);
533 add_object_attribute(o
, 0, CKA_ENCRYPT
, &bool_true
, sizeof(bool_true
));
534 add_object_attribute(o
, 0, CKA_VERIFY
, &bool_true
, sizeof(bool_true
));
535 add_object_attribute(o
, 0, CKA_VERIFY_RECOVER
, &bool_false
, sizeof(bool_false
));
536 add_object_attribute(o
, 0, CKA_WRAP
, &bool_true
, sizeof(bool_true
));
537 add_object_attribute(o
, 0, CKA_TRUSTED
, &bool_true
, sizeof(bool_true
));
539 add_pubkey_info(hxctx
, o
, key_type
, cert
);
541 st_logf("add key ok: %lx\n", (unsigned long)OBJECT_ID(o
));
543 if (hx509_cert_have_private_key(cert
)) {
548 ret
= CKR_DEVICE_MEMORY
;
551 o
->type
= STO_T_PRIVATE_KEY
;
552 o
->cert
= hx509_cert_ref(cert
);
555 add_object_attribute(o
, 0, CKA_CLASS
, &c
, sizeof(c
));
556 add_object_attribute(o
, 0, CKA_TOKEN
, &bool_true
, sizeof(bool_true
));
557 add_object_attribute(o
, 0, CKA_PRIVATE
, &bool_true
, sizeof(bool_false
));
558 add_object_attribute(o
, 0, CKA_MODIFIABLE
, &bool_false
, sizeof(bool_false
));
559 add_object_attribute(o
, 0, CKA_LABEL
, foo
->label
, strlen(foo
->label
));
561 add_object_attribute(o
, 0, CKA_KEY_TYPE
, &key_type
, sizeof(key_type
));
562 add_object_attribute(o
, 0, CKA_ID
, foo
->id
, strlen(foo
->id
));
563 add_object_attribute(o
, 0, CKA_START_DATE
, "", 1); /* XXX */
564 add_object_attribute(o
, 0, CKA_END_DATE
, "", 1); /* XXX */
565 add_object_attribute(o
, 0, CKA_DERIVE
, &bool_false
, sizeof(bool_false
));
566 add_object_attribute(o
, 0, CKA_LOCAL
, &bool_false
, sizeof(bool_false
));
567 mech_type
= CKM_RSA_X_509
;
568 add_object_attribute(o
, 0, CKA_KEY_GEN_MECHANISM
, &mech_type
, sizeof(mech_type
));
570 add_object_attribute(o
, 0, CKA_SUBJECT
, subject_data
.data
, subject_data
.length
);
571 add_object_attribute(o
, 0, CKA_SENSITIVE
, &bool_true
, sizeof(bool_true
));
572 add_object_attribute(o
, 0, CKA_SECONDARY_AUTH
, &bool_false
, sizeof(bool_true
));
574 add_object_attribute(o
, 0, CKA_AUTH_PIN_FLAGS
, &flags
, sizeof(flags
));
576 add_object_attribute(o
, 0, CKA_DECRYPT
, &bool_true
, sizeof(bool_true
));
577 add_object_attribute(o
, 0, CKA_SIGN
, &bool_true
, sizeof(bool_true
));
578 add_object_attribute(o
, 0, CKA_SIGN_RECOVER
, &bool_false
, sizeof(bool_false
));
579 add_object_attribute(o
, 0, CKA_UNWRAP
, &bool_true
, sizeof(bool_true
));
580 add_object_attribute(o
, 0, CKA_EXTRACTABLE
, &bool_true
, sizeof(bool_true
));
581 add_object_attribute(o
, 0, CKA_NEVER_EXTRACTABLE
, &bool_false
, sizeof(bool_false
));
583 add_pubkey_info(hxctx
, o
, key_type
, cert
);
589 st_logf("something went wrong when adding cert!\n");
593 hx509_xfree(cert_data
.data
);
594 hx509_xfree(serial_data
.data
);
595 hx509_xfree(issuer_data
.data
);
596 hx509_xfree(subject_data
.data
);
603 add_certificate(const char *cert_file
,
615 ret
= hx509_certs_init(context
, cert_file
, 0, NULL
, &certs
);
617 st_logf("failed to open file %s\n", cert_file
);
618 return CKR_GENERAL_ERROR
;
621 ret
= hx509_certs_iter(context
, certs
, add_cert
, &foo
);
622 hx509_certs_free(&certs
);
624 st_logf("failed adding certs from file %s\n", cert_file
);
625 return CKR_GENERAL_ERROR
;
632 find_object_final(struct session_state
*state
)
634 if (state
->find
.attributes
) {
637 for (i
= 0; i
< state
->find
.num_attributes
; i
++) {
638 if (state
->find
.attributes
[i
].pValue
)
639 free(state
->find
.attributes
[i
].pValue
);
641 free(state
->find
.attributes
);
642 state
->find
.attributes
= NULL
;
643 state
->find
.num_attributes
= 0;
644 state
->find
.next_object
= -1;
649 reset_crypto_state(struct session_state
*state
)
651 state
->encrypt_object
= -1;
652 if (state
->encrypt_mechanism
)
653 free(state
->encrypt_mechanism
);
654 state
->encrypt_mechanism
= NULL_PTR
;
655 state
->decrypt_object
= -1;
656 if (state
->decrypt_mechanism
)
657 free(state
->decrypt_mechanism
);
658 state
->decrypt_mechanism
= NULL_PTR
;
659 state
->sign_object
= -1;
660 if (state
->sign_mechanism
)
661 free(state
->sign_mechanism
);
662 state
->sign_mechanism
= NULL_PTR
;
663 state
->verify_object
= -1;
664 if (state
->verify_mechanism
)
665 free(state
->verify_mechanism
);
666 state
->verify_mechanism
= NULL_PTR
;
667 state
->digest_object
= -1;
671 close_session(struct session_state
*state
)
673 if (state
->find
.attributes
) {
674 application_error("application didn't do C_FindObjectsFinal\n");
675 find_object_final(state
);
678 state
->session_handle
= CK_INVALID_HANDLE
;
679 soft_token
.application
= NULL_PTR
;
680 soft_token
.notify
= NULL_PTR
;
681 reset_crypto_state(state
);
687 return soft_token
.open_sessions
> 0 ? "yes" : "no";
691 read_conf_file(const char *fn
, CK_USER_TYPE userType
, const char *pin
)
693 char buf
[1024], *type
, *s
, *p
;
700 st_logf("can't open configuration file %s\n", fn
);
701 return CKR_GENERAL_ERROR
;
704 while(fgets(buf
, sizeof(buf
), f
) != NULL
) {
705 buf
[strcspn(buf
, "\n")] = '\0';
709 st_logf("line: %s\n", buf
);
720 type
= strtok_r(p
, "\t", &s
);
724 if (strcasecmp("certificate", type
) == 0) {
725 char *cert
, *id
, *label
;
727 id
= strtok_r(NULL
, "\t", &s
);
732 st_logf("id: %s\n", id
);
733 label
= strtok_r(NULL
, "\t", &s
);
735 st_logf("no label\n");
738 cert
= strtok_r(NULL
, "\t", &s
);
740 st_logf("no certfiicate store\n");
744 st_logf("adding: %s: %s in file %s\n", id
, label
, cert
);
746 ret
= add_certificate(cert
, pin
, id
, label
);
750 st_logf("unknown type: %s\n", type
);
760 func_not_supported(void)
762 st_logf("function not supported\n");
763 return CKR_FUNCTION_NOT_SUPPORTED
;
767 C_Initialize(CK_VOID_PTR a
)
769 CK_C_INITIALIZE_ARGS_PTR args
= a
;
773 st_logf("Initialize\n");
777 OpenSSL_add_all_algorithms();
779 srandom(getpid() ^ time(NULL
));
781 for (i
= 0; i
< MAX_NUM_SESSION
; i
++) {
782 soft_token
.state
[i
].session_handle
= CK_INVALID_HANDLE
;
783 soft_token
.state
[i
].find
.attributes
= NULL
;
784 soft_token
.state
[i
].find
.num_attributes
= 0;
785 soft_token
.state
[i
].find
.next_object
= -1;
786 reset_crypto_state(&soft_token
.state
[i
]);
789 soft_token
.flags
.hardware_slot
= 1;
790 soft_token
.flags
.app_error_fatal
= 0;
791 soft_token
.flags
.login_done
= 0;
793 soft_token
.object
.objs
= NULL
;
794 soft_token
.object
.num_objs
= 0;
796 soft_token
.logfile
= NULL
;
798 soft_token
.logfile
= stdout
;
801 soft_token
.logfile
= fopen("/tmp/log-pkcs11.txt", "a");
805 st_logf("\tCreateMutex:\t%p\n", args
->CreateMutex
);
806 st_logf("\tDestroyMutext\t%p\n", args
->DestroyMutex
);
807 st_logf("\tLockMutext\t%p\n", args
->LockMutex
);
808 st_logf("\tUnlockMutext\t%p\n", args
->UnlockMutex
);
809 st_logf("\tFlags\t%04x\n", (unsigned int)args
->flags
);
813 char *fn
= NULL
, *home
= NULL
;
815 if (getuid() == geteuid()) {
816 fn
= getenv("SOFTPKCS11RC");
819 home
= getenv("HOME");
821 if (fn
== NULL
&& home
== NULL
) {
822 struct passwd
*pw
= getpwuid(getuid());
828 asprintf(&fn
, "%s/.soft-token.rc", home
);
830 fn
= strdup("/etc/soft-token.rc");
833 soft_token
.config_file
= fn
;
836 ret
= read_conf_file(soft_token
.config_file
, CKU_USER
, NULL
);
838 soft_token
.flags
.login_done
= 1;
844 C_Finalize(CK_VOID_PTR args
)
850 st_logf("Finalize\n");
852 for (i
= 0; i
< MAX_NUM_SESSION
; i
++) {
853 if (soft_token
.state
[i
].session_handle
!= CK_INVALID_HANDLE
) {
854 application_error("application finalized without "
855 "closing session\n");
856 close_session(&soft_token
.state
[i
]);
864 C_GetInfo(CK_INFO_PTR args
)
868 st_logf("GetInfo\n");
870 memset(args
, 17, sizeof(*args
));
871 args
->cryptokiVersion
.major
= 2;
872 args
->cryptokiVersion
.minor
= 10;
873 snprintf_fill((char *)args
->manufacturerID
,
874 sizeof(args
->manufacturerID
),
876 "Heimdal hx509 SoftToken");
877 snprintf_fill((char *)args
->libraryDescription
,
878 sizeof(args
->libraryDescription
), ' ',
879 "Heimdal hx509 SoftToken");
880 args
->libraryVersion
.major
= 2;
881 args
->libraryVersion
.minor
= 0;
886 extern CK_FUNCTION_LIST funcs
;
889 C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList
)
893 *ppFunctionList
= &funcs
;
898 C_GetSlotList(CK_BBOOL tokenPresent
,
899 CK_SLOT_ID_PTR pSlotList
,
900 CK_ULONG_PTR pulCount
)
903 st_logf("GetSlotList: %s\n",
904 tokenPresent
? "tokenPresent" : "token not Present");
912 C_GetSlotInfo(CK_SLOT_ID slotID
,
913 CK_SLOT_INFO_PTR pInfo
)
916 st_logf("GetSlotInfo: slot: %d : %s\n", (int)slotID
, has_session());
918 memset(pInfo
, 18, sizeof(*pInfo
));
921 return CKR_ARGUMENTS_BAD
;
923 snprintf_fill((char *)pInfo
->slotDescription
,
924 sizeof(pInfo
->slotDescription
),
926 "Heimdal hx509 SoftToken (slot)");
927 snprintf_fill((char *)pInfo
->manufacturerID
,
928 sizeof(pInfo
->manufacturerID
),
930 "Heimdal hx509 SoftToken (slot)");
931 pInfo
->flags
= CKF_TOKEN_PRESENT
;
932 if (soft_token
.flags
.hardware_slot
)
933 pInfo
->flags
|= CKF_HW_SLOT
;
934 pInfo
->hardwareVersion
.major
= 1;
935 pInfo
->hardwareVersion
.minor
= 0;
936 pInfo
->firmwareVersion
.major
= 1;
937 pInfo
->firmwareVersion
.minor
= 0;
943 C_GetTokenInfo(CK_SLOT_ID slotID
,
944 CK_TOKEN_INFO_PTR pInfo
)
947 st_logf("GetTokenInfo: %s\n", has_session());
949 memset(pInfo
, 19, sizeof(*pInfo
));
951 snprintf_fill((char *)pInfo
->label
,
952 sizeof(pInfo
->label
),
954 "Heimdal hx509 SoftToken (token)");
955 snprintf_fill((char *)pInfo
->manufacturerID
,
956 sizeof(pInfo
->manufacturerID
),
958 "Heimdal hx509 SoftToken (token)");
959 snprintf_fill((char *)pInfo
->model
,
960 sizeof(pInfo
->model
),
962 "Heimdal hx509 SoftToken (token)");
963 snprintf_fill((char *)pInfo
->serialNumber
,
964 sizeof(pInfo
->serialNumber
),
968 CKF_TOKEN_INITIALIZED
|
969 CKF_USER_PIN_INITIALIZED
;
971 if (soft_token
.flags
.login_done
== 0)
972 pInfo
->flags
|= CKF_LOGIN_REQUIRED
;
975 CKF_RESTORE_KEY_NOT_NEEDED |
977 pInfo
->ulMaxSessionCount
= MAX_NUM_SESSION
;
978 pInfo
->ulSessionCount
= soft_token
.open_sessions
;
979 pInfo
->ulMaxRwSessionCount
= MAX_NUM_SESSION
;
980 pInfo
->ulRwSessionCount
= soft_token
.open_sessions
;
981 pInfo
->ulMaxPinLen
= 1024;
982 pInfo
->ulMinPinLen
= 0;
983 pInfo
->ulTotalPublicMemory
= 4711;
984 pInfo
->ulFreePublicMemory
= 4712;
985 pInfo
->ulTotalPrivateMemory
= 4713;
986 pInfo
->ulFreePrivateMemory
= 4714;
987 pInfo
->hardwareVersion
.major
= 2;
988 pInfo
->hardwareVersion
.minor
= 0;
989 pInfo
->firmwareVersion
.major
= 2;
990 pInfo
->firmwareVersion
.minor
= 0;
996 C_GetMechanismList(CK_SLOT_ID slotID
,
997 CK_MECHANISM_TYPE_PTR pMechanismList
,
998 CK_ULONG_PTR pulCount
)
1001 st_logf("GetMechanismList\n");
1004 if (pMechanismList
== NULL_PTR
)
1006 pMechanismList
[1] = CKM_RSA_PKCS
;
1012 C_GetMechanismInfo(CK_SLOT_ID slotID
,
1013 CK_MECHANISM_TYPE type
,
1014 CK_MECHANISM_INFO_PTR pInfo
)
1017 st_logf("GetMechanismInfo: slot %d type: %d\n",
1018 (int)slotID
, (int)type
);
1019 memset(pInfo
, 0, sizeof(*pInfo
));
1025 C_InitToken(CK_SLOT_ID slotID
,
1026 CK_UTF8CHAR_PTR pPin
,
1028 CK_UTF8CHAR_PTR pLabel
)
1031 st_logf("InitToken: slot %d\n", (int)slotID
);
1032 return CKR_FUNCTION_NOT_SUPPORTED
;
1036 C_OpenSession(CK_SLOT_ID slotID
,
1038 CK_VOID_PTR pApplication
,
1040 CK_SESSION_HANDLE_PTR phSession
)
1044 st_logf("OpenSession: slot: %d\n", (int)slotID
);
1046 if (soft_token
.open_sessions
== MAX_NUM_SESSION
)
1047 return CKR_SESSION_COUNT
;
1049 soft_token
.application
= pApplication
;
1050 soft_token
.notify
= Notify
;
1052 for (i
= 0; i
< MAX_NUM_SESSION
; i
++)
1053 if (soft_token
.state
[i
].session_handle
== CK_INVALID_HANDLE
)
1055 if (i
== MAX_NUM_SESSION
)
1058 soft_token
.open_sessions
++;
1060 soft_token
.state
[i
].session_handle
=
1061 (CK_SESSION_HANDLE
)(random() & 0xfffff);
1062 *phSession
= soft_token
.state
[i
].session_handle
;
1068 C_CloseSession(CK_SESSION_HANDLE hSession
)
1070 struct session_state
*state
;
1072 st_logf("CloseSession\n");
1074 if (verify_session_handle(hSession
, &state
) != CKR_OK
)
1075 application_error("closed session not open");
1077 close_session(state
);
1083 C_CloseAllSessions(CK_SLOT_ID slotID
)
1088 st_logf("CloseAllSessions\n");
1090 for (i
= 0; i
< MAX_NUM_SESSION
; i
++)
1091 if (soft_token
.state
[i
].session_handle
!= CK_INVALID_HANDLE
)
1092 close_session(&soft_token
.state
[i
]);
1098 C_GetSessionInfo(CK_SESSION_HANDLE hSession
,
1099 CK_SESSION_INFO_PTR pInfo
)
1101 st_logf("GetSessionInfo\n");
1104 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1106 memset(pInfo
, 20, sizeof(*pInfo
));
1109 if (soft_token
.flags
.login_done
)
1110 pInfo
->state
= CKS_RO_USER_FUNCTIONS
;
1112 pInfo
->state
= CKS_RO_PUBLIC_SESSION
;
1113 pInfo
->flags
= CKF_SERIAL_SESSION
;
1114 pInfo
->ulDeviceError
= 0;
1120 C_Login(CK_SESSION_HANDLE hSession
,
1121 CK_USER_TYPE userType
,
1122 CK_UTF8CHAR_PTR pPin
,
1131 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1133 if (pPin
!= NULL_PTR
) {
1134 asprintf(&pin
, "%.*s", (int)ulPinLen
, pPin
);
1135 st_logf("type: %d password: %s\n", (int)userType
, pin
);
1142 ret
= read_conf_file(soft_token
.config_file
, userType
, pin
);
1144 soft_token
.flags
.login_done
= 1;
1148 return soft_token
.flags
.login_done
? CKR_OK
: CKR_PIN_INCORRECT
;
1152 C_Logout(CK_SESSION_HANDLE hSession
)
1154 st_logf("Logout\n");
1157 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1158 return CKR_FUNCTION_NOT_SUPPORTED
;
1162 C_GetObjectSize(CK_SESSION_HANDLE hSession
,
1163 CK_OBJECT_HANDLE hObject
,
1164 CK_ULONG_PTR pulSize
)
1166 st_logf("GetObjectSize\n");
1169 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1170 return CKR_FUNCTION_NOT_SUPPORTED
;
1174 C_GetAttributeValue(CK_SESSION_HANDLE hSession
,
1175 CK_OBJECT_HANDLE hObject
,
1176 CK_ATTRIBUTE_PTR pTemplate
,
1179 struct session_state
*state
;
1180 struct st_object
*obj
;
1187 st_logf("GetAttributeValue: %lx\n",
1188 (unsigned long)HANDLE_OBJECT_ID(hObject
));
1189 VERIFY_SESSION_HANDLE(hSession
, &state
);
1191 if ((ret
= object_handle_to_object(hObject
, &obj
)) != CKR_OK
) {
1192 st_logf("object not found: %lx\n",
1193 (unsigned long)HANDLE_OBJECT_ID(hObject
));
1197 for (i
= 0; i
< ulCount
; i
++) {
1198 st_logf(" getting 0x%08lx\n", (unsigned long)pTemplate
[i
].type
);
1199 for (j
= 0; j
< obj
->num_attributes
; j
++) {
1200 if (obj
->attrs
[j
].secret
) {
1201 pTemplate
[i
].ulValueLen
= (CK_ULONG
)-1;
1204 if (pTemplate
[i
].type
== obj
->attrs
[j
].attribute
.type
) {
1205 if (pTemplate
[i
].pValue
!= NULL_PTR
&& obj
->attrs
[j
].secret
== 0) {
1206 if (pTemplate
[i
].ulValueLen
>= obj
->attrs
[j
].attribute
.ulValueLen
)
1207 memcpy(pTemplate
[i
].pValue
, obj
->attrs
[j
].attribute
.pValue
,
1208 obj
->attrs
[j
].attribute
.ulValueLen
);
1210 pTemplate
[i
].ulValueLen
= obj
->attrs
[j
].attribute
.ulValueLen
;
1214 if (j
== obj
->num_attributes
) {
1215 st_logf("key type: 0x%08lx not found\n", (unsigned long)pTemplate
[i
].type
);
1216 pTemplate
[i
].ulValueLen
= (CK_ULONG
)-1;
1224 C_FindObjectsInit(CK_SESSION_HANDLE hSession
,
1225 CK_ATTRIBUTE_PTR pTemplate
,
1228 struct session_state
*state
;
1230 st_logf("FindObjectsInit\n");
1234 VERIFY_SESSION_HANDLE(hSession
, &state
);
1236 if (state
->find
.next_object
!= -1) {
1237 application_error("application didn't do C_FindObjectsFinal\n");
1238 find_object_final(state
);
1243 print_attributes(pTemplate
, ulCount
);
1245 state
->find
.attributes
=
1246 calloc(1, ulCount
* sizeof(state
->find
.attributes
[0]));
1247 if (state
->find
.attributes
== NULL
)
1248 return CKR_DEVICE_MEMORY
;
1249 for (i
= 0; i
< ulCount
; i
++) {
1250 state
->find
.attributes
[i
].pValue
=
1251 malloc(pTemplate
[i
].ulValueLen
);
1252 if (state
->find
.attributes
[i
].pValue
== NULL
) {
1253 find_object_final(state
);
1254 return CKR_DEVICE_MEMORY
;
1256 memcpy(state
->find
.attributes
[i
].pValue
,
1257 pTemplate
[i
].pValue
, pTemplate
[i
].ulValueLen
);
1258 state
->find
.attributes
[i
].type
= pTemplate
[i
].type
;
1259 state
->find
.attributes
[i
].ulValueLen
= pTemplate
[i
].ulValueLen
;
1261 state
->find
.num_attributes
= ulCount
;
1262 state
->find
.next_object
= 0;
1264 st_logf("find all objects\n");
1265 state
->find
.attributes
= NULL
;
1266 state
->find
.num_attributes
= 0;
1267 state
->find
.next_object
= 0;
1274 C_FindObjects(CK_SESSION_HANDLE hSession
,
1275 CK_OBJECT_HANDLE_PTR phObject
,
1276 CK_ULONG ulMaxObjectCount
,
1277 CK_ULONG_PTR pulObjectCount
)
1279 struct session_state
*state
;
1284 st_logf("FindObjects\n");
1286 VERIFY_SESSION_HANDLE(hSession
, &state
);
1288 if (state
->find
.next_object
== -1) {
1289 application_error("application didn't do C_FindObjectsInit\n");
1290 return CKR_ARGUMENTS_BAD
;
1292 if (ulMaxObjectCount
== 0) {
1293 application_error("application asked for 0 objects\n");
1294 return CKR_ARGUMENTS_BAD
;
1296 *pulObjectCount
= 0;
1297 for (i
= state
->find
.next_object
; i
< soft_token
.object
.num_objs
; i
++) {
1298 st_logf("FindObjects: %d\n", i
);
1299 state
->find
.next_object
= i
+ 1;
1300 if (attributes_match(soft_token
.object
.objs
[i
],
1301 state
->find
.attributes
,
1302 state
->find
.num_attributes
)) {
1303 *phObject
++ = soft_token
.object
.objs
[i
]->object_handle
;
1305 (*pulObjectCount
)++;
1306 if (ulMaxObjectCount
== 0)
1314 C_FindObjectsFinal(CK_SESSION_HANDLE hSession
)
1316 struct session_state
*state
;
1320 st_logf("FindObjectsFinal\n");
1321 VERIFY_SESSION_HANDLE(hSession
, &state
);
1322 find_object_final(state
);
1327 commonInit(CK_ATTRIBUTE
*attr_match
, int attr_match_len
,
1328 const CK_MECHANISM_TYPE
*mechs
, int mechs_len
,
1329 const CK_MECHANISM_PTR pMechanism
, CK_OBJECT_HANDLE hKey
,
1330 struct st_object
**o
)
1336 if ((ret
= object_handle_to_object(hKey
, o
)) != CKR_OK
)
1339 ret
= attributes_match(*o
, attr_match
, attr_match_len
);
1341 application_error("called commonInit on key that doesn't "
1342 "support required attr");
1343 return CKR_ARGUMENTS_BAD
;
1346 for (i
= 0; i
< mechs_len
; i
++)
1347 if (mechs
[i
] == pMechanism
->mechanism
)
1349 if (i
== mechs_len
) {
1350 application_error("called mech (%08lx) not supported\n",
1351 pMechanism
->mechanism
);
1352 return CKR_ARGUMENTS_BAD
;
1359 dup_mechanism(CK_MECHANISM_PTR
*dup
, const CK_MECHANISM_PTR pMechanism
)
1363 p
= malloc(sizeof(*p
));
1365 return CKR_DEVICE_MEMORY
;
1370 memcpy(p
, pMechanism
, sizeof(*p
));
1378 C_EncryptInit(CK_SESSION_HANDLE hSession
,
1379 CK_MECHANISM_PTR pMechanism
,
1380 CK_OBJECT_HANDLE hKey
)
1382 struct session_state
*state
;
1383 CK_MECHANISM_TYPE mechs
[] = { CKM_RSA_PKCS
};
1384 CK_BBOOL bool_true
= CK_TRUE
;
1385 CK_ATTRIBUTE attr
[] = {
1386 { CKA_ENCRYPT
, &bool_true
, sizeof(bool_true
) }
1388 struct st_object
*o
;
1393 st_logf("EncryptInit\n");
1394 VERIFY_SESSION_HANDLE(hSession
, &state
);
1396 ret
= commonInit(attr
, sizeof(attr
)/sizeof(attr
[0]),
1397 mechs
, sizeof(mechs
)/sizeof(mechs
[0]),
1398 pMechanism
, hKey
, &o
);
1402 ret
= dup_mechanism(&state
->encrypt_mechanism
, pMechanism
);
1404 state
->encrypt_object
= OBJECT_ID(o
);
1410 C_Encrypt(CK_SESSION_HANDLE hSession
,
1413 CK_BYTE_PTR pEncryptedData
,
1414 CK_ULONG_PTR pulEncryptedDataLen
)
1416 CK_RV ret
= CKR_FUNCTION_NOT_SUPPORTED
;
1418 struct session_state
*state
;
1419 struct st_object
*o
;
1420 void *buffer
= NULL
;
1422 int padding
, len
, buffer_len
, padding_len
;
1426 st_logf("Encrypt\n");
1428 VERIFY_SESSION_HANDLE(hSession
, &state
);
1430 if (state
->encrypt_object
== -1)
1431 return CKR_ARGUMENTS_BAD
;
1433 o
= soft_token
.object
.objs
[state
->encrypt_object
];
1435 if (o
->u
.public_key
== NULL
) {
1436 st_logf("public key NULL\n");
1437 return CKR_ARGUMENTS_BAD
;
1440 rsa
= o
->u
.public_key
->pkey
.rsa
;
1443 return CKR_ARGUMENTS_BAD
;
1445 RSA_blinding_off(rsa
); /* XXX RAND is broken while running in mozilla ? */
1447 buffer_len
= RSA_size(rsa
);
1449 buffer
= malloc(buffer_len
);
1450 if (buffer
== NULL
) {
1451 ret
= CKR_DEVICE_MEMORY
;
1456 switch(state
->encrypt_mechanism
->mechanism
) {
1458 padding
= RSA_PKCS1_PADDING
;
1459 padding_len
= RSA_PKCS1_PADDING_SIZE
;
1462 ret
= CKR_FUNCTION_NOT_SUPPORTED
;
1466 if (buffer_len
+ padding_len
< ulDataLen
) {
1467 ret
= CKR_ARGUMENTS_BAD
;
1471 if (pulEncryptedDataLen
== NULL
) {
1472 st_logf("pulEncryptedDataLen NULL\n");
1473 ret
= CKR_ARGUMENTS_BAD
;
1477 if (pData
== NULL_PTR
) {
1478 st_logf("data NULL\n");
1479 ret
= CKR_ARGUMENTS_BAD
;
1483 len
= RSA_public_encrypt(ulDataLen
, pData
, buffer
, rsa
, padding
);
1485 ret
= CKR_DEVICE_ERROR
;
1488 if (len
> buffer_len
)
1491 if (pEncryptedData
!= NULL_PTR
)
1492 memcpy(pEncryptedData
, buffer
, len
);
1493 *pulEncryptedDataLen
= len
;
1497 memset(buffer
, 0, buffer_len
);
1505 C_EncryptUpdate(CK_SESSION_HANDLE hSession
,
1508 CK_BYTE_PTR pEncryptedPart
,
1509 CK_ULONG_PTR pulEncryptedPartLen
)
1512 st_logf("EncryptUpdate\n");
1513 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1514 return CKR_FUNCTION_NOT_SUPPORTED
;
1519 C_EncryptFinal(CK_SESSION_HANDLE hSession
,
1520 CK_BYTE_PTR pLastEncryptedPart
,
1521 CK_ULONG_PTR pulLastEncryptedPartLen
)
1524 st_logf("EncryptFinal\n");
1525 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1526 return CKR_FUNCTION_NOT_SUPPORTED
;
1530 /* C_DecryptInit initializes a decryption operation. */
1532 C_DecryptInit(CK_SESSION_HANDLE hSession
,
1533 CK_MECHANISM_PTR pMechanism
,
1534 CK_OBJECT_HANDLE hKey
)
1536 struct session_state
*state
;
1537 CK_MECHANISM_TYPE mechs
[] = { CKM_RSA_PKCS
};
1538 CK_BBOOL bool_true
= CK_TRUE
;
1539 CK_ATTRIBUTE attr
[] = {
1540 { CKA_DECRYPT
, &bool_true
, sizeof(bool_true
) }
1542 struct st_object
*o
;
1546 st_logf("DecryptInit\n");
1547 VERIFY_SESSION_HANDLE(hSession
, &state
);
1549 ret
= commonInit(attr
, sizeof(attr
)/sizeof(attr
[0]),
1550 mechs
, sizeof(mechs
)/sizeof(mechs
[0]),
1551 pMechanism
, hKey
, &o
);
1555 ret
= dup_mechanism(&state
->decrypt_mechanism
, pMechanism
);
1557 state
->decrypt_object
= OBJECT_ID(o
);
1564 C_Decrypt(CK_SESSION_HANDLE hSession
,
1565 CK_BYTE_PTR pEncryptedData
,
1566 CK_ULONG ulEncryptedDataLen
,
1568 CK_ULONG_PTR pulDataLen
)
1570 CK_RV ret
= CKR_FUNCTION_NOT_SUPPORTED
;
1572 struct session_state
*state
;
1573 struct st_object
*o
;
1574 void *buffer
= NULL
;
1576 int padding
, len
, buffer_len
, padding_len
;
1579 st_logf("Decrypt\n");
1581 VERIFY_SESSION_HANDLE(hSession
, &state
);
1583 if (state
->decrypt_object
== -1)
1584 return CKR_ARGUMENTS_BAD
;
1586 o
= soft_token
.object
.objs
[state
->decrypt_object
];
1588 if (o
->u
.private_key
.key
== NULL
) {
1589 st_logf("private key NULL\n");
1590 return CKR_ARGUMENTS_BAD
;
1593 rsa
= o
->u
.private_key
.key
->pkey
.rsa
;
1596 return CKR_ARGUMENTS_BAD
;
1598 RSA_blinding_off(rsa
); /* XXX RAND is broken while running in mozilla ? */
1600 buffer_len
= RSA_size(rsa
);
1602 buffer
= malloc(buffer_len
);
1603 if (buffer
== NULL
) {
1604 ret
= CKR_DEVICE_MEMORY
;
1609 switch(state
->decrypt_mechanism
->mechanism
) {
1611 padding
= RSA_PKCS1_PADDING
;
1612 padding_len
= RSA_PKCS1_PADDING_SIZE
;
1615 ret
= CKR_FUNCTION_NOT_SUPPORTED
;
1619 if (buffer_len
+ padding_len
< ulEncryptedDataLen
) {
1620 ret
= CKR_ARGUMENTS_BAD
;
1624 if (pulDataLen
== NULL
) {
1625 st_logf("pulDataLen NULL\n");
1626 ret
= CKR_ARGUMENTS_BAD
;
1630 if (pEncryptedData
== NULL_PTR
) {
1631 st_logf("data NULL\n");
1632 ret
= CKR_ARGUMENTS_BAD
;
1636 len
= RSA_private_decrypt(ulEncryptedDataLen
, pEncryptedData
, buffer
,
1639 ret
= CKR_DEVICE_ERROR
;
1642 if (len
> buffer_len
)
1645 if (pData
!= NULL_PTR
)
1646 memcpy(pData
, buffer
, len
);
1651 memset(buffer
, 0, buffer_len
);
1660 C_DecryptUpdate(CK_SESSION_HANDLE hSession
,
1661 CK_BYTE_PTR pEncryptedPart
,
1662 CK_ULONG ulEncryptedPartLen
,
1664 CK_ULONG_PTR pulPartLen
)
1667 st_logf("DecryptUpdate\n");
1669 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1670 return CKR_FUNCTION_NOT_SUPPORTED
;
1675 C_DecryptFinal(CK_SESSION_HANDLE hSession
,
1676 CK_BYTE_PTR pLastPart
,
1677 CK_ULONG_PTR pulLastPartLen
)
1679 st_logf("DecryptFinal\n");
1681 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1682 return CKR_FUNCTION_NOT_SUPPORTED
;
1687 C_DigestInit(CK_SESSION_HANDLE hSession
,
1688 CK_MECHANISM_PTR pMechanism
)
1690 st_logf("DigestInit\n");
1692 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1693 return CKR_FUNCTION_NOT_SUPPORTED
;
1697 C_SignInit(CK_SESSION_HANDLE hSession
,
1698 CK_MECHANISM_PTR pMechanism
,
1699 CK_OBJECT_HANDLE hKey
)
1701 struct session_state
*state
;
1702 CK_MECHANISM_TYPE mechs
[] = { CKM_RSA_PKCS
};
1703 CK_BBOOL bool_true
= CK_TRUE
;
1704 CK_ATTRIBUTE attr
[] = {
1705 { CKA_SIGN
, &bool_true
, sizeof(bool_true
) }
1707 struct st_object
*o
;
1711 st_logf("SignInit\n");
1712 VERIFY_SESSION_HANDLE(hSession
, &state
);
1714 ret
= commonInit(attr
, sizeof(attr
)/sizeof(attr
[0]),
1715 mechs
, sizeof(mechs
)/sizeof(mechs
[0]),
1716 pMechanism
, hKey
, &o
);
1720 ret
= dup_mechanism(&state
->sign_mechanism
, pMechanism
);
1722 state
->sign_object
= OBJECT_ID(o
);
1728 C_Sign(CK_SESSION_HANDLE hSession
,
1731 CK_BYTE_PTR pSignature
,
1732 CK_ULONG_PTR pulSignatureLen
)
1734 struct session_state
*state
;
1735 struct st_object
*o
;
1738 const AlgorithmIdentifier
*alg
;
1739 heim_octet_string sig
, data
;
1743 VERIFY_SESSION_HANDLE(hSession
, &state
);
1748 if (state
->sign_object
== -1)
1749 return CKR_ARGUMENTS_BAD
;
1751 if (pulSignatureLen
== NULL
) {
1752 st_logf("signature len NULL\n");
1753 ret
= CKR_ARGUMENTS_BAD
;
1757 if (pData
== NULL_PTR
) {
1758 st_logf("data NULL\n");
1759 ret
= CKR_ARGUMENTS_BAD
;
1763 o
= soft_token
.object
.objs
[state
->sign_object
];
1765 if (hx509_cert_have_private_key(o
->cert
) == 0) {
1766 st_logf("private key NULL\n");
1767 return CKR_ARGUMENTS_BAD
;
1770 switch(state
->sign_mechanism
->mechanism
) {
1772 alg
= hx509_signature_rsa_pkcs1_x509();
1775 ret
= CKR_FUNCTION_NOT_SUPPORTED
;
1780 data
.length
= ulDataLen
;
1782 hret
= _hx509_create_signature(context
,
1783 _hx509_cert_private_key(o
->cert
),
1789 ret
= CKR_DEVICE_ERROR
;
1792 *pulSignatureLen
= sig
.length
;
1794 if (pSignature
!= NULL_PTR
)
1795 memcpy(pSignature
, sig
.data
, sig
.length
);
1800 memset(sig
.data
, 0, sig
.length
);
1801 der_free_octet_string(&sig
);
1807 C_SignUpdate(CK_SESSION_HANDLE hSession
,
1812 st_logf("SignUpdate\n");
1813 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1814 return CKR_FUNCTION_NOT_SUPPORTED
;
1819 C_SignFinal(CK_SESSION_HANDLE hSession
,
1820 CK_BYTE_PTR pSignature
,
1821 CK_ULONG_PTR pulSignatureLen
)
1824 st_logf("SignUpdate\n");
1825 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1826 return CKR_FUNCTION_NOT_SUPPORTED
;
1830 C_VerifyInit(CK_SESSION_HANDLE hSession
,
1831 CK_MECHANISM_PTR pMechanism
,
1832 CK_OBJECT_HANDLE hKey
)
1834 struct session_state
*state
;
1835 CK_MECHANISM_TYPE mechs
[] = { CKM_RSA_PKCS
};
1836 CK_BBOOL bool_true
= CK_TRUE
;
1837 CK_ATTRIBUTE attr
[] = {
1838 { CKA_VERIFY
, &bool_true
, sizeof(bool_true
) }
1840 struct st_object
*o
;
1844 st_logf("VerifyInit\n");
1845 VERIFY_SESSION_HANDLE(hSession
, &state
);
1847 ret
= commonInit(attr
, sizeof(attr
)/sizeof(attr
[0]),
1848 mechs
, sizeof(mechs
)/sizeof(mechs
[0]),
1849 pMechanism
, hKey
, &o
);
1853 ret
= dup_mechanism(&state
->verify_mechanism
, pMechanism
);
1855 state
->verify_object
= OBJECT_ID(o
);
1861 C_Verify(CK_SESSION_HANDLE hSession
,
1864 CK_BYTE_PTR pSignature
,
1865 CK_ULONG ulSignatureLen
)
1867 struct session_state
*state
;
1868 struct st_object
*o
;
1869 const AlgorithmIdentifier
*alg
;
1872 heim_octet_string data
, sig
;
1875 st_logf("Verify\n");
1876 VERIFY_SESSION_HANDLE(hSession
, &state
);
1878 if (state
->verify_object
== -1)
1879 return CKR_ARGUMENTS_BAD
;
1881 o
= soft_token
.object
.objs
[state
->verify_object
];
1883 switch(state
->verify_mechanism
->mechanism
) {
1885 alg
= hx509_signature_rsa_pkcs1_x509();
1888 ret
= CKR_FUNCTION_NOT_SUPPORTED
;
1893 sig
.length
= ulDataLen
;
1894 data
.data
= pSignature
;
1895 data
.length
= ulSignatureLen
;
1897 hret
= _hx509_verify_signature(context
,
1898 _hx509_get_cert(o
->cert
),
1903 ret
= CKR_GENERAL_ERROR
;
1914 C_VerifyUpdate(CK_SESSION_HANDLE hSession
,
1919 st_logf("VerifyUpdate\n");
1920 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1921 return CKR_FUNCTION_NOT_SUPPORTED
;
1925 C_VerifyFinal(CK_SESSION_HANDLE hSession
,
1926 CK_BYTE_PTR pSignature
,
1927 CK_ULONG ulSignatureLen
)
1930 st_logf("VerifyFinal\n");
1931 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1932 return CKR_FUNCTION_NOT_SUPPORTED
;
1936 C_GenerateRandom(CK_SESSION_HANDLE hSession
,
1937 CK_BYTE_PTR RandomData
,
1938 CK_ULONG ulRandomLen
)
1941 st_logf("GenerateRandom\n");
1942 VERIFY_SESSION_HANDLE(hSession
, NULL
);
1943 return CKR_FUNCTION_NOT_SUPPORTED
;
1947 CK_FUNCTION_LIST funcs
= {
1959 (void *)func_not_supported
, /* C_InitPIN */
1960 (void *)func_not_supported
, /* C_SetPIN */
1965 (void *)func_not_supported
, /* C_GetOperationState */
1966 (void *)func_not_supported
, /* C_SetOperationState */
1969 (void *)func_not_supported
, /* C_CreateObject */
1970 (void *)func_not_supported
, /* C_CopyObject */
1971 (void *)func_not_supported
, /* C_DestroyObject */
1972 (void *)func_not_supported
, /* C_GetObjectSize */
1973 C_GetAttributeValue
,
1974 (void *)func_not_supported
, /* C_SetAttributeValue */
1978 (void *)func_not_supported
, /* C_EncryptInit, */
1979 (void *)func_not_supported
, /* C_Encrypt, */
1980 (void *)func_not_supported
, /* C_EncryptUpdate, */
1981 (void *)func_not_supported
, /* C_EncryptFinal, */
1982 (void *)func_not_supported
, /* C_DecryptInit, */
1983 (void *)func_not_supported
, /* C_Decrypt, */
1984 (void *)func_not_supported
, /* C_DecryptUpdate, */
1985 (void *)func_not_supported
, /* C_DecryptFinal, */
1987 (void *)func_not_supported
, /* C_Digest */
1988 (void *)func_not_supported
, /* C_DigestUpdate */
1989 (void *)func_not_supported
, /* C_DigestKey */
1990 (void *)func_not_supported
, /* C_DigestFinal */
1995 (void *)func_not_supported
, /* C_SignRecoverInit */
1996 (void *)func_not_supported
, /* C_SignRecover */
2001 (void *)func_not_supported
, /* C_VerifyRecoverInit */
2002 (void *)func_not_supported
, /* C_VerifyRecover */
2003 (void *)func_not_supported
, /* C_DigestEncryptUpdate */
2004 (void *)func_not_supported
, /* C_DecryptDigestUpdate */
2005 (void *)func_not_supported
, /* C_SignEncryptUpdate */
2006 (void *)func_not_supported
, /* C_DecryptVerifyUpdate */
2007 (void *)func_not_supported
, /* C_GenerateKey */
2008 (void *)func_not_supported
, /* C_GenerateKeyPair */
2009 (void *)func_not_supported
, /* C_WrapKey */
2010 (void *)func_not_supported
, /* C_UnwrapKey */
2011 (void *)func_not_supported
, /* C_DeriveKey */
2012 (void *)func_not_supported
, /* C_SeedRandom */
2014 (void *)func_not_supported
, /* C_GetFunctionStatus */
2015 (void *)func_not_supported
, /* C_CancelFunction */
2016 (void *)func_not_supported
/* C_WaitForSlotEvent */