summaryrefslogtreecommitdiff
path: root/security/nss/lib/fortcrypt/fortpk11.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/fortcrypt/fortpk11.c')
-rw-r--r--security/nss/lib/fortcrypt/fortpk11.c4544
1 files changed, 0 insertions, 4544 deletions
diff --git a/security/nss/lib/fortcrypt/fortpk11.c b/security/nss/lib/fortcrypt/fortpk11.c
deleted file mode 100644
index 076db666e..000000000
--- a/security/nss/lib/fortcrypt/fortpk11.c
+++ /dev/null
@@ -1,4544 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- *
- * This file implements PKCS 11 for FORTEZZA using MACI
- * drivers. Except for the Mac. They only have CI libraries, so
- * that's what we use there.
- *
- * For more information about PKCS 11 See PKCS 11 Token Inteface Standard.
- *
- * This implementations queries the MACI to figure out how
- * many slots exist on a given system. There is an artificial boundary
- * of 32 slots, because allocating slots dynamically caused memory
- * problems in the client when first this module was first developed.
- * Some how the heap was being corrupted and we couldn't find out where.
- * Subsequent attempts to allocate dynamic memory caused no problem.
- *
- * In this implementation, session objects are only visible to the session
- * that created or generated them.
- */
-
-#include "fpkmem.h"
-#include "seccomon.h"
-#include "fpkcs11.h"
-#include "fpkcs11i.h"
-#include "cryptint.h"
-#include "pk11func.h"
-#include "fortsock.h"
-#include "fmutex.h"
-#ifdef notdef
-#include <ctype.h>
-#include <stdio.h>
-#endif
-#ifdef XP_MAC
-#ifndef __POWERPC__
-#include <A4Stuff.h>
-#endif
-/* This is not a 4.0 project, so I can't depend on
- * 4.0 defines, so instead I depend on CodeWarrior
- * defines. I define XP_MAC in fpkmem.h
- */
-#if __POWERPC__
-#elif __CFM68K__
-#else
-/* These include are taken fromn npmac.cpp which are used
- * by the plugin group to properly set-up a plug-in for
- * dynamic loading on 68K.
- */
-
-#include <Quickdraw.h>
-
-/*
-** The Mixed Mode procInfos defined in npupp.h assume Think C-
-** style calling conventions. These conventions are used by
-** Metrowerks with the exception of pointer return types, which
-** in Metrowerks 68K are returned in A0, instead of the standard
-** D0. Thus, since NPN_MemAlloc and NPN_UserAgent return pointers,
-** Mixed Mode will return the values to a 68K plugin in D0, but
-** a 68K plugin compiled by Metrowerks will expect the result in
-** A0. The following pragma forces Metrowerks to use D0 instead.
-*/
-#ifdef __MWERKS__
-#ifndef powerc
-#pragma pointers_in_D0
-#endif
-#endif
-
-#ifdef __MWERKS__
-#ifndef powerc
-#pragma pointers_in_A0
-#endif
-#endif
-
-/* The following fix for static initializers fixes a previous
-** incompatibility with some parts of PowerPlant.
-*/
-#ifdef __MWERKS__
-#ifdef __cplusplus
- extern "C" {
-#endif
-#ifndef powerc
- extern void __InitCode__(void);
-#else
- extern void __sinit(void);
-#endif
- extern void __destroy_global_chain(void);
-#ifdef __cplusplus
- }
-#endif /* __cplusplus */
-#endif /* __MWERKS__ */
-
-#endif
-#endif
-
-
-typedef struct {
- unsigned char *data;
- int len;
-} CertItem;
-
-
-/*
- * ******************** Static data *******************************
- */
-
-/* The next three strings must be exactly 32 characters long */
-static char *manufacturerID = "Netscape Communications Corp ";
-static char *libraryDescription = "Communicator Fortezza Crypto Svc";
-
-typedef enum {DSA_KEY, KEA_KEY, V1_KEY, INVALID_KEY } PrivKeyType;
-
-static PK11Slot fort11_slot[NUM_SLOTS];
-static FortezzaSocket fortezzaSockets[NUM_SLOTS];
-static PRBool init = PR_FALSE;
-static CK_ULONG kNumSockets = 0;
-
-#define __PASTE(x,y) x##y
-
-
-#undef CK_FUNC
-#undef CK_EXTERN
-#undef CK_NEED_ARG_LIST
-#undef _CK_RV
-
-#define fort11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen
-#define fort11_SlotFromSession pk11_SlotFromSession
-#define fort11_isToken pk11_isToken
-
-static CK_FUNCTION_LIST fort11_funcList = {
- { 2, 1 },
-
-#undef CK_FUNC
-#undef CK_EXTERN
-#undef CK_NEED_ARG_LIST
-#undef _CK_RV
-
-#define CK_EXTERN
-#define CK_FUNC(name) name,
-#define _CK_RV
-
-#include "fpkcs11f.h"
-
-};
-
-#undef CK_FUNC
-#undef CK_EXTERN
-#undef _CK_RV
-
-
-#undef __PASTE
-#undef pk11_SlotFromSessionHandle
-#undef pk11_SlotFromID
-
-#define MAJOR_VERSION_MASK 0xFF00
-#define MINOR_VERSION_MASK 0x00FF
-
-/* Mechanisms */
-struct mechanismList {
- CK_MECHANISM_TYPE type;
- CK_MECHANISM_INFO domestic;
- PRBool privkey;
-};
-
-static struct mechanismList mechanisms[] = {
- {CKM_DSA, {512,1024,CKF_SIGN}, PR_TRUE},
- {CKM_SKIPJACK_KEY_GEN, {92, 92, CKF_GENERATE}, PR_TRUE},
- {CKM_SKIPJACK_CBC64, {92, 92, CKF_ENCRYPT | CKF_DECRYPT}, PR_TRUE},
- {CKM_SKIPJACK_WRAP, {92, 92, CKF_WRAP}, PR_TRUE},
- {CKM_KEA_KEY_DERIVE, {128, 128, CKF_DERIVE}, PR_TRUE},
-};
-static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
-
-/*************Static function prototypes********************************/
-static PRBool fort11_isTrue(PK11Object *object,CK_ATTRIBUTE_TYPE type);
-static void fort11_FreeAttribute(PK11Attribute *attribute);
-static void fort11_DestroyAttribute(PK11Attribute *attribute);
-static PK11Object* fort11_NewObject(PK11Slot *slot);
-static PK11FreeStatus fort11_FreeObject(PK11Object *object);
-static CK_RV fort11_AddAttributeType(PK11Object *object,
- CK_ATTRIBUTE_TYPE type,
- void *valPtr,
- CK_ULONG length);
-static void fort11_AddSlotObject(PK11Slot *slot, PK11Object *object);
-static PK11Attribute* fort11_FindAttribute(PK11Object *object,
- CK_ATTRIBUTE_TYPE type);
-static PK11Attribute* fort11_NewAttribute(CK_ATTRIBUTE_TYPE type,
- CK_VOID_PTR value, CK_ULONG len);
-static void fort11_DeleteAttributeType(PK11Object *object,
- CK_ATTRIBUTE_TYPE type);
-static void fort11_AddAttribute(PK11Object *object,
- PK11Attribute *attribute);
-static void fort11_AddObject(PK11Session *session,
- PK11Object *object);
-static PK11Object * fort11_ObjectFromHandle(CK_OBJECT_HANDLE handle,
- PK11Session *session);
-static void fort11_DeleteObject(PK11Session *session,PK11Object *object);
-static CK_RV fort11_DestroyObject(PK11Object *object);
-void fort11_FreeSession(PK11Session *session);
-
-#define FIRST_SLOT_SESS_ID 0x00000100L
-#define ADD_NEXT_SESS_ID 0x00000100L
-#define SLOT_MASK 0x000000FFL
-
-#define FAILED CKR_FUNCTION_FAILED
-
-static void
-fort11_FreeFortezzaKey (void *inFortezzaKey) {
- RemoveKey ((FortezzaKey*) inFortezzaKey);
-}
-
-static void
-fort11_DestroySlotObjects (PK11Slot *slot, PK11Session *session) {
- PK11Object *currObject, *nextObject, *oldObject;
- int i;
-
- for (i=0; i<HASH_SIZE; i++) {
- currObject = slot->tokObjects[i];
- slot->tokObjects[i] = NULL;
- do {
- FMUTEX_Lock(slot->sessionLock);
-
- if (currObject) {
- nextObject = currObject->next;
- FMUTEX_Lock(currObject->refLock);
- currObject->refCount++;
- FMUTEX_Unlock(currObject->refLock);
- fort11_DeleteObject(session, currObject);
- }
- FMUTEX_Unlock(slot->sessionLock);
- if (currObject) {
- oldObject = currObject;
- currObject = nextObject;
- fort11_FreeObject(oldObject);
- }
- } while (currObject != NULL);
- }
-}
-
-static void
-fort11_TokenRemoved(PK11Slot *slot, PK11Session *session) {
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
-
- LogoutFromSocket (socket);
- slot->isLoggedIn = PR_FALSE;
- if (session && session->notify) {
- /*If no session pointer exists, lots of leaked memory*/
- session->notify (session->handle, CKN_SURRENDER,
- session->appData);
- fort11_FreeSession(session); /* Release the reference held
- * by the slot with the session
- */
- }
-
- fort11_DestroySlotObjects(slot, session);
- fort11_FreeSession(session); /* Release the reference held
- * by the slot with the session
- */
-
- /* All keys will have been freed at this point so we can
- * NULL out this pointer
- */
- socket->keys = NULL;
-
-}
-
-PRBool
-fort11_FortezzaIsUserCert(unsigned char * label) {
-
- if ( (!PORT_Memcmp(label, "KEAK", 4)) || /* v3 user certs */
- (!PORT_Memcmp(label, "DSA1", 4)) ||
- (!PORT_Memcmp(label, "DSAI", 4)) ||
- (!PORT_Memcmp(label, "DSAO", 4)) ||
- (!PORT_Memcmp(label, "INKS", 4)) || /* v1 user certs */
- (!PORT_Memcmp(label, "INKX", 4)) ||
- (!PORT_Memcmp(label, "ONKS", 4)) ||
- (!PORT_Memcmp(label, "ONKX", 4)) ||
- (!PORT_Memcmp(label, "3IXS", 4)) || /* old v3 user certs */
- (!PORT_Memcmp(label, "3OXS", 4)) ||
- (!PORT_Memcmp(label, "3IKX", 4)) ) {
-
- return PR_TRUE;
-
- } else { return PR_FALSE; }
-
-}
-
-static PRBool
-fort11_FortezzaIsACert(unsigned char * label) {
- if (label == NULL) return PR_FALSE;
-
- if ( (!PORT_Memcmp(label, "DSA1", 4)) || /* v3 certs */
- (!PORT_Memcmp(label, "DSAI", 4)) ||
- (!PORT_Memcmp(label, "DSAO", 4)) ||
- (!PORT_Memcmp(label, "DSAX", 4)) ||
- (!PORT_Memcmp(label, "KEAK", 4)) ||
- (!PORT_Memcmp(label, "KEAX", 4)) ||
- (!PORT_Memcmp(label, "CAX1", 4)) ||
- (!PORT_Memcmp(label, "PCA1", 4)) ||
- (!PORT_Memcmp(label, "PAA1", 4)) ||
- (!PORT_Memcmp(label, "ICA1", 4)) ||
-
- (!PORT_Memcmp(label, "3IXS", 4)) || /* old v3 certs */
- (!PORT_Memcmp(label, "3OXS", 4)) ||
- (!PORT_Memcmp(label, "3CAX", 4)) ||
- (!PORT_Memcmp(label, "3IKX", 4)) ||
- (!PORT_Memcmp(label, "3PCA", 4)) ||
- (!PORT_Memcmp(label, "3PAA", 4)) ||
- (!PORT_Memcmp(label, "3ICA", 4)) ||
-
- (!PORT_Memcmp(label, "INKS", 4)) || /* v1 certs */
- (!PORT_Memcmp(label, "INKX", 4)) ||
- (!PORT_Memcmp(label, "ONKS", 4)) ||
- (!PORT_Memcmp(label, "ONKX", 4)) ||
- (!PORT_Memcmp(label, "RRXX", 4)) ||
- (!PORT_Memcmp(label, "RTXX", 4)) ||
- (!PORT_Memcmp(label, "LAXX", 4)) ) {
-
- return PR_TRUE;
-
- }
-
- return PR_FALSE;
-}
-
-static
-int fort11_cert_length(unsigned char *buf, int length) {
- unsigned char tag;
- int used_length= 0;
- int data_length;
-
- tag = buf[used_length++];
-
- /* blow out when we come to the end */
- if (tag == 0) {
- return 0;
- }
-
- data_length = buf[used_length++];
-
- if (data_length&0x80) {
- int len_count = data_length & 0x7f;
-
- data_length = 0;
-
- while (len_count-- > 0) {
- data_length = (data_length << 8) | buf[used_length++];
- }
- }
-
- if (data_length > (length-used_length) ) {
- return length;
- }
-
- return (data_length + used_length);
-}
-
-unsigned char *fort11_data_start(unsigned char *buf, int length,
- int *data_length, PRBool includeTag) {
- unsigned char tag;
- int used_length= 0;
-
- tag = buf[used_length++];
-
- /* blow out when we come to the end */
- if (tag == 0) {
- return NULL;
- }
-
- *data_length = buf[used_length++];
-
- if (*data_length&0x80) {
- int len_count = *data_length & 0x7f;
-
- *data_length = 0;
-
- while (len_count-- > 0) {
- *data_length = (*data_length << 8) | buf[used_length++];
- }
- }
-
- if (*data_length > (length-used_length) ) {
- *data_length = length-used_length;
- return NULL;
- }
- if (includeTag) *data_length += used_length;
-
- return (buf + (includeTag ? 0 : used_length));
-}
-
-int
-fort11_GetCertFields(unsigned char *cert,int cert_length,CertItem *issuer,
- CertItem *serial,CertItem *subject)
-{
- unsigned char *buf;
- int buf_length;
- unsigned char *date;
- int datelen;
-
- /* get past the signature wrap */
- buf = fort11_data_start(cert,cert_length,&buf_length,PR_FALSE);
- if (buf == NULL) return FAILED;
- /* get into the raw cert data */
- buf = fort11_data_start(buf,buf_length,&buf_length,PR_FALSE);
- if (buf == NULL) return FAILED;
- /* skip past any optional version number */
- if ((buf[0] & 0xa0) == 0xa0) {
- date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE);
- if (date == NULL) return FAILED;
- buf_length -= (date-buf) + datelen;
- buf = date + datelen;
- }
- /* serial number */
- serial->data = fort11_data_start(buf,buf_length,&serial->len,PR_FALSE);
- if (serial->data == NULL) return FAILED;
- buf_length -= (serial->data-buf) + serial->len;
- buf = serial->data + serial->len;
- /* skip the OID */
- date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE);
- if (date == NULL) return FAILED;
- buf_length -= (date-buf) + datelen;
- buf = date + datelen;
- /* issuer */
- issuer->data = fort11_data_start(buf,buf_length,&issuer->len,PR_TRUE);
- if (issuer->data == NULL) return FAILED;
- buf_length -= (issuer->data-buf) + issuer->len;
- buf = issuer->data + issuer->len;
- /* skip the date */
- date = fort11_data_start(buf,buf_length,&datelen,PR_FALSE);
- if (date == NULL) return FAILED;
- buf_length -= (date-buf) + datelen;
- buf = date + datelen;
- /*subject */
- subject->data=fort11_data_start(buf,buf_length,&subject->len,PR_TRUE);
- if (subject->data == NULL) return FAILED;
- buf_length -= (subject->data-buf) + subject->len;
- buf = subject->data +subject->len;
- /*subject */
- return CKR_OK;
-}
-
-/* quick tohex function to get rid of scanf */
-static
-int fort11_tohex(char *s) {
- int val = 0;
-
- for(;*s;s++) {
- if ((*s >= '0') && (*s <= '9')) {
- val = (val << 4) + (*s - '0');
- continue;
- } else if ((*s >= 'a') && (*s <= 'f')) {
- val = (val << 4) + (*s - 'a') + 10;
- continue;
- } else if ((*s >= 'A') && (*s <= 'F')) {
- val = (val << 4) + (*s - 'A') + 10;
- continue;
- }
- break;
- }
- return val;
-}
-
-/* only should be called for V3 KEA cert labels. */
-
-static int
-fort11_GetSibling(CI_CERT_STR label) {
-
- int value = 0;
- char s[3];
-
- label +=4;
-
- strcpy(s,"00");
- memcpy(s, label, 2);
- value = fort11_tohex(s);
-
- /* sibling of 255 means no sibling */
- if (value == 255) {
- value = -1;
- }
-
- return value;
-}
-
-
-static PrivKeyType
-fort11_GetKeyType(CI_CERT_STR label) {
- if (label == NULL) return INVALID_KEY;
-
- if ( (!PORT_Memcmp(label, "DSA1", 4)) || /* v3 certs */
- (!PORT_Memcmp(label, "DSAI", 4)) ||
- (!PORT_Memcmp(label, "DSAO", 4)) ||
- (!PORT_Memcmp(label, "3IXS", 4)) || /* old v3 certs */
- (!PORT_Memcmp(label, "3OXS", 4)) ) {
-
- return DSA_KEY;
- }
-
-
- if ( (!PORT_Memcmp(label, "KEAK", 4)) ||
- (!PORT_Memcmp(label, "3IKX", 4)) ) {
- return KEA_KEY;
- }
-
- if ( (!PORT_Memcmp(label, "INKS", 4)) || /* V1 Certs*/
- (!PORT_Memcmp(label, "INKX", 4)) ||
- (!PORT_Memcmp(label, "ONKS", 4)) ||
- (!PORT_Memcmp(label, "ONKX", 4)) ||
- (!PORT_Memcmp(label, "RRXX", 4)) ||
- (!PORT_Memcmp(label, "RTXX", 4)) ||
- (!PORT_Memcmp(label, "LAXX", 4)) ) {
-
- return V1_KEY;
- }
-
- return INVALID_KEY;
-}
-
-static CK_RV
-fort11_ConvertToDSAKey(PK11Object *privateKey, PK11Slot *slot) {
- CK_KEY_TYPE key_type = CKK_DSA;
- CK_BBOOL cktrue = TRUE;
- CK_BBOOL ckfalse = FALSE;
- CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
- CK_CHAR label[] = "A DSA Private Key";
-
-
- /* Fill in the common Default values */
- if (fort11_AddAttributeType(privateKey,CKA_START_DATE, NULL, 0) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey,CKA_END_DATE, NULL, 0) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey,CKA_SUBJECT, NULL, 0) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_CLASS, &privClass,
- sizeof (CK_OBJECT_CLASS)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_KEY_TYPE, &key_type,
- sizeof(CK_KEY_TYPE)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType (privateKey, CKA_TOKEN, &cktrue,
- sizeof (CK_BBOOL)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType (privateKey, CKA_LABEL, label,
- PORT_Strlen((char*)label)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_SENSITIVE, &cktrue,
- sizeof (CK_BBOOL)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_SIGN, &cktrue,
- sizeof (CK_BBOOL)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- if (fort11_AddAttributeType(privateKey, CKA_DERIVE, &cktrue,
- sizeof(cktrue)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_LOCAL, &ckfalse,
- sizeof(ckfalse)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_DECRYPT, &ckfalse,
- sizeof(ckfalse)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_SIGN_RECOVER, &ckfalse,
- sizeof(ckfalse)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_UNWRAP, &ckfalse,
- sizeof(ckfalse)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_EXTRACTABLE, &ckfalse,
- sizeof(ckfalse)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_ALWAYS_SENSITIVE, &cktrue,
- sizeof(cktrue)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_NEVER_EXTRACTABLE, &cktrue,
- sizeof(ckfalse)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_PRIME, NULL, 0) != CKR_OK){
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_SUBPRIME, NULL, 0) != CKR_OK){
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_BASE, NULL, 0) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_VALUE, NULL, 0) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_PRIVATE, &cktrue,
- sizeof(cktrue)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_MODIFIABLE,&ckfalse,
- sizeof(ckfalse)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- FMUTEX_Lock(slot->objectLock);
- privateKey->handle = slot->tokenIDCount++;
- privateKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- FMUTEX_Unlock(slot->objectLock);
- privateKey->objclass = privClass;
- privateKey->slot = slot;
- privateKey->inDB = PR_TRUE;
-
-
- return CKR_OK;
-}
-
-static int
-fort11_LoadRootPAAKey(PK11Slot *slot, PK11Session *session) {
- CK_OBJECT_CLASS theClass = CKO_SECRET_KEY;
- int id = 0;
- CK_BBOOL True = TRUE;
- CK_BBOOL False = FALSE;
- CK_CHAR label[] = "Trusted Root PAA Key";
- PK11Object *rootKey;
- FortezzaKey *newKey;
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
-
- /*Don't know the key type. Does is matter?*/
-
- rootKey = fort11_NewObject(slot);
-
- if (rootKey == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- if (fort11_AddAttributeType(rootKey, CKA_CLASS, &theClass,
- sizeof(theClass)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- if (fort11_AddAttributeType(rootKey, CKA_TOKEN, &True,
- sizeof(True)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- if (fort11_AddAttributeType(rootKey, CKA_LABEL, label,
- sizeof(label)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- if (fort11_AddAttributeType(rootKey, CKA_PRIVATE, &True,
- sizeof (True)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- if (fort11_AddAttributeType(rootKey,CKA_MODIFIABLE, &False,
- sizeof(False)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- if (fort11_AddAttributeType(rootKey, CKA_ID, &id,
- sizeof(int)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- if (fort11_AddAttributeType(rootKey, CKA_DERIVE, &True,
- sizeof(True)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- if (fort11_AddAttributeType(rootKey, CKA_SENSITIVE, &True,
- sizeof(True)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- FMUTEX_Lock(slot->objectLock);
- rootKey->handle = slot->tokenIDCount++;
- rootKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- FMUTEX_Unlock(slot->objectLock);
-
- rootKey->objclass = theClass;
- rootKey->slot = slot;
- rootKey->inDB = PR_TRUE;
-
- newKey = NewFortezzaKey(socket, Ks, NULL, 0);
- if (newKey == NULL) {
- fort11_FreeObject(rootKey);
- return CKR_HOST_MEMORY;
- }
-
- rootKey->objectInfo = (void*)newKey;
- rootKey->infoFree = fort11_FreeFortezzaKey;
- fort11_AddObject(session, rootKey);
-
- return CKR_OK;
-}
-
-static CK_RV
-fort11_ConvertToKEAKey (PK11Object *privateKey, PK11Slot *slot) {
- CK_OBJECT_CLASS theClass = CKO_PRIVATE_KEY;
- CK_KEY_TYPE keyType = CKK_KEA;
- CK_CHAR label[] = "A KEA private key Object";
- CK_BBOOL True = TRUE;
- CK_BBOOL False = FALSE;
-
- if (fort11_AddAttributeType(privateKey, CKA_CLASS, &theClass,
- sizeof (CK_OBJECT_CLASS)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_KEY_TYPE, &keyType,
- sizeof (CK_KEY_TYPE)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_TOKEN, &True,
- sizeof(CK_BBOOL)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType (privateKey, CKA_LABEL, label,
- PORT_Strlen((char*)label)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType (privateKey, CKA_SENSITIVE,
- &True, sizeof(CK_BBOOL)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType (privateKey, CKA_DERIVE,
- &True, sizeof(CK_BBOOL)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_PRIVATE, &True,
- sizeof(True)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_START_DATE, NULL, 0) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_END_DATE, NULL, 0) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- if (fort11_AddAttributeType(privateKey, CKA_LOCAL, &False,
- sizeof(False)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- FMUTEX_Lock(slot->objectLock);
- privateKey->handle = slot->tokenIDCount++;
- privateKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- FMUTEX_Unlock(slot->objectLock);
- privateKey->objclass = theClass;
- privateKey->slot = slot;
- privateKey->inDB = PR_TRUE;
-
- return CKR_OK;
-}
-
-static CK_RV
-fort11_ConvertToV1Key (PK11Object* privateKey, PK11Slot *slot) {
- CK_RV rv;
- CK_BBOOL True = TRUE;
-
- rv = fort11_ConvertToDSAKey(privateKey, slot);
- if (rv != CKR_OK) {
- return rv;
- }
-
- if (fort11_AddAttributeType(privateKey, CKA_DERIVE, &True,
- sizeof (CK_BBOOL)) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- return CKR_OK;
-}
-
-static CK_RV
-fort11_NewPrivateKey(PK11Object *privKeyObject, PK11Slot *slot,CI_PERSON currPerson) {
- PrivKeyType keyType = fort11_GetKeyType(currPerson.CertLabel);
- CK_RV rv;
-
- switch (keyType) {
- case DSA_KEY:
- rv = fort11_ConvertToDSAKey(privKeyObject, slot);
- break;
- case KEA_KEY:
- rv = fort11_ConvertToKEAKey(privKeyObject, slot);
- break;
- case V1_KEY:
- rv = fort11_ConvertToV1Key(privKeyObject, slot);
- break;
- default:
- rv = CKR_GENERAL_ERROR;
- break;
- }
- return rv;
-}
-
-
-PRBool
-fort11_LoadCertObjectForSearch(CI_PERSON currPerson, PK11Slot *slot,
- PK11Session *session, CI_PERSON *pers_array) {
- PK11Object *certObject, *privKeyObject;
- PK11Attribute *attribute, *newAttribute;
- int ci_rv;
- CI_CERTIFICATE cert;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_CERTIFICATE_TYPE certType = CKC_X_509;
- CK_BBOOL cktrue = TRUE;
- CK_BBOOL ckfalse = FALSE;
- CertItem issuer, serial, subject;
- int certSize;
- char nickname[50];
- char *cursor;
- PrivKeyType priv_key;
- int sibling;
-
-
- certObject = fort11_NewObject(slot);
- if (certObject == NULL)
- return PR_FALSE;
-
- ci_rv = MACI_GetCertificate (fortezzaSockets[slot->slotID-1].maciSession,
- currPerson.CertificateIndex, cert);
- if (ci_rv != CI_OK){
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
-
- ci_rv = fort11_GetCertFields(cert,CI_CERT_SIZE,&issuer,&serial,&subject);
-
- if (ci_rv != CKR_OK) {
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
-
- if (fort11_AddAttributeType(certObject, CKA_CLASS, &certClass,
- sizeof (CK_OBJECT_CLASS)) != CKR_OK) {
- fort11_FreeObject (certObject);
- return PR_FALSE;
- }
- if (fort11_AddAttributeType(certObject, CKA_TOKEN, &cktrue,
- sizeof (CK_BBOOL)) != CKR_OK) {
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
- if (fort11_AddAttributeType(certObject, CKA_PRIVATE, &ckfalse,
- sizeof (CK_BBOOL)) != CKR_OK) {
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
-
-
- /* check if the label represents a KEA key. if so, the
- nickname should be made the same as the corresponding DSA
- sibling cert. */
-
- priv_key = fort11_GetKeyType(currPerson.CertLabel);
-
- if (priv_key == KEA_KEY) {
- sibling = fort11_GetSibling(currPerson.CertLabel);
-
- /* check for failure of fort11_GetSibling. also check that
- the sibling is not zero. */
-
- if (sibling > 0) {
- /* assign the KEA cert label to be the same as the
- sibling DSA label */
-
- sprintf (nickname, "%s", &pers_array[sibling-1].CertLabel[8] );
- } else {
- sprintf (nickname, "%s", &currPerson.CertLabel[8]);
- }
- } else {
- sprintf (nickname, "%s", &currPerson.CertLabel[8]);
- }
-
- cursor = nickname+PORT_Strlen(nickname)-1;
- while ((*cursor) == ' ') {
- cursor--;
- }
- cursor[1] = '\0';
- if (fort11_AddAttributeType(certObject, CKA_LABEL, nickname,
- PORT_Strlen(nickname)) != CKR_OK) {
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
-
-
-
- if (fort11_AddAttributeType(certObject, CKA_CERTIFICATE_TYPE, &certType,
- sizeof(CK_CERTIFICATE_TYPE)) != CKR_OK) {
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
- certSize = fort11_cert_length(cert,CI_CERT_SIZE);
- if (fort11_AddAttributeType (certObject, CKA_VALUE, cert, certSize)
- != CI_OK) {
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
- if (fort11_AddAttributeType(certObject, CKA_ISSUER, issuer.data,
- issuer.len) != CKR_OK) {
- fort11_FreeObject (certObject);
- return PR_FALSE;
- }
- if (fort11_AddAttributeType(certObject, CKA_SUBJECT, subject.data,
- subject.len) != CKR_OK) {
- fort11_FreeObject (certObject);
- return PR_FALSE;
- }
- if (fort11_AddAttributeType(certObject, CKA_SERIAL_NUMBER,
- serial.data, serial.len) != CKR_OK) {
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
- /*Change this to a byte array later*/
- if (fort11_AddAttributeType(certObject, CKA_ID,
- &currPerson.CertificateIndex,
- sizeof(int)) != CKR_OK) {
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
- certObject->objectInfo = NULL;
- certObject->infoFree = NULL;
-
- certObject->objclass = certClass;
- certObject->slot = slot;
- certObject->inDB = PR_TRUE;
-
- FMUTEX_Lock(slot->objectLock);
-
- certObject->handle = slot->tokenIDCount++;
- certObject->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT);
-
- FMUTEX_Unlock(slot->objectLock);
-
- if (fort11_FortezzaIsUserCert (currPerson.CertLabel)) {
- privKeyObject = fort11_NewObject(slot);
- if (fort11_NewPrivateKey(privKeyObject, slot, currPerson) != CKR_OK) {
- fort11_FreeObject(privKeyObject);
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
- if(fort11_AddAttributeType(privKeyObject,CKA_ID,
- &currPerson.CertificateIndex,
- sizeof(int)) != CKR_OK) {
- fort11_FreeObject(privKeyObject);
- fort11_FreeObject(certObject);
- return PR_FALSE;
- }
- attribute = fort11_FindAttribute(certObject,CKA_SUBJECT);
- newAttribute=
- fort11_NewAttribute(pk11_attr_expand(&attribute->attrib));
- fort11_FreeAttribute(attribute);
- if (newAttribute != NULL) {
- fort11_DeleteAttributeType(privKeyObject,
- CKA_SUBJECT);
- fort11_AddAttribute(privKeyObject,
- newAttribute);
- }
- fort11_AddObject (session, privKeyObject);
- }
-
-
- fort11_AddObject (session, certObject);
-
-
- return PR_TRUE;
-}
-
-#define TRUSTED_PAA "00000000Trusted Root PAA"
-
-static int
-fort11_BuildCertObjects(FortezzaSocket *currSocket, PK11Slot *slot,
- PK11Session *session) {
-
- int i;
- CI_PERSON rootPAA;
-
- PORT_Memcpy (rootPAA.CertLabel, TRUSTED_PAA, 1+PORT_Strlen (TRUSTED_PAA));
- rootPAA.CertificateIndex = 0;
-
- if (!fort11_LoadCertObjectForSearch(rootPAA, slot, session,
- currSocket->personalityList)) {
- return CKR_GENERAL_ERROR;
- }
-
- if (fort11_LoadRootPAAKey(slot, session) != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
-
- for (i=0 ; i < currSocket->numPersonalities; i++) {
- if (fort11_FortezzaIsACert (currSocket->personalityList[i].CertLabel)){
- if (!fort11_LoadCertObjectForSearch(currSocket->personalityList[i],
- slot, session,
- currSocket->personalityList)){
- return CKR_GENERAL_ERROR;
- }
- }
- }
-
- return CKR_OK;
-}
-
-PK11Slot*
-fort11_SlotFromSessionHandle(CK_SESSION_HANDLE inHandle) {
- CK_SESSION_HANDLE whichSlot = inHandle & SLOT_MASK;
-
- if (whichSlot >= kNumSockets) return NULL_PTR;
-
- return &fort11_slot[whichSlot];
-}
-
-PK11Slot*
-fort11_SlotFromID (CK_SLOT_ID inSlotID) {
- if (inSlotID == 0 || inSlotID > kNumSockets)
- return NULL;
-
- return &fort11_slot[inSlotID-1];
-}
-
-CK_ULONG fort11_firstSessionID (int inSlotNum) {
- return (CK_ULONG)(inSlotNum);
-}
-
-/*
- * Utility to convert passed in PIN to a CI_PIN
- */
-void fort11_convertToCIPin (CI_PIN ciPin,CK_CHAR_PTR pPin, CK_ULONG ulLen) {
- unsigned long i;
-
- for (i=0; i<ulLen; i++) {
- ciPin[i] = pPin[i];
- }
- ciPin[ulLen] = '\0';
-}
-
-
-/*
- * return true if object has attribute
- */
-static PRBool
-fort11_hasAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type) {
- PK11Attribute *attribute;
-
- FMUTEX_Lock(object->attributeLock);
- pk11queue_find(attribute,type,object->head,HASH_SIZE);
- FMUTEX_Unlock(object->attributeLock);
-
- return (PRBool)(attribute != NULL);
-}
-
-/*
- * create a new attribute with type, value, and length. Space is allocated
- * to hold value.
- */
-static PK11Attribute *
-fort11_NewAttribute(CK_ATTRIBUTE_TYPE type, CK_VOID_PTR value, CK_ULONG len) {
- PK11Attribute *attribute;
- CK_RV mrv;
-
- attribute = (PK11Attribute*)PORT_Alloc(sizeof(PK11Attribute));
- if (attribute == NULL) return NULL;
-
- attribute->attrib.type = type;
- if (value) {
- attribute->attrib.pValue = (CK_VOID_PTR)PORT_Alloc(len);
- if (attribute->attrib.pValue == NULL) {
- PORT_Free(attribute);
- return NULL;
- }
- PORT_Memcpy(attribute->attrib.pValue,value,len);
- attribute->attrib.ulValueLen = len;
- } else {
- attribute->attrib.pValue = NULL;
- attribute->attrib.ulValueLen = 0;
- }
- attribute->handle = type;
- attribute->next = attribute->prev = NULL;
- attribute->refCount = 1;
- if (FMUTEX_MutexEnabled()) {
- mrv = FMUTEX_Create (&attribute->refLock);
- if (mrv != CKR_OK) {
- if (attribute->attrib.pValue) PORT_Free(attribute->attrib.pValue);
- PORT_Free(attribute);
- return NULL;
- }
- } else {
- attribute->refLock = NULL;
- }
-
- return attribute;
-}
-
-/*
- * add an attribute to an object
- */
-static
-void fort11_AddAttribute(PK11Object *object,PK11Attribute *attribute) {
- FMUTEX_Lock (object->attributeLock);
- pk11queue_add(attribute,attribute->handle,object->head,HASH_SIZE);
- FMUTEX_Unlock(object->attributeLock);
-}
-
-static CK_RV
-fort11_AddAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *valPtr,
- CK_ULONG length) {
- PK11Attribute *attribute;
- attribute = fort11_NewAttribute(type,valPtr,length);
- if (attribute == NULL) { return CKR_HOST_MEMORY; }
- fort11_AddAttribute(object,attribute);
- return CKR_OK;
-}
-
-
-
-/* Make sure a given attribute exists. If it doesn't, initialize it to
- * value and len
- */
-static CK_RV
-fort11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *value,
- unsigned int len) {
- if ( !fort11_hasAttribute(object, type)) {
- return fort11_AddAttributeType(object,type,value,len);
- }
- return CKR_OK;
-}
-
-/*
- * look up and attribute structure from a type and Object structure.
- * The returned attribute is referenced and needs to be freed when
- * it is no longer needed.
- */
-static PK11Attribute *
-fort11_FindAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type) {
- PK11Attribute *attribute;
-
- FMUTEX_Lock(object->attributeLock);
- pk11queue_find(attribute,type,object->head,HASH_SIZE);
- if (attribute) {
- /* atomic increment would be nice here */
- FMUTEX_Lock(attribute->refLock);
- attribute->refCount++;
- FMUTEX_Unlock(attribute->refLock);
- }
- FMUTEX_Unlock(object->attributeLock);
-
- return(attribute);
-}
-
-/*
- * this is only valid for CK_BBOOL type attributes. Return the state
- * of that attribute.
- */
-static PRBool
-fort11_isTrue(PK11Object *object,CK_ATTRIBUTE_TYPE type) {
- PK11Attribute *attribute;
- PRBool tok = PR_FALSE;
-
- attribute=fort11_FindAttribute(object,type);
- if (attribute == NULL) { return PR_FALSE; }
- tok = (PRBool)(*(CK_BBOOL *)attribute->attrib.pValue);
- fort11_FreeAttribute(attribute);
-
- return tok;
-}
-
-/*
- * add an object to a slot and session queue
- */
-static
-void fort11_AddSlotObject(PK11Slot *slot, PK11Object *object) {
- FMUTEX_Lock(slot->objectLock);
- pk11queue_add(object,object->handle,slot->tokObjects,HASH_SIZE);
- FMUTEX_Unlock(slot->objectLock);
-}
-
-static
-void fort11_AddObject(PK11Session *session, PK11Object *object) {
- PK11Slot *slot = fort11_SlotFromSession(session);
-
- if (!fort11_isToken(object->handle)) {
- FMUTEX_Lock(session->objectLock);
- pk11queue_add(&object->sessionList,0,session->objects,0);
- FMUTEX_Unlock(session->objectLock);
- }
- fort11_AddSlotObject(slot,object);
-}
-
-/*
- * free all the data associated with an object. Object reference count must
- * be 'zero'.
- */
-static CK_RV
-fort11_DestroyObject(PK11Object *object) {
- int i;
- CK_RV crv = CKR_OK;
-/* PORT_Assert(object->refCount == 0);*/
-
- if (object->label) PORT_Free(object->label);
-
- /* clean out the attributes */
- /* since no one is referencing us, it's safe to walk the chain
- * without a lock */
- for (i=0; i < HASH_SIZE; i++) {
- PK11Attribute *ap,*next;
- for (ap = object->head[i]; ap != NULL; ap = next) {
- next = ap->next;
- /* paranoia */
- ap->next = ap->prev = NULL;
- fort11_FreeAttribute(ap);
- }
- object->head[i] = NULL;
- }
- FMUTEX_Destroy(object->attributeLock);
- FMUTEX_Destroy(object->refLock);
- if (object->objectInfo) {
- (*object->infoFree)(object->objectInfo);
- }
- PORT_Free(object);
- return crv;
-}
-
-
-/*
- * release a reference to an attribute structure
- */
-static void
-fort11_FreeAttribute(PK11Attribute *attribute) {
- PRBool destroy = PR_FALSE;
-
- FMUTEX_Lock(attribute->refLock);
- if (attribute->refCount == 1) destroy = PR_TRUE;
- attribute->refCount--;
- FMUTEX_Unlock(attribute->refLock);
-
- if (destroy) fort11_DestroyAttribute(attribute);
-}
-
-
-/*
- * release a reference to an object handle
- */
-static PK11FreeStatus
-fort11_FreeObject(PK11Object *object) {
- PRBool destroy = PR_FALSE;
- CK_RV crv;
-
- FMUTEX_Lock(object->refLock);
- if (object->refCount == 1) destroy = PR_TRUE;
- object->refCount--;
- FMUTEX_Unlock(object->refLock);
-
- if (destroy) {
- crv = fort11_DestroyObject(object);
- if (crv != CKR_OK) {
- return PK11_DestroyFailure;
- }
- return PK11_Destroyed;
- }
- return PK11_Busy;
-}
-
-static void
-fort11_update_state(PK11Slot *slot,PK11Session *session) {
- if (slot->isLoggedIn) {
- if (slot->ssoLoggedIn) {
- session->info.state = CKS_RW_SO_FUNCTIONS;
- } else if (session->info.flags & CKF_RW_SESSION) {
- session->info.state = CKS_RW_USER_FUNCTIONS;
- } else {
- session->info.state = CKS_RO_USER_FUNCTIONS;
- }
- } else {
- if (session->info.flags & CKF_RW_SESSION) {
- session->info.state = CKS_RW_PUBLIC_SESSION;
- } else {
- session->info.state = CKS_RO_PUBLIC_SESSION;
- }
- }
-}
-
-/* update the state of all the sessions on a slot */
-static void
-fort11_update_all_states(PK11Slot *slot) {
- int i;
- PK11Session *session;
-
- for (i=0; i < SESSION_HASH_SIZE; i++) {
- FMUTEX_Lock(slot->sessionLock);
- for (session = slot->head[i]; session; session = session->next) {
- fort11_update_state(slot,session);
- }
- FMUTEX_Unlock(slot->sessionLock);
- }
-}
-
-
-/*
- * Create a new object
- */
-static PK11Object *
-fort11_NewObject(PK11Slot *slot) {
- PK11Object *object;
- CK_RV mrv;
- int i;
-
- object = (PK11Object*)PORT_Alloc(sizeof(PK11Object));
- if (object == NULL) return NULL;
-
- object->handle = 0;
- object->next = object->prev = NULL;
- object->sessionList.next = NULL;
- object->sessionList.prev = NULL;
- object->sessionList.parent = object;
- object->inDB = PR_FALSE;
- object->label = NULL;
- object->refCount = 1;
- object->session = NULL;
- object->slot = slot;
- object->objclass = 0xffff;
- if (FMUTEX_MutexEnabled()) {
- mrv = FMUTEX_Create(&object->refLock);
- if (mrv != CKR_OK) {
- PORT_Free(object);
- return NULL;
- }
- mrv = FMUTEX_Create(&object->attributeLock);
- if (mrv != CKR_OK) {
- FMUTEX_Destroy(object->refLock);
- PORT_Free(object);
- return NULL;
- }
- } else {
- object->attributeLock = NULL;
- object->refLock = NULL;
- }
- for (i=0; i < HASH_SIZE; i++) {
- object->head[i] = NULL;
- }
- object->objectInfo = NULL;
- object->infoFree = NULL;
- return object;
-}
-
-/*
- * look up and object structure from a handle. OBJECT_Handles only make
- * sense in terms of a given session. make a reference to that object
- * structure returned.
- */
-static PK11Object * fort11_ObjectFromHandle(CK_OBJECT_HANDLE handle,
- PK11Session *session) {
- PK11Object **head;
- void *lock;
- PK11Slot *slot = fort11_SlotFromSession(session);
- PK11Object *object;
-
- /*
- * Token objects are stored in the slot. Session objects are stored
- * with the session.
- */
- head = slot->tokObjects;
- lock = slot->objectLock;
-
- FMUTEX_Lock(lock);
- pk11queue_find(object,handle,head,HASH_SIZE);
- if (object) {
- FMUTEX_Lock(object->refLock);
- object->refCount++;
- FMUTEX_Unlock(object->refLock);
- }
- FMUTEX_Unlock(lock);
-
- return(object);
-}
-
-/*
- * add an object to a slot andsession queue
- */
-static
-void fort11_DeleteObject(PK11Session *session, PK11Object *object) {
- PK11Slot *slot;
-
- if (session == NULL)
- return;
- slot = fort11_SlotFromSession(session);
- if (!fort11_isToken(object->handle)) {
- FMUTEX_Lock(session->objectLock);
- pk11queue_delete(&object->sessionList,0,session->objects,0);
- FMUTEX_Unlock(session->objectLock);
- }
- FMUTEX_Lock(slot->objectLock);
- pk11queue_delete(object,object->handle,slot->tokObjects,HASH_SIZE);
- FMUTEX_Unlock(slot->objectLock);
- fort11_FreeObject(object);
-}
-
-
-
-/*
- * ******************** Search Utilities *******************************
- */
-
-/* add an object to a search list */
-CK_RV
-fort11_AddToList(PK11ObjectListElement **list,PK11Object *object) {
- PK11ObjectListElement *newelem =
- (PK11ObjectListElement *)PORT_Alloc(sizeof(PK11ObjectListElement));
-
- if (newelem == NULL) return CKR_HOST_MEMORY;
-
- newelem->next = *list;
- newelem->object = object;
- FMUTEX_Lock(object->refLock);
- object->refCount++;
- FMUTEX_Unlock(object->refLock);
-
- *list = newelem;
- return CKR_OK;
-}
-
-
-/*
- * free a single list element. Return the Next object in the list.
- */
-PK11ObjectListElement *
-fort11_FreeObjectListElement(PK11ObjectListElement *objectList) {
- PK11ObjectListElement *ol = objectList->next;
-
- fort11_FreeObject(objectList->object);
- PORT_Free(objectList);
- return ol;
-}
-
-/* free an entire object list */
-void
-fort11_FreeObjectList(PK11ObjectListElement *objectList) {
- PK11ObjectListElement *ol;
-
- for (ol= objectList; ol != NULL; ol = fort11_FreeObjectListElement(ol)) {}
-}
-
-/*
- * free a search structure
- */
-void
-fort11_FreeSearch(PK11SearchResults *search) {
- if (search->handles) {
- PORT_Free(search->handles);
- }
- PORT_Free(search);
-}
-
-
-/*
- * Free up all the memory associated with an attribute. Reference count
- * must be zero to call this.
- */
-static void
-fort11_DestroyAttribute(PK11Attribute *attribute) {
- /*PORT_Assert(attribute->refCount == 0);*/
- FMUTEX_Destroy(attribute->refLock);
- if (attribute->attrib.pValue) {
- /* clear out the data in the attribute value... it may have been
- * sensitive data */
- PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
- PORT_Free(attribute->attrib.pValue);
- }
- PORT_Free(attribute);
-}
-
-/*
- * delete an attribute from an object
- */
-static void
-fort11_DeleteAttribute(PK11Object *object, PK11Attribute *attribute) {
- FMUTEX_Lock(object->attributeLock);
- if (attribute->next || attribute->prev) {
- pk11queue_delete(attribute,attribute->handle,
- object->head,HASH_SIZE);
- }
- FMUTEX_Unlock(object->attributeLock);
- fort11_FreeAttribute(attribute);
-}
-
-/*
- * decode when a particular attribute may be modified
- * PK11_NEVER: This attribute must be set at object creation time and
- * can never be modified.
- * PK11_ONCOPY: This attribute may be modified only when you copy the
- * object.
- * PK11_SENSITIVE: The CKA_SENSITIVE attribute can only be changed from
- * FALSE to TRUE.
- * PK11_ALWAYS: This attribute can always be modified.
- * Some attributes vary their modification type based on the class of the
- * object.
- */
-PK11ModifyType
-fort11_modifyType(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass) {
- /* if we don't know about it, user user defined, always allow modify */
- PK11ModifyType mtype = PK11_ALWAYS;
-
- switch(type) {
- /* NEVER */
- case CKA_CLASS:
- case CKA_CERTIFICATE_TYPE:
- case CKA_KEY_TYPE:
- case CKA_MODULUS:
- case CKA_MODULUS_BITS:
- case CKA_PUBLIC_EXPONENT:
- case CKA_PRIVATE_EXPONENT:
- case CKA_PRIME:
- case CKA_SUBPRIME:
- case CKA_BASE:
- case CKA_PRIME_1:
- case CKA_PRIME_2:
- case CKA_EXPONENT_1:
- case CKA_EXPONENT_2:
- case CKA_COEFFICIENT:
- case CKA_VALUE_LEN:
- mtype = PK11_NEVER;
- break;
-
- /* ONCOPY */
- case CKA_TOKEN:
- case CKA_PRIVATE:
- mtype = PK11_ONCOPY;
- break;
-
- /* SENSITIVE */
- case CKA_SENSITIVE:
- mtype = PK11_SENSITIVE;
- break;
-
- /* ALWAYS */
- case CKA_LABEL:
- case CKA_APPLICATION:
- case CKA_ID:
- case CKA_SERIAL_NUMBER:
- case CKA_START_DATE:
- case CKA_END_DATE:
- case CKA_DERIVE:
- case CKA_ENCRYPT:
- case CKA_DECRYPT:
- case CKA_SIGN:
- case CKA_VERIFY:
- case CKA_SIGN_RECOVER:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- case CKA_UNWRAP:
- mtype = PK11_ALWAYS;
- break;
-
- /* DEPENDS ON CLASS */
- case CKA_VALUE:
- mtype = (inClass == CKO_DATA) ? PK11_ALWAYS : PK11_NEVER;
- break;
-
- case CKA_SUBJECT:
- mtype = (inClass == CKO_CERTIFICATE) ? PK11_NEVER : PK11_ALWAYS;
- break;
- default:
- break;
- }
- return mtype;
-}
-
-/* decode if a particular attribute is sensitive (cannot be read
- * back to the user of if the object is set to SENSITIVE) */
-PRBool
-fort11_isSensitive(CK_ATTRIBUTE_TYPE type, CK_OBJECT_CLASS inClass) {
- switch(type) {
- /* ALWAYS */
- case CKA_PRIVATE_EXPONENT:
- case CKA_PRIME_1:
- case CKA_PRIME_2:
- case CKA_EXPONENT_1:
- case CKA_EXPONENT_2:
- case CKA_COEFFICIENT:
- return PR_TRUE;
-
- /* DEPENDS ON CLASS */
- case CKA_VALUE:
- /* PRIVATE and SECRET KEYS have SENSITIVE values */
- return (PRBool)((inClass == CKO_PRIVATE_KEY) ||
- (inClass == CKO_SECRET_KEY));
-
- default:
- break;
- }
- return PR_FALSE;
-}
-
-static void
-fort11_DeleteAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type) {
- PK11Attribute *attribute;
- attribute = fort11_FindAttribute(object, type);
- if (attribute == NULL) return ;
- fort11_DeleteAttribute(object,attribute);
-}
-
-
-/*
- * create a new nession. NOTE: The session handle is not set, and the
- * session is not added to the slot's session queue.
- */
-static PK11Session *
-fort11_NewSession(CK_SLOT_ID slotID, CK_NOTIFY notify,
- CK_VOID_PTR pApplication,
- CK_FLAGS flags) {
- PK11Session *session;
- PK11Slot *slot = &fort11_slot[slotID-1];
- CK_RV mrv;
-
- if (slot == NULL) return NULL;
-
- session = (PK11Session*)PORT_Alloc(sizeof(PK11Session));
- if (session == NULL) return NULL;
-
- session->next = session->prev = NULL;
- session->refCount = 1;
- session->context = NULL;
- session->search = NULL;
- session->objectIDCount = 1;
- session->fortezzaContext.fortezzaKey = NULL;
- session->fortezzaContext.fortezzaSocket = NULL;
-
- if (FMUTEX_MutexEnabled()) {
- mrv = FMUTEX_Create(&session->refLock);
- if (mrv != CKR_OK) {
- PORT_Free(session);
- return NULL;
- }
- mrv = FMUTEX_Create(&session->objectLock);
- if (mrv != CKR_OK) {
- FMUTEX_Destroy(session->refLock);
- PORT_Free(session);
- return NULL;
- }
- } else {
- session->refLock = NULL;
- session->objectLock = NULL;
- }
-
- session->objects[0] = NULL;
-
- session->slot = slot;
- session->notify = notify;
- session->appData = pApplication;
- session->info.flags = flags;
- session->info.slotID = slotID;
- fort11_update_state(slot,session);
- return session;
-}
-
-
-/*
- * look up a session structure from a session handle
- * generate a reference to it.
- */
-PK11Session *
-fort11_SessionFromHandle(CK_SESSION_HANDLE handle, PRBool isCloseSession) {
- PK11Slot *slot = fort11_SlotFromSessionHandle(handle);
- PK11Session *session;
-
- if (!isCloseSession &&
- !SocketStateUnchanged(&fortezzaSockets[slot->slotID-1]))
- return NULL;
-
- FMUTEX_Lock(slot->sessionLock);
- pk11queue_find(session,handle,slot->head,SESSION_HASH_SIZE);
- if (session) session->refCount++;
- FMUTEX_Unlock(slot->sessionLock);
-
- return (session);
-}
-
-/* free all the data associated with a session. */
-static void
-fort11_DestroySession(PK11Session *session)
-{
- PK11ObjectList *op,*next;
-/* PORT_Assert(session->refCount == 0);*/
-
- /* clean out the attributes */
- FMUTEX_Lock(session->objectLock);
- for (op = session->objects[0]; op != NULL; op = next) {
- next = op->next;
- /* paranoia */
- op->next = op->prev = NULL;
- fort11_DeleteObject(session,op->parent);
- }
- FMUTEX_Unlock(session->objectLock);
-
- FMUTEX_Destroy(session->objectLock);
- FMUTEX_Destroy(session->refLock);
-
- if (session->search) {
- fort11_FreeSearch(session->search);
- }
-
- pk11queue_delete(session, session->handle, session->slot->head,
- SESSION_HASH_SIZE);
-
- PORT_Free(session);
-}
-
-
-/*
- * release a reference to a session handle
- */
-void
-fort11_FreeSession(PK11Session *session) {
- PRBool destroy = PR_FALSE;
- PK11Slot *slot = NULL;
-
- if (!session) return; /*Quick fix to elminate crash*/
- /*Fix in later version */
-
- if (FMUTEX_MutexEnabled()) {
- slot = fort11_SlotFromSession(session);
- FMUTEX_Lock(slot->sessionLock);
- }
- if (session->refCount == 1) destroy = PR_TRUE;
- session->refCount--;
- if (FMUTEX_MutexEnabled()) {
- FMUTEX_Unlock(slot->sessionLock);
- }
-
- if (destroy) {
- fort11_DestroySession(session);
- }
-}
-
-
-/* return true if the object matches the template */
-PRBool
-fort11_objectMatch(PK11Object *object,CK_ATTRIBUTE_PTR theTemplate,int count) {
- int i;
-
- for (i=0; i < count; i++) {
- PK11Attribute *attribute =
- fort11_FindAttribute(object,theTemplate[i].type);
- if (attribute == NULL) {
- return PR_FALSE;
- }
- if (attribute->attrib.ulValueLen == theTemplate[i].ulValueLen) {
- if (PORT_Memcmp(attribute->attrib.pValue,theTemplate[i].pValue,
- theTemplate[i].ulValueLen) == 0) {
- fort11_FreeAttribute(attribute);
- continue;
- }
- }
- fort11_FreeAttribute(attribute);
- return PR_FALSE;
- }
- return PR_TRUE;
-}
-
-/* search through all the objects in the queue and return the template matches
- * in the object list.
- */
-CK_RV
-fort11_searchObjectList(PK11ObjectListElement **objectList,PK11Object **head,
- void *lock, CK_ATTRIBUTE_PTR theTemplate, int count) {
- int i;
- PK11Object *object;
- CK_RV rv;
-
- for(i=0; i < HASH_SIZE; i++) {
- /* We need to hold the lock to copy a consistant version of
- * the linked list. */
- FMUTEX_Lock(lock);
- for (object = head[i]; object != NULL; object= object->next) {
- if (fort11_objectMatch(object,theTemplate,count)) {
- rv = fort11_AddToList(objectList,object);
- if (rv != CKR_OK) {
- return rv;
- }
- }
- }
- FMUTEX_Unlock(lock);
- }
- return CKR_OK;
-}
-
-static PRBool
-fort11_NotAllFuncsNULL (CK_C_INITIALIZE_ARGS_PTR pArgs) {
- return (PRBool)(pArgs && pArgs->CreateMutex && pArgs->DestroyMutex &&
- pArgs->LockMutex && pArgs->UnlockMutex);
-}
-
-static PRBool
-fort11_InArgCheck(CK_C_INITIALIZE_ARGS_PTR pArgs) {
- PRBool rv;
- /* The only check for now, is to make sure that all of the
- * function pointers are either all NULL or all Non-NULL.
- * We also need to make sure the pReserved field in pArgs is
- * set to NULL.
- */
- if (pArgs == NULL) {
- return PR_TRUE; /* If the argument is NULL, no
- * inconsistencies can exist.
- */
- }
-
- if (pArgs->pReserved != NULL) {
- return PR_FALSE;
- }
-
- if (pArgs->CreateMutex != NULL) {
- rv = (PRBool) (pArgs->DestroyMutex != NULL &&
- pArgs->LockMutex != NULL &&
- pArgs->UnlockMutex != NULL);
- } else { /*pArgs->CreateMutex == NULL*/
- rv = (PRBool) (pArgs->DestroyMutex == NULL &&
- pArgs->LockMutex == NULL &&
- pArgs->UnlockMutex == NULL);
- }
- return rv;
-}
-
-
-
-/**********************************************************************
- *
- * Start of PKCS 11 functions
- *
- **********************************************************************/
-
-
-/**********************************************************************
- *
- * In order to get this to work on 68K, we have to do some special tricks,
- * First trick is that we need to make the module a Code Resource, and
- * all Code Resources on 68K have to have a main function. So we
- * define main to be a wrapper for C_GetFunctionList which will be the
- * first funnction called by any software that uses the PKCS11 module.
- *
- * The second trick is that whenever you access a global variable from
- * the Code Resource, it does funny things to the stack on 68K, so we
- * need to call some macros that handle the stack for us. First thing
- * you do is call EnterCodeResource() first thing in a function that
- * accesses a global, right before you leave that function, you call
- * ExitCodeResource. This will take care of stack management.
- *
- * Third trick is to call __InitCode__() when we first enter the module
- * so that all of the global variables get initialized properly.
- *
- **********************************************************************/
-
-#if defined(XP_MAC) && !defined(__POWERPC__)
-
-#define FORT11_RETURN(exp) {ExitCodeResource(); return (exp);}
-#define FORT11_ENTER() EnterCodeResource();
-
-#else /*XP_MAC*/
-
-#define FORT11_RETURN(exp) return (exp);
-#define FORT11_ENTER()
-
-#endif /*XP_MAC*/
-
-#define CARD_OK(rv) if ((rv) != CI_OK) FORT11_RETURN (CKR_DEVICE_ERROR);
-#define SLOT_OK(slot) if ((slot) > kNumSockets) FORT11_RETURN (CKR_SLOT_ID_INVALID);
-
-#ifdef XP_MAC
-/* This is not a 4.0 project, so I can't depend on
- * 4.0 defines, so instead I depend on CodeWarrior
- * defines.
- */
-#if __POWERPC__
-#elif __CFM68K__
-#else
-/* To get this to work on 68K, we need to have
- * the symbol main. So we just make it a wrapper for C_GetFunctionList.
- */
-PR_PUBLIC_API(CK_RV) main(CK_FUNCTION_LIST_PTR *pFunctionList) {
- FORT11_ENTER()
- CK_RV rv;
-
- __InitCode__();
-
- rv = C_GetFunctionList(pFunctionList);
- FORT11_RETURN (rv);
-}
-#endif
-
-#endif /*XP_MAC*/
-
-/* Return the function list */
-PR_PUBLIC_API(CK_RV) C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
- /* No need to do a FORT11_RETURN as this function will never be directly
- * called in the case where we need to do stack management.
- * The main function will call this after taking care of stack stuff.
- */
- *pFunctionList = &fort11_funcList;
- return CKR_OK;
-}
-
-
-/* C_Initialize initializes the Cryptoki library. */
-PR_PUBLIC_API(CK_RV) C_Initialize(CK_VOID_PTR pReserved) {
- FORT11_ENTER()
- int i,j, tempNumSockets;
- int rv = 1;
- CK_C_INITIALIZE_ARGS_PTR pArgs = (CK_C_INITIALIZE_ARGS_PTR)pReserved;
- CK_RV mrv;
-
- /* intialize all the slots */
- if (!init) {
- init = PR_TRUE;
-
- /* need to initialize locks before MACI_Initialize is called in
- * software fortezza. */
- if (pArgs) {
- if (!fort11_InArgCheck(pArgs)) {
- FORT11_RETURN (CKR_ARGUMENTS_BAD);
- }
- if (pArgs->flags & CKF_OS_LOCKING_OK){
- if (!fort11_NotAllFuncsNULL(pArgs)) {
- FORT11_RETURN (CKR_CANT_LOCK);
- }
- }
- if (fort11_NotAllFuncsNULL(pArgs)) {
- mrv = FMUTEX_Init(pArgs);
- if (mrv != CKR_OK) {
- return CKR_GENERAL_ERROR;
- }
- }
- }
- rv = MACI_Initialize (&tempNumSockets);
- kNumSockets = (CK_ULONG)tempNumSockets;
-
- CARD_OK (rv);
- for (i=0; i < (int) kNumSockets; i++) {
- if (FMUTEX_MutexEnabled()) {
- mrv = FMUTEX_Create(&fort11_slot[i].sessionLock);
- if (mrv != CKR_OK) {
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
- mrv = FMUTEX_Create(&fort11_slot[i].objectLock);
- if (mrv != CKR_OK) {
- FMUTEX_Destroy(fort11_slot[i].sessionLock);
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
- } else {
- fort11_slot[i].sessionLock = NULL;
- fort11_slot[i].objectLock = NULL;
- }
- for(j=0; j < SESSION_HASH_SIZE; j++) {
- fort11_slot[i].head[j] = NULL;
- }
- for(j=0; j < HASH_SIZE; j++) {
- fort11_slot[i].tokObjects[j] = NULL;
- }
- fort11_slot[i].password = NULL;
- fort11_slot[i].hasTokens = PR_FALSE;
- fort11_slot[i].sessionIDCount = fort11_firstSessionID (i);
- fort11_slot[i].sessionCount = 0;
- fort11_slot[i].rwSessionCount = 0;
- fort11_slot[i].tokenIDCount = 1;
- fort11_slot[i].needLogin = PR_TRUE;
- fort11_slot[i].isLoggedIn = PR_FALSE;
- fort11_slot[i].ssoLoggedIn = PR_FALSE;
- fort11_slot[i].DB_loaded = PR_FALSE;
- fort11_slot[i].slotID= i+1;
- InitSocket(&fortezzaSockets[i], i+1);
- }
- }
- FORT11_RETURN (CKR_OK);
-}
-
-/*C_Finalize indicates that an application is done with the Cryptoki library.*/
-PR_PUBLIC_API(CK_RV) C_Finalize (CK_VOID_PTR pReserved) {
- FORT11_ENTER()
- int i;
-
- for (i=0; i< (int) kNumSockets; i++) {
- FreeSocket(&fortezzaSockets[i]);
- }
- MACI_Terminate(fortezzaSockets[0].maciSession);
- init = PR_FALSE;
- FORT11_RETURN (CKR_OK);
-}
-
-
-
-
-/* C_GetInfo returns general information about Cryptoki. */
-PR_PUBLIC_API(CK_RV) C_GetInfo(CK_INFO_PTR pInfo) {
- FORT11_ENTER()
- pInfo->cryptokiVersion = fort11_funcList.version;
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- pInfo->libraryVersion.major = 1;
- pInfo->libraryVersion.minor = 7;
- PORT_Memcpy(pInfo->libraryDescription,libraryDescription,32);
- pInfo->flags = 0;
- FORT11_RETURN (CKR_OK);
-}
-
-/* C_GetSlotList obtains a list of slots in the system. */
-PR_PUBLIC_API(CK_RV) C_GetSlotList(CK_BBOOL tokenPresent,
- CK_SLOT_ID_PTR pSlotList,
- CK_ULONG_PTR pulCount) {
- FORT11_ENTER()
- int i;
-
- if (pSlotList != NULL) {
- if (*pulCount >= kNumSockets) {
- for (i=0; i < (int) kNumSockets; i++) {
- pSlotList[i] = i+1;
- }
- } else {
- FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
- }
- } else {
- *pulCount = kNumSockets;
- }
- FORT11_RETURN (CKR_OK);
-}
-
-/* C_GetSlotInfo obtains information about a particular slot in the system. */
-PR_PUBLIC_API(CK_RV) C_GetSlotInfo(CK_SLOT_ID slotID,
- CK_SLOT_INFO_PTR pInfo) {
- FORT11_ENTER()
- int rv;
- CI_CONFIG ciConfig;
- CI_STATE ciState;
- HSESSION maciSession;
- char slotDescription[65];
- FortezzaSocket *socket;
-
-
- SLOT_OK(slotID);
-
- socket = &fortezzaSockets[slotID-1];
- if (!socket->isOpen) {
- InitSocket(socket, slotID);
- }
- maciSession = socket->maciSession;
-
- rv = MACI_Select(maciSession, slotID);
-
- CARD_OK (rv)
-
- rv = MACI_GetConfiguration (maciSession, &ciConfig);
-
-
- pInfo->firmwareVersion.major = 0;
- pInfo->firmwareVersion.minor = 0;
-#ifdef SWFORT
- PORT_Memcpy (pInfo->manufacturerID,"Netscape Communications Corp ",32);
- PORT_Memcpy (slotDescription,"Netscape Software Slot # ",32);
-#define _local_BASE 24
-#else
- PORT_Memcpy (pInfo->manufacturerID,"LITRONIC ",32);
- PORT_Memcpy (slotDescription,"Litronic MACI Slot # ",32);
-#define _local_BASE 20
-#endif
- slotDescription[_local_BASE] = (char )((slotID < 10) ? slotID :
- slotID/10) + '0';
- if (slotID >= 10) slotDescription[_local_BASE+1] =
- (char)(slotID % 10) + '0';
- PORT_Memcpy (&slotDescription[32]," ",32);
- PORT_Memcpy (pInfo->slotDescription, slotDescription , 64);
- if (rv == CI_OK) {
- pInfo->hardwareVersion.major =
- (ciConfig.ManufacturerVersion & MAJOR_VERSION_MASK) >> 8;
- pInfo->hardwareVersion.minor =
- ciConfig.ManufacturerVersion & MINOR_VERSION_MASK;
- pInfo->flags = CKF_TOKEN_PRESENT;
- } else {
- pInfo->hardwareVersion.major = 0;
- pInfo->hardwareVersion.minor = 0;
- pInfo->flags = 0;
- }
-#ifdef SWFORT
- /* do we need to make it a removable device as well?? */
- pInfo->flags |= CKF_REMOVABLE_DEVICE;
-#else
- pInfo->flags |= (CKF_REMOVABLE_DEVICE | CKF_HW_SLOT);
-#endif
-
- rv = MACI_GetState(maciSession, &ciState);
-
- if (rv == CI_OK) {
- switch (ciState) {
- case CI_ZEROIZE:
- case CI_INTERNAL_FAILURE:
- pInfo->flags &= (~CKF_TOKEN_PRESENT);
- default:
- break;
- }
- } else {
- pInfo->flags &= (~CKF_TOKEN_PRESENT);
- }
-
- FORT11_RETURN (CKR_OK);
-}
-
-#define CKF_THREAD_SAFE 0x8000
-
-/* C_GetTokenInfo obtains information about a particular token
- in the system. */
-PR_PUBLIC_API(CK_RV) C_GetTokenInfo(CK_SLOT_ID slotID,
- CK_TOKEN_INFO_PTR pInfo) {
- FORT11_ENTER()
- CI_STATUS cardStatus;
- CI_CONFIG ciConfig;
- PK11Slot *slot;
- int rv, i;
- char tmp[33];
- FortezzaSocket *socket;
-
- SLOT_OK (slotID);
-
- slot = &fort11_slot[slotID-1];
-
- socket = &fortezzaSockets[slotID-1];
- if (!socket->isOpen) {
- InitSocket(socket, slotID);
- }
-
- rv = MACI_Select (socket->maciSession, slotID);
- rv = MACI_GetStatus (socket->maciSession, &cardStatus);
- if (rv != CI_OK) {
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
-#ifdef SWFORT
- sprintf (tmp, "Software FORTEZZA Slot #%d", slotID);
-#else
- sprintf (tmp, "FORTEZZA Slot #%d", slotID);
-#endif
-
- PORT_Memcpy (pInfo->label, tmp, PORT_Strlen(tmp)+1);
-
- for (i=0; i<8; i++) {
- int serNum;
-
- serNum = (int)cardStatus.SerialNumber[i];
- sprintf ((char*)&pInfo->serialNumber[2*i], "%.2x", serNum);
- }
-
- rv = MACI_GetTime (fortezzaSockets[slotID-1].maciSession, pInfo->utcTime);
- if (rv == CI_OK) {
- pInfo->flags = CKF_CLOCK_ON_TOKEN;
- } else {
- switch (rv) {
- case CI_LIB_NOT_INIT:
- case CI_INV_POINTER:
- case CI_NO_CARD:
- case CI_NO_SOCKET:
- FORT11_RETURN (CKR_DEVICE_ERROR);
- default:
- pInfo->flags = 0;
- break;
- }
- }
-
- rv = MACI_GetConfiguration (fortezzaSockets[slotID-1].maciSession,
- &ciConfig);
-
- if (rv == CI_OK) {
- PORT_Memcpy(pInfo->manufacturerID,ciConfig.ManufacturerName,
- PORT_Strlen(ciConfig.ManufacturerName));
- for (i=PORT_Strlen(ciConfig.ManufacturerName); i<32; i++) {
- pInfo->manufacturerID[i] = ' ';
- }
- PORT_Memcpy(pInfo->model,ciConfig.ProcessorType,16);
- }
- pInfo->ulMaxPinLen = CI_PIN_SIZE;
- pInfo->ulMinPinLen = 0;
- pInfo->ulTotalPublicMemory = 0;
- pInfo->ulFreePublicMemory = 0;
- pInfo->flags |= CKF_RNG | CKF_LOGIN_REQUIRED| CKF_USER_PIN_INITIALIZED |
- CKF_THREAD_SAFE | CKF_WRITE_PROTECTED;
-
- pInfo->ulMaxSessionCount = 0;
- pInfo->ulSessionCount = slot->sessionCount;
- pInfo->ulMaxRwSessionCount = 0;
- pInfo->ulRwSessionCount = slot->rwSessionCount;
-
- if (rv == CI_OK) {
- pInfo->firmwareVersion.major =
- (ciConfig.ManufacturerSWVer & MAJOR_VERSION_MASK) >> 8;
- pInfo->firmwareVersion.minor =
- ciConfig.ManufacturerSWVer & MINOR_VERSION_MASK;
- pInfo->hardwareVersion.major =
- (ciConfig.ManufacturerVersion & MAJOR_VERSION_MASK) >> 8;
- pInfo->hardwareVersion.minor =
- ciConfig.ManufacturerVersion & MINOR_VERSION_MASK;
- }
- FORT11_RETURN (CKR_OK);
-}
-
-
-
-/* C_GetMechanismList obtains a list of mechanism types supported by a
- token. */
-PR_PUBLIC_API(CK_RV) C_GetMechanismList(CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE_PTR pMechanismList,
- CK_ULONG_PTR pulCount) {
- FORT11_ENTER()
- CK_RV rv = CKR_OK;
- int i;
-
- SLOT_OK (slotID);
-
- if (pMechanismList == NULL) {
- *pulCount = mechanismCount;
- } else {
- if (*pulCount >= mechanismCount) {
- *pulCount = mechanismCount;
- for (i=0; i< (int)mechanismCount; i++) {
- pMechanismList[i] = mechanisms[i].type;
- }
- } else {
- rv = CKR_BUFFER_TOO_SMALL;
- }
- }
- FORT11_RETURN (rv);
-}
-
-
-/* C_GetMechanismInfo obtains information about a particular mechanism
- * possibly supported by a token. */
-PR_PUBLIC_API(CK_RV) C_GetMechanismInfo(CK_SLOT_ID slotID,
- CK_MECHANISM_TYPE type,
- CK_MECHANISM_INFO_PTR pInfo) {
- int i;
- FORT11_ENTER()
- SLOT_OK (slotID);
-
- for (i=0; i< (int)mechanismCount; i++) {
- if (type == mechanisms[i].type) {
- PORT_Memcpy (pInfo, &mechanisms[i].domestic, sizeof (CK_MECHANISM_INFO));
- FORT11_RETURN (CKR_OK);
- }
- }
- FORT11_RETURN (CKR_MECHANISM_INVALID);
-}
-
-
-/* C_InitToken initializes a token. */
-PR_PUBLIC_API(CK_RV) C_InitToken(CK_SLOT_ID slotID,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen,
- CK_CHAR_PTR pLabel) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_InitPIN initializes the normal user's PIN. */
-PR_PUBLIC_API(CK_RV) C_InitPIN(CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_SetPIN modifies the PIN of user that is currently logged in. */
-/* NOTE: This is only valid for the PRIVATE_KEY_SLOT */
-PR_PUBLIC_API(CK_RV) C_SetPIN(CK_SESSION_HANDLE hSession,
- CK_CHAR_PTR pOldPin,
- CK_ULONG ulOldLen,
- CK_CHAR_PTR pNewPin,
- CK_ULONG ulNewLen) {
- FORT11_ENTER()
-#ifndef SWFORT
- CI_PIN ciOldPin, ciNewPin;
-#endif
- PK11Session *session;
- PK11Slot *slot;
- int rv;
-
- session = fort11_SessionFromHandle (hSession, PR_FALSE);
-
- slot = fort11_SlotFromSession (session);
- SLOT_OK(slot->slotID)
-
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- rv = MACI_Select (fortezzaSockets[slot->slotID-1].maciSession, slot->slotID);
- CARD_OK (rv)
-
- if (slot->needLogin && session->info.state != CKS_RW_USER_FUNCTIONS) {
- fort11_FreeSession (session);
- FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
- }
-
- fort11_FreeSession (session);
-
- if (ulNewLen > CI_PIN_SIZE || ulOldLen > CI_PIN_SIZE)
- FORT11_RETURN (CKR_PIN_LEN_RANGE);
-
-#ifndef SWFORT
- fort11_convertToCIPin (ciOldPin,pOldPin, ulOldLen);
- fort11_convertToCIPin (ciNewPin,pNewPin, ulNewLen);
-
- rv = MACI_ChangePIN (fortezzaSockets[slot->slotID-1].maciSession,
- CI_USER_PIN, ciOldPin, ciNewPin);
-#else
- rv = MACI_ChangePIN (fortezzaSockets[slot->slotID-1].maciSession,
- CI_USER_PIN, pOldPin, pNewPin);
-#endif
-
- if (rv != CI_OK) {
- switch (rv) {
- case CI_FAIL:
- FORT11_RETURN (CKR_PIN_INCORRECT);
- default:
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
- }
- FORT11_RETURN (CKR_OK);
-}
-
-/* C_OpenSession opens a session between an application and a token. */
-PR_PUBLIC_API(CK_RV) C_OpenSession(CK_SLOT_ID slotID,
- CK_FLAGS flags,
- CK_VOID_PTR pApplication,
- CK_NOTIFY Notify,
- CK_SESSION_HANDLE_PTR phSession) {
- FORT11_ENTER()
- PK11Slot *slot;
- CK_SESSION_HANDLE sessionID;
- PK11Session *session;
- FortezzaSocket *socket;
-
- SLOT_OK (slotID)
- slot = &fort11_slot[slotID-1];
- socket = &fortezzaSockets[slotID-1];
-
- if (!socket->isOpen) {
- if (InitSocket(socket, slotID) != SOCKET_SUCCESS) {
- FORT11_RETURN (CKR_TOKEN_NOT_PRESENT);
- }
- }
-
- session = fort11_NewSession (slotID, Notify, pApplication,
- flags | CKF_SERIAL_SESSION);
-
- if (session == NULL) FORT11_RETURN (CKR_HOST_MEMORY);
-
- FMUTEX_Lock(slot->sessionLock);
-
- slot->sessionIDCount += ADD_NEXT_SESS_ID;
- sessionID = slot->sessionIDCount;
- fort11_update_state (slot, session);
- pk11queue_add (session, sessionID, slot->head, SESSION_HASH_SIZE);
- slot->sessionCount++;
- if (session->info.flags & CKF_RW_SESSION) {
- slot->rwSessionCount++;
- }
- session->handle = sessionID;
- session->info.ulDeviceError = 0;
-
- FMUTEX_Unlock(slot->sessionLock);
-
- *phSession = sessionID;
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_CloseSession closes a session between an application and a token. */
-PR_PUBLIC_API(CK_RV) C_CloseSession(CK_SESSION_HANDLE hSession) {
- FORT11_ENTER()
- PK11Slot *slot;
- PK11Session *session;
-
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- slot = fort11_SlotFromSessionHandle (hSession);
-
- if (session == NULL) {
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- FMUTEX_Lock(slot->sessionLock);
- if (session->next || session->prev) {
- session->refCount--;
- if (session->info.flags & CKF_RW_SESSION) {
- slot->rwSessionCount--;
- }
- if (slot->sessionCount == 0) {
- slot->isLoggedIn = PR_FALSE;
- slot->password = NULL;
- }
- }
-
- FMUTEX_Unlock(slot->sessionLock);
-
- fort11_FreeSession (session);
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_CloseAllSessions closes all sessions with a token. */
-PR_PUBLIC_API(CK_RV) C_CloseAllSessions (CK_SLOT_ID slotID) {
- FORT11_ENTER()
- PK11Slot *slot;
- PK11Session *session;
- int i;
-
-
- slot = fort11_SlotFromID(slotID);
- if (slot == NULL) FORT11_RETURN (CKR_SLOT_ID_INVALID);
-
- /* first log out the card */
- FMUTEX_Lock(slot->sessionLock);
- slot->isLoggedIn = PR_FALSE;
- slot->password = NULL;
- FMUTEX_Unlock(slot->sessionLock);
-
- /* now close all the current sessions */
- /* NOTE: If you try to open new sessions before C_CloseAllSessions
- * completes, some of those new sessions may or may not be closed by
- * C_CloseAllSessions... but any session running when this code starts
- * will guarrenteed be close, and no session will be partially closed */
- for (i=0; i < SESSION_HASH_SIZE; i++) {
- do {
- FMUTEX_Lock(slot->sessionLock);
- session = slot->head[i];
- /* hand deque */
- /* this duplicates much of C_close session functionality, but because
- * we know that we are freeing all the sessions, we and do some
- * more efficient processing */
- if (session) {
- slot->head[i] = session->next;
- if (session->next) session->next->prev = NULL;
- session->next = session->prev = NULL;
- slot->sessionCount--;
- if (session->info.flags & CKF_RW_SESSION) {
- slot->rwSessionCount--;
- }
- }
- FMUTEX_Unlock(slot->sessionLock);
- if (session) fort11_FreeSession(session);
- } while (session != NULL);
- }
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_GetSessionInfo obtains information about the session. */
-PR_PUBLIC_API(CK_RV) C_GetSessionInfo(CK_SESSION_HANDLE hSession,
- CK_SESSION_INFO_PTR pInfo) {
- FORT11_ENTER()
- PK11Session *session;
- PK11Slot *slot;
- CI_STATE cardState;
- FortezzaSocket *socket;
- int ciRV;
-
- session = fort11_SessionFromHandle (hSession, PR_FALSE);
- slot = fort11_SlotFromSessionHandle(hSession);
- socket = &fortezzaSockets[slot->slotID-1];
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
- PORT_Memcpy (pInfo, &session->info, sizeof (CK_SESSION_INFO));
- fort11_FreeSession(session);
-
- ciRV = MACI_Select(socket->maciSession, slot->slotID);
- CARD_OK(ciRV)
-
- ciRV = MACI_GetState(socket->maciSession, &cardState);
- CARD_OK(ciRV)
-
- if (socket->isLoggedIn) {
- switch (cardState) {
- case CI_POWER_UP:
- case CI_UNINITIALIZED:
- case CI_INITIALIZED:
- case CI_SSO_INITIALIZED:
- case CI_LAW_INITIALIZED:
- case CI_USER_INITIALIZED:
- pInfo->state = CKS_RO_PUBLIC_SESSION;
- break;
- case CI_STANDBY:
- case CI_READY:
- pInfo->state = CKS_RO_USER_FUNCTIONS;
- break;
- default:
- pInfo->state = CKS_RO_PUBLIC_SESSION;
- break;
- }
- } else {
- pInfo->state = CKS_RO_PUBLIC_SESSION;
- }
-
- FORT11_RETURN (CKR_OK);
-}
-
-/* C_Login logs a user into a token. */
-PR_PUBLIC_API(CK_RV) C_Login(CK_SESSION_HANDLE hSession,
- CK_USER_TYPE userType,
- CK_CHAR_PTR pPin,
- CK_ULONG ulPinLen) {
- FORT11_ENTER()
- PK11Slot *slot;
- PK11Session *session;
-#ifndef SWFORT
- CI_PIN ciPin;
-#endif
- int rv, ciUserType;
-
- slot = fort11_SlotFromSessionHandle (hSession);
- session = fort11_SessionFromHandle(hSession, PR_FALSE);
-
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- fort11_FreeSession(session);
-
- if (slot->isLoggedIn) FORT11_RETURN (CKR_USER_ALREADY_LOGGED_IN);
- slot->ssoLoggedIn = PR_FALSE;
-
-#ifndef SWFORT
- if (ulPinLen > CI_PIN_SIZE) FORT11_RETURN (CKR_PIN_LEN_RANGE);
-
- fort11_convertToCIPin (ciPin, pPin, ulPinLen);
-#endif
- switch (userType) {
- case CKU_SO:
- ciUserType = CI_SSO_PIN;
- break;
- case CKU_USER:
- ciUserType = CI_USER_PIN;
- break;
- default:
- FORT11_RETURN (CKR_USER_TYPE_INVALID);
- }
-
-#ifndef SWFORT
- rv = LoginToSocket(&fortezzaSockets[slot->slotID-1], ciUserType, ciPin);
-#else
- rv = LoginToSocket(&fortezzaSockets[slot->slotID-1], ciUserType, pPin);
-#endif
-
- switch (rv) {
- case SOCKET_SUCCESS:
- break;
- case CI_FAIL:
- FORT11_RETURN (CKR_PIN_INCORRECT);
- default:
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- FMUTEX_Lock(slot->sessionLock);
- slot->isLoggedIn = PR_TRUE;
- if (userType == CKU_SO) {
- slot->ssoLoggedIn = PR_TRUE;
- }
- FMUTEX_Unlock(slot->sessionLock);
-
- fort11_update_all_states(slot);
- FORT11_RETURN (CKR_OK);
-}
-
-/* C_Logout logs a user out from a token. */
-PR_PUBLIC_API(CK_RV) C_Logout(CK_SESSION_HANDLE hSession) {
- FORT11_ENTER()
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
-
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- if (!slot->isLoggedIn)
- FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
-
- FMUTEX_Lock(slot->sessionLock);
-
- slot->isLoggedIn = PR_FALSE;
- slot->ssoLoggedIn = PR_FALSE;
- slot->password = NULL;
- LogoutFromSocket (&fortezzaSockets[slot->slotID-1]);
-
- FMUTEX_Unlock(slot->sessionLock);
-
- fort11_update_all_states(slot);
- FORT11_RETURN (CKR_OK);
-}
-
-/* C_CreateObject creates a new object. */
-PR_PUBLIC_API(CK_RV) C_CreateObject(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phObject) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_CopyObject copies an object, creating a new object for the copy. */
-PR_PUBLIC_API(CK_RV) C_CopyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phNewObject) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_DestroyObject destroys an object. */
-PR_PUBLIC_API(CK_RV) C_DestroyObject(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject) {
- FORT11_ENTER()
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- PK11Session *session;
- PK11Object *object;
- PK11FreeStatus status;
-
- /*
- * This whole block just makes sure we really can destroy the
- * requested object.
- */
- session = fort11_SessionFromHandle(hSession, PR_FALSE);
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- object = fort11_ObjectFromHandle(hObject,session);
- if (object == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OBJECT_HANDLE_INVALID);
- }
-
- /* don't destroy a private object if we aren't logged in */
- if ((!slot->isLoggedIn) && (slot->needLogin) &&
- (fort11_isTrue(object,CKA_PRIVATE))) {
- fort11_FreeSession(session);
- fort11_FreeObject(object);
- FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
- }
-
- /* don't destroy a token object if we aren't in a rw session */
-
- if (((session->info.flags & CKF_RW_SESSION) == 0) &&
- (fort11_isTrue(object,CKA_TOKEN))) {
- fort11_FreeSession(session);
- fort11_FreeObject(object);
- FORT11_RETURN (CKR_SESSION_READ_ONLY);
- }
-
- /* ACTUALLY WE NEED TO DEAL WITH TOKEN OBJECTS AS WELL */
- FMUTEX_Lock(session->objectLock);
- fort11_DeleteObject(session,object);
- FMUTEX_Unlock(session->objectLock);
-
- fort11_FreeSession(session);
-
- /*
- * get some indication if the object is destroyed. Note: this is not
- * 100%. Someone may have an object reference outstanding (though that
- * should not be the case by here. Also now that the object is "half"
- * destroyed. Our internal representation is destroyed, but it is still
- * in the data base.
- */
- status = fort11_FreeObject(object);
-
- FORT11_RETURN ((status != PK11_DestroyFailure) ? CKR_OK : CKR_DEVICE_ERROR);
-}
-
-
-/* C_GetObjectSize gets the size of an object in bytes. */
-PR_PUBLIC_API(CK_RV) C_GetObjectSize(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ULONG_PTR pulSize) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- *pulSize = 0;
- return CKR_OK;
-}
-
-
-/* C_GetAttributeValue obtains the value of one or more object attributes. */
-PR_PUBLIC_API(CK_RV) C_GetAttributeValue(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount) {
- FORT11_ENTER()
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- PK11Session *session;
- PK11Object *object;
- PK11Attribute *attribute;
- PRBool sensitive;
- int i;
-
- /*
- * make sure we're allowed
- */
- session = fort11_SessionFromHandle(hSession, PR_FALSE);
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- object = fort11_ObjectFromHandle(hObject,session);
- fort11_FreeSession(session);
- if (object == NULL) {
- FORT11_RETURN (CKR_OBJECT_HANDLE_INVALID);
- }
-
- /* don't read a private object if we aren't logged in */
- if ((!slot->isLoggedIn) && (slot->needLogin) &&
- (fort11_isTrue(object,CKA_PRIVATE))) {
- fort11_FreeObject(object);
- FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
- }
-
- sensitive = fort11_isTrue(object,CKA_SENSITIVE);
- for (i=0; i < (int)ulCount; i++) {
- /* Make sure that this attribute is retrievable */
- if (sensitive && fort11_isSensitive(pTemplate[i].type,object->objclass)) {
- fort11_FreeObject(object);
- FORT11_RETURN (CKR_ATTRIBUTE_SENSITIVE);
- }
- attribute = fort11_FindAttribute(object,pTemplate[i].type);
- if (attribute == NULL) {
- fort11_FreeObject(object);
- FORT11_RETURN (CKR_ATTRIBUTE_TYPE_INVALID);
- }
- if (pTemplate[i].pValue != NULL) {
- PORT_Memcpy(pTemplate[i].pValue,attribute->attrib.pValue,
- attribute->attrib.ulValueLen);
- }
- pTemplate[i].ulValueLen = attribute->attrib.ulValueLen;
- fort11_FreeAttribute(attribute);
- }
-
- fort11_FreeObject(object);
- FORT11_RETURN (CKR_OK);
-}
-
-/* C_SetAttributeValue modifies the value of one or more object attributes */
-PR_PUBLIC_API(CK_RV) C_SetAttributeValue (CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hObject,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-/* C_FindObjectsInit initializes a search for token and session objects
- * that match a template. */
-PR_PUBLIC_API(CK_RV) C_FindObjectsInit(CK_SESSION_HANDLE hSession,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount) {
- FORT11_ENTER()
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- PK11Session *session;
- PK11ObjectListElement *objectList = NULL;
- PK11ObjectListElement *olp;
- PK11SearchResults *search, *freeSearch;
- FortezzaSocket *currSocket;
- int rv, count, i;
-
- if (slot == NULL) {
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
-
- if ((!slot->isLoggedIn) && (slot->needLogin))
- FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
-
- session = fort11_SessionFromHandle(hSession, PR_FALSE);
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
- currSocket = &fortezzaSockets[slot->slotID-1];
- if (currSocket->personalityList == NULL) {
- rv = FetchPersonalityList(currSocket);
- if (rv != SOCKET_SUCCESS) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- rv = fort11_BuildCertObjects(currSocket, slot, session);
-
- if (rv != CKR_OK) {
- fort11_FreeSession(session);
- FORT11_RETURN (rv);
- }
-
-
- }
- rv = fort11_searchObjectList(&objectList, slot->tokObjects,
- slot->objectLock, pTemplate, ulCount);
- if (rv != CKR_OK) {
- fort11_FreeObjectList(objectList);
- fort11_FreeSession(session);
- FORT11_RETURN (rv);
- }
-
- /*copy list to session*/
-
- count = 0;
- for(olp = objectList; olp != NULL; olp = olp->next) {
- count++;
- }
-
- search = (PK11SearchResults *)PORT_Alloc(sizeof(PK11SearchResults));
- if (search != NULL) {
- search->handles = (CK_OBJECT_HANDLE *)
- PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * count);
- if (search->handles != NULL) {
- for (i=0; i < count; i++) {
- search->handles[i] = objectList->object->handle;
- objectList = fort11_FreeObjectListElement(objectList);
- }
- } else {
- PORT_Free(search);
- search = NULL;
- }
- }
- if (search == NULL) {
- fort11_FreeObjectList(objectList);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
- }
-
- /* store the search info */
- search->index = 0;
- search->size = count;
- if ((freeSearch = session->search) != NULL) {
- session->search = NULL;
- fort11_FreeSearch(freeSearch);
- }
- session->search = search;
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_FindObjects continues a search for token and session objects
- * that match a template, obtaining additional object handles. */
-PR_PUBLIC_API(CK_RV) C_FindObjects(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE_PTR phObject,
- CK_ULONG ulMaxObjectCount,
- CK_ULONG_PTR pulObjectCount) {
- FORT11_ENTER()
- PK11Session *session;
- PK11SearchResults *search;
- PK11Slot *slot;
- int transfer;
- unsigned long left;
-
- *pulObjectCount = 0;
- session = fort11_SessionFromHandle(hSession,PR_FALSE);
- slot = fort11_SlotFromSessionHandle(hSession);
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
- if (session->search == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
- }
- search = session->search;
- left = session->search->size - session->search->index;
- transfer = (ulMaxObjectCount > left) ? left : ulMaxObjectCount;
- PORT_Memcpy(phObject,&search->handles[search->index],
- transfer*sizeof(CK_OBJECT_HANDLE_PTR));
- search->index += transfer;
- if (search->index == search->size) {
- session->search = NULL;
- fort11_FreeSearch(search);
- }
- fort11_FreeSession(session);
- *pulObjectCount = transfer;
- FORT11_RETURN (CKR_OK);
-}
-
-/* C_FindObjectsFinal finishes a search for token and session objects. */
-PR_PUBLIC_API(CK_RV) C_FindObjectsFinal(CK_SESSION_HANDLE hSession) {
- FORT11_ENTER()
- PK11Session *session;
- PK11SearchResults *search;
- PK11Slot *slot;
-
- session = fort11_SessionFromHandle(hSession, PR_FALSE);
- slot = fort11_SlotFromSessionHandle(hSession);
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
- search = session->search;
- session->search = NULL;
- if (search == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
- }
- fort11_FreeSearch(search);
-
- /* UnloadPersonalityList(&fortezzaSockets[session->slot->slotID-1]); */
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_EncryptInit initializes an encryption operation. */
-PR_PUBLIC_API(CK_RV) C_EncryptInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- PK11Object *keyObject;
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- FortezzaContext *context;
- HSESSION hs = socket->maciSession;
- FortezzaKey *fortezzaKey;
- CI_IV fortezzaIV;
- int ciRV, registerIndex;
-
-
- if (pMechanism->mechanism != CKM_SKIPJACK_CBC64) {
- if (session) {
- fort11_FreeSession(session);
- }
- FORT11_RETURN (CKR_MECHANISM_INVALID);
- }
-
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- keyObject = fort11_ObjectFromHandle (hKey, session);
-
- if (keyObject == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
- }
-
- ciRV = MACI_Select (hs, slot->slotID);
- if (ciRV != CI_OK) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- ciRV = MACI_SetMode(hs, CI_ENCRYPT_TYPE, CI_CBC64_MODE);
- if (ciRV != CI_OK) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- /*Load the correct key into a key register*/
- fortezzaKey = (FortezzaKey*)keyObject->objectInfo;
- fort11_FreeObject (keyObject);
- if (fortezzaKey == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- if (fortezzaKey->keyRegister == KeyNotLoaded) {
- registerIndex = LoadKeyIntoRegister (fortezzaKey);
- } else {
- registerIndex = fortezzaKey->keyRegister;
- }
-
- if (registerIndex == KeyNotLoaded) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- ciRV = MACI_SetKey (hs,registerIndex);
- if (ciRV != CI_OK) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- ciRV = MACI_GenerateIV(hs, fortezzaIV);
- if (ciRV != CI_OK) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
- context = &session->fortezzaContext;
- InitContext(context, socket, hKey);
- ciRV = SaveState(context, fortezzaIV, session, fortezzaKey,
- CI_ENCRYPT_EXT_TYPE, pMechanism->mechanism);
- if (ciRV != SOCKET_SUCCESS) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- if (pMechanism->pParameter != NULL &&
- pMechanism->ulParameterLen >= sizeof(CI_IV)) {
- PORT_Memcpy (pMechanism->pParameter, fortezzaIV, sizeof(CI_IV));
- }
-
- InitCryptoOperation(context, Encrypt);
- fort11_FreeSession(session);
-
- FORT11_RETURN (CKR_OK);
-}
-
-/* C_Encrypt encrypts single-part data. */
-PR_PUBLIC_API(CK_RV) C_Encrypt (CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG_PTR pulEncryptedDataLen) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- FortezzaContext *context;
- HSESSION hs;
- CK_RV rv;
-
-
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession , PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- context = &session->fortezzaContext;
- if (GetCryptoOperation(context) != Encrypt) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
- }
-
- *pulEncryptedDataLen = ulDataLen;
- if (pEncryptedData == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
- }
-
- hs = socket->maciSession;
- FMUTEX_Lock(socket->registersLock);
- MACI_Lock(hs, CI_BLOCK_LOCK_FLAG);
- rv = EncryptData (context, pData, ulDataLen,
- pEncryptedData, *pulEncryptedDataLen);
- MACI_Unlock(hs);
- FMUTEX_Unlock(socket->registersLock);
-
- if (rv != SOCKET_SUCCESS) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- EndCryptoOperation(context, Encrypt);
- fort11_FreeSession(session);
-
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_EncryptUpdate continues a multiple-part encryption operation. */
-PR_PUBLIC_API(CK_RV) C_EncryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession,PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- FortezzaContext *context;
- int rv;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved (slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- context = &session->fortezzaContext;
-
- if (GetCryptoOperation(context) != Encrypt) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
- }
-
- if (pEncryptedPart == NULL) {
- *pulEncryptedPartLen = ulPartLen;
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
- }
-
- if (*pulEncryptedPartLen < ulPartLen) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
- }
-
- *pulEncryptedPartLen = ulPartLen;
-
- FMUTEX_Lock(socket->registersLock);
- MACI_Lock(socket->maciSession, CI_BLOCK_LOCK_FLAG);
- rv = EncryptData(context,pPart, ulPartLen, pEncryptedPart,
- *pulEncryptedPartLen);
- MACI_Unlock(socket->maciSession);
- FMUTEX_Unlock(socket->registersLock);
-
- fort11_FreeSession(session);
- if (rv != SOCKET_SUCCESS) {
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_EncryptFinal finishes a multiple-part encryption operation. */
-PR_PUBLIC_API(CK_RV) C_EncryptFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastEncryptedPart,
- CK_ULONG_PTR pulLastEncryptedPartLen){
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaContext *context;
- int rv;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- context = &session->fortezzaContext;
-
- rv = EndCryptoOperation(context, Encrypt);
- fort11_FreeSession(session);
-
- FORT11_RETURN (CKR_OK);
-}
-/* C_DecryptInit initializes a decryption operation. */
-PR_PUBLIC_API(CK_RV) C_DecryptInit( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- PK11Object *keyObject;
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- FortezzaContext *context;
- HSESSION hs = socket->maciSession;
- FortezzaKey *fortezzaKey;
- CI_IV fortezzaIV;
- int ciRV, registerIndex;
-
- if (pMechanism->mechanism != CKM_SKIPJACK_CBC64) {
- if (session) fort11_FreeSession(session);
- FORT11_RETURN (CKR_MECHANISM_INVALID);
- }
-
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- keyObject = fort11_ObjectFromHandle (hKey, session);
-
- if (keyObject == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
- }
-
- fortezzaKey = (FortezzaKey*)keyObject->objectInfo;
- fort11_FreeObject(keyObject);
-
- if (fortezzaKey == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- ciRV = MACI_Select (hs, slot->slotID);
- if (ciRV != CI_OK) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- ciRV = MACI_SetMode(hs, CI_DECRYPT_TYPE, CI_CBC64_MODE);
- if (ciRV != CI_OK) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- FMUTEX_Lock(socket->registersLock);
- if (fortezzaKey->keyRegister == KeyNotLoaded) {
- registerIndex = LoadKeyIntoRegister(fortezzaKey);
- } else {
- registerIndex = fortezzaKey->keyRegister;
- }
-
- if (registerIndex == KeyNotLoaded) {
- FMUTEX_Unlock(socket->registersLock);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- if (pMechanism->pParameter == NULL ||
- pMechanism->ulParameterLen < sizeof (CI_IV)) {
- FORT11_RETURN (CKR_MECHANISM_PARAM_INVALID);
- }
-
- PORT_Memcpy (fortezzaIV, pMechanism->pParameter, sizeof(CI_IV));
-
- ciRV = MACI_SetKey (hs, registerIndex);
- if (ciRV != CI_OK) {
- FMUTEX_Unlock(socket->registersLock);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- ciRV = MACI_LoadIV (hs, fortezzaIV);
- if (ciRV != CI_OK) {
- FMUTEX_Unlock(socket->registersLock);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- context = &session->fortezzaContext;
- InitContext(context, socket, hKey);
- ciRV = SaveState (context, fortezzaIV, session, fortezzaKey,
- CI_DECRYPT_EXT_TYPE, pMechanism->mechanism);
-
- FMUTEX_Unlock(socket->registersLock);
-
- if (ciRV != SOCKET_SUCCESS) {
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- InitCryptoOperation (context, Decrypt);
- fort11_FreeSession (session);
-
- FORT11_RETURN (CKR_OK);
-}
-
-/* C_Decrypt decrypts encrypted data in a single part. */
-PR_PUBLIC_API(CK_RV) C_Decrypt(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- FortezzaContext *context;
- HSESSION hs;
- CK_RV rv;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- context = &session->fortezzaContext;
-
- if (GetCryptoOperation(context) != Decrypt) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
- }
-
- *pulDataLen = ulEncryptedDataLen;
- if (pData == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
- }
-
- hs = socket->maciSession;
- FMUTEX_Lock(socket->registersLock);
- MACI_Lock(hs, CI_NULL_FLAG);
- rv = DecryptData (context, pEncryptedData, ulEncryptedDataLen,
- pData, *pulDataLen);
- MACI_Unlock(hs);
- FMUTEX_Unlock(socket->registersLock);
- if (rv != SOCKET_SUCCESS) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- EndCryptoOperation (context, Decrypt);
- fort11_FreeSession(session);
-
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_DecryptUpdate continues a multiple-part decryption operation. */
-PR_PUBLIC_API(CK_RV) C_DecryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession,PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- FortezzaContext *context;
- HSESSION hs;
- int rv;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved (slot, session);
- fort11_FreeSession (session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- context = &session->fortezzaContext;
- hs = socket->maciSession;
-
- if (GetCryptoOperation(context) != Decrypt) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
- }
-
- if (pPart == NULL) {
- *pulPartLen = ulEncryptedPartLen;
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
- }
-
- *pulPartLen = ulEncryptedPartLen;
-
- FMUTEX_Lock(socket->registersLock);
- MACI_Lock (hs, CI_NULL_FLAG);
- rv = DecryptData (context, pEncryptedPart, ulEncryptedPartLen, pPart,
- *pulPartLen);
- MACI_Unlock(hs);
- FMUTEX_Unlock(socket->registersLock);
-
- fort11_FreeSession(session);
-
- if (rv != SOCKET_SUCCESS) {
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_DecryptFinal finishes a multiple-part decryption operation. */
-PR_PUBLIC_API(CK_RV) C_DecryptFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pLastPart,
- CK_ULONG_PTR pulLastPartLen) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaContext *context;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved (slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- context = &session->fortezzaContext;
- EndCryptoOperation (context, Decrypt);
-
- fort11_FreeSession(session);
-
- FORT11_RETURN (CKR_OK);
-}
-
-
-/*
- ************** Crypto Functions: Digest (HASH) ************************
- */
-
-/* C_DigestInit initializes a message-digesting operation. */
-PR_PUBLIC_API(CK_RV) C_DigestInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_Digest digests data in a single part. */
-PR_PUBLIC_API(CK_RV) C_Digest(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_DigestUpdate continues a multiple-part message-digesting operation. */
-PR_PUBLIC_API(CK_RV) C_DigestUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_DigestFinal finishes a multiple-part message-digesting operation. */
-PR_PUBLIC_API(CK_RV) C_DigestFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pDigest,
- CK_ULONG_PTR pulDigestLen) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/*
- ************** Crypto Functions: Sign ************************
- */
-
-/* C_SignInit initializes a signature (private key encryption) operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-PR_PUBLIC_API(CK_RV) C_SignInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- PK11Object *keyObject;
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- FortezzaContext *context;
- PK11Attribute *idAttribute;
- int personalityIndex;
- HSESSION hs = socket->maciSession;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- if (pMechanism->mechanism != CKM_DSA) {
- FORT11_RETURN (CKR_MECHANISM_INVALID);
- }
-
- keyObject = fort11_ObjectFromHandle (hKey, session);
-
- if (keyObject == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
- }
-
- context = &session->fortezzaContext;
- InitContext(context, socket, hKey);
- InitCryptoOperation (context, Sign);
- fort11_FreeSession(session);
-
- idAttribute = fort11_FindAttribute(keyObject, CKA_ID);
- fort11_FreeObject(keyObject);
-
- if (idAttribute == NULL) {
- FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
- }
-
- personalityIndex = *(int*)(idAttribute->attrib.pValue);
- fort11_FreeAttribute(idAttribute);
-
- MACI_Select (hs, slot->slotID);
- if (MACI_SetPersonality (hs,personalityIndex) != CI_OK) {
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_Sign signs (encrypts with private key) data in a single part,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-PR_PUBLIC_API(CK_RV) C_Sign(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen) {
-
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaContext *context;
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- HSESSION hs = socket->maciSession;
- PK11Object *keyObject;
- PK11Attribute *idAttribute;
- int ciRV, personalityIndex;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved (slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
-
- context = &session->fortezzaContext;
- if (GetCryptoOperation(context) != Sign) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OPERATION_NOT_INITIALIZED);
- }
-
- if (pSignature == NULL) {
- *pulSignatureLen = 40;
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
- }
-
- if (ulDataLen > 20) {
- FORT11_RETURN (CKR_DATA_LEN_RANGE);
- }
-
- if (*pulSignatureLen < 40) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
- }
- *pulSignatureLen = 40;
-
- keyObject = fort11_ObjectFromHandle(context->hKey, session);
- if (keyObject == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN(CKR_GENERAL_ERROR);
- }
-
- idAttribute = fort11_FindAttribute(keyObject, CKA_ID);
- fort11_FreeObject(keyObject);
-
- personalityIndex = *(int*)(idAttribute->attrib.pValue);
- fort11_FreeAttribute(idAttribute);
-
- MACI_Select(hs, slot->slotID);
-
- MACI_Lock(hs, CI_BLOCK_LOCK_FLAG);
- ciRV = MACI_SetPersonality(hs, personalityIndex);
- if (ciRV != CI_OK) {
- MACI_Unlock(hs);
- fort11_FreeSession(session);
- FORT11_RETURN(CKR_DEVICE_ERROR);
- }
-
- ciRV = MACI_Sign (hs, pData, pSignature);
- if (ciRV != CI_OK) {
- MACI_Unlock(hs);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- MACI_Unlock(hs);
- EndCryptoOperation (context, Sign);
- fort11_FreeSession(session);
-
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-PR_PUBLIC_API(CK_RV) C_SignUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_SignFinal finishes a multiple-part signature operation,
- * FORT11_RETURNing the signature. */
-PR_PUBLIC_API(CK_RV) C_SignFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-/*
- ************** Crypto Functions: Sign Recover ************************
- */
-/* C_SignRecoverInit initializes a signature operation,
- * where the (digest) data can be recovered from the signature.
- * E.g. encryption with the user's private key */
-PR_PUBLIC_API(CK_RV) C_SignRecoverInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_SignRecover signs data in a single operation
- * where the (digest) data can be recovered from the signature.
- * E.g. encryption with the user's private key */
-PR_PUBLIC_API(CK_RV) C_SignRecover(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG_PTR pulSignatureLen) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-/*
- ************** Crypto Functions: verify ************************
- */
-
-/* C_VerifyInit initializes a verification operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature (e.g. DSA) */
-PR_PUBLIC_API(CK_RV) C_VerifyInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_Verify verifies a signature in a single-part operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-PR_PUBLIC_API(CK_RV) C_Verify(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pData,
- CK_ULONG ulDataLen,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_VerifyUpdate continues a multiple-part verification operation,
- * where the signature is an appendix to the data,
- * and plaintext cannot be recovered from the signature */
-PR_PUBLIC_API(CK_RV) C_VerifyUpdate( CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen) {
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_VerifyFinal finishes a multiple-part verification operation,
- * checking the signature. */
-PR_PUBLIC_API(CK_RV) C_VerifyFinal(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-/*
- ************** Crypto Functions: Verify Recover ************************
- */
-
-/* C_VerifyRecoverInit initializes a signature verification operation,
- * where the data is recovered from the signature.
- * E.g. Decryption with the user's public key */
-PR_PUBLIC_API(CK_RV) C_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hKey) {
- /* For functions that don't access globals, we don't have to worry about the
- * stack.
- */
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_VerifyRecover verifies a signature in a single-part operation,
- * where the data is recovered from the signature.
- * E.g. Decryption with the user's public key */
-PR_PUBLIC_API(CK_RV) C_VerifyRecover(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSignature,
- CK_ULONG ulSignatureLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen) {
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-/*
- **************************** Key Functions: ************************
- */
-
-#define MAX_KEY_LEN 256
-/* C_GenerateKey generates a secret key, creating a new key object. */
-PR_PUBLIC_API(CK_RV) C_GenerateKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulCount,
- CK_OBJECT_HANDLE_PTR phKey) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- PK11Object *key;
- FortezzaKey *newKey;
- int i, keyRegister;
- CK_ULONG key_length = 0;
- CK_RV crv = CKR_OK;
- CK_OBJECT_CLASS secretKey = CKO_SECRET_KEY;
- CK_BBOOL False = FALSE;
- CK_BBOOL cktrue = TRUE;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved (slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
- if (pMechanism->mechanism != CKM_SKIPJACK_KEY_GEN) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_MECHANISM_INVALID);
- }
-
- key = fort11_NewObject(slot);
-
- if (key == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_HOST_MEMORY);
- }
-
- for (i=0; i < (int) ulCount; i++) {
- if (pTemplate[i].type == CKA_VALUE_LEN) {
- key_length = *(CK_ULONG *)pTemplate[i].pValue;
- continue;
- }
- crv = fort11_AddAttributeType (key, pk11_attr_expand (&pTemplate[i]));
- if (crv != CKR_OK)
- break;
- }
-
- if (crv != CKR_OK) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (crv);
- }
-
- /* make sure we don't have any class, key_type, or value fields */
- fort11_DeleteAttributeType(key,CKA_CLASS);
- fort11_DeleteAttributeType(key,CKA_KEY_TYPE);
- fort11_DeleteAttributeType(key,CKA_VALUE);
-
- if (MAX_KEY_LEN < key_length) {
- crv = CKR_TEMPLATE_INCONSISTENT;
- }
-
- if (crv != CKR_OK) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (crv);
- }
-
- if (fort11_AddAttributeType(key, CKA_CLASS,&secretKey,
- sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- if (fort11_AddAttributeType(key, CKA_TOKEN, &False,
- sizeof(CK_BBOOL)) != CKR_OK) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- if (fort11_isTrue(key,CKA_SENSITIVE)) {
- fort11_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,
- sizeof(CK_BBOOL));
- }
- if (!fort11_isTrue(key,CKA_EXTRACTABLE)) {
- fort11_forceAttribute(key,CKA_NEVER_EXTRACTABLE,&cktrue,
- sizeof(CK_BBOOL));
- }
-
- FMUTEX_Lock(socket->registersLock);
-
- keyRegister = GetBestKeyRegister(socket);
- newKey = NewFortezzaKey(socket, MEK, NULL, keyRegister);
-
- FMUTEX_Unlock(socket->registersLock);
-
- if (newKey == NULL) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_HOST_MEMORY);
- }
-
- key->objectInfo = (void*)newKey;
- key->infoFree = fort11_FreeFortezzaKey;
-
- FMUTEX_Lock(slot->objectLock);
- key->handle = slot->tokenIDCount++;
- key->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- FMUTEX_Unlock(slot->objectLock);
-
- key->objclass = secretKey;
- key->slot = slot;
- key->inDB = PR_TRUE;
-
- fort11_AddObject(session, key);
- fort11_FreeSession(session);
- SetFortezzaKeyHandle(newKey, key->handle);
- *phKey = key->handle;
-
- FORT11_RETURN (CKR_OK);
-
-}
-
-
-/* C_GenerateKeyPair generates a public-key/private-key pair,
- * creating new key objects. */
-PR_PUBLIC_API(CK_RV) C_GenerateKeyPair
- (CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_ATTRIBUTE_PTR pPublicKeyTemplate,
- CK_ULONG ulPublicKeyAttributeCount,
- CK_ATTRIBUTE_PTR pPrivateKeyTemplate,
- CK_ULONG ulPrivateKeyAttributeCount,
- CK_OBJECT_HANDLE_PTR phPrivateKey,
- CK_OBJECT_HANDLE_PTR phPublicKey) {
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-/* C_WrapKey wraps (i.e., encrypts) a key. */
-PR_PUBLIC_API(CK_RV) C_WrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hWrappingKey,
- CK_OBJECT_HANDLE hKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG_PTR pulWrappedKeyLen) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle (hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- PK11Object *wrapKey;
- PK11Object *srcKey;
- FortezzaKey *wrapFortKey;
- FortezzaKey *srcFortKey;
- int rv;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- if (!socket->isLoggedIn) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
- }
-
- if (pMechanism->mechanism != CKM_SKIPJACK_WRAP) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_MECHANISM_INVALID);
- }
-
- wrapKey = fort11_ObjectFromHandle (hWrappingKey, session);
- if ((wrapKey == NULL) || (wrapKey->objectInfo == NULL)) {
- if (wrapKey)
- fort11_FreeObject(wrapKey);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
- }
-
- srcKey = fort11_ObjectFromHandle (hKey, session);
- fort11_FreeSession(session);
- if ((srcKey == NULL) || (srcKey->objectInfo == NULL)) {
- FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
- }
-
- wrapFortKey = (FortezzaKey*)wrapKey->objectInfo;
- fort11_FreeObject(wrapKey);
-
- srcFortKey = (FortezzaKey*)srcKey->objectInfo;
- fort11_FreeObject(srcKey);
-
- FMUTEX_Lock(socket->registersLock);
- if (wrapFortKey->keyRegister == KeyNotLoaded) {
- if (LoadKeyIntoRegister(wrapFortKey) == KeyNotLoaded) {
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
- }
-
- if (srcFortKey->keyRegister == KeyNotLoaded) {
- if (LoadKeyIntoRegister(srcFortKey) == KeyNotLoaded) {
- FMUTEX_Unlock(socket->registersLock);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
- }
-
- MACI_Lock(socket->maciSession, CI_BLOCK_LOCK_FLAG);
- rv = WrapKey (wrapFortKey, srcFortKey, pWrappedKey, *pulWrappedKeyLen);
- MACI_Unlock(socket->maciSession);
- FMUTEX_Unlock(socket->registersLock);
-
- if (rv != SOCKET_SUCCESS) {
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new key object. */
-PR_PUBLIC_API(CK_RV) C_UnwrapKey(CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hUnwrappingKey,
- CK_BYTE_PTR pWrappedKey,
- CK_ULONG ulWrappedKeyLen,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- PK11Object *wrapKey;
- PK11Object *newKey;
- FortezzaKey *fortKey;
- FortezzaKey *unwrapFort;
- CK_ULONG key_length;
- int i, newKeyRegister;
- CK_RV crv = CKR_OK;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- if (pMechanism->mechanism != CKM_SKIPJACK_WRAP){
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_MECHANISM_INVALID);
- }
-
- if (!socket->isLoggedIn) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_USER_NOT_LOGGED_IN);
- }
-
- wrapKey = fort11_ObjectFromHandle(hUnwrappingKey, session);
- if (wrapKey == NULL || wrapKey->objectInfo == NULL) {
- if (wrapKey)
- fort11_FreeObject(wrapKey);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_UNWRAPPING_KEY_HANDLE_INVALID);
- }
-
- fortKey = (FortezzaKey*)wrapKey->objectInfo;
- fort11_FreeObject(wrapKey);
-
- newKey = fort11_NewObject(slot);
- if (newKey == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_HOST_MEMORY);
- }
-
- for (i=0; i< (int)ulAttributeCount; i++) {
- if (pTemplate[i].type == CKA_VALUE_LEN) {
- key_length = *(CK_ULONG*)pTemplate[i].pValue;
- continue;
- }
- crv=fort11_AddAttributeType(newKey,fort11_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) {
- break;
- }
- }
-
- if (crv != CKR_OK) {
- fort11_FreeSession(session);
- fort11_FreeObject(newKey);
- FORT11_RETURN (crv);
- }
-
- /* make sure we don't have any class, key_type, or value fields */
- if (!fort11_hasAttribute(newKey,CKA_CLASS)) {
- fort11_FreeObject(newKey);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_TEMPLATE_INCOMPLETE);
- }
- if (!fort11_hasAttribute(newKey,CKA_KEY_TYPE)) {
- fort11_FreeObject(newKey);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_TEMPLATE_INCOMPLETE);
- }
-
- FMUTEX_Lock(socket->registersLock);
- newKeyRegister = UnwrapKey (pWrappedKey, fortKey);
- if (newKeyRegister == KeyNotLoaded) {
- /*Couldn't Unwrap the key*/
- fort11_FreeObject(newKey);
- fort11_FreeSession(session);
- FMUTEX_Unlock(socket->registersLock);
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- unwrapFort = NewUnwrappedKey(newKeyRegister, fortKey->id, socket);
- FMUTEX_Unlock(socket->registersLock);
-
- if (unwrapFort == NULL) {
- fort11_FreeObject(newKey);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_HOST_MEMORY);
- }
- newKey->objectInfo = unwrapFort;
- newKey->infoFree = fort11_FreeFortezzaKey;
-
- FMUTEX_Lock(slot->objectLock);
- newKey->handle = slot->tokenIDCount++;
- newKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- FMUTEX_Unlock(slot->objectLock);
- newKey->objclass = CKO_SECRET_KEY;
- newKey->slot = slot;
- newKey->inDB = PR_TRUE;
-
- fort11_AddObject (session, newKey);
- fort11_FreeSession(session);
-
- SetFortezzaKeyHandle(unwrapFort, newKey->handle);
- *phKey = newKey->handle;
-
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_DeriveKey derives a key from a base key, creating a new key object. */
-PR_PUBLIC_API(CK_RV) C_DeriveKey( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism,
- CK_OBJECT_HANDLE hBaseKey,
- CK_ATTRIBUTE_PTR pTemplate,
- CK_ULONG ulAttributeCount,
- CK_OBJECT_HANDLE_PTR phKey) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaSocket *socket = &fortezzaSockets[slot->slotID-1];
- PK11Object *key, *sourceKey;
- CK_ULONG i;
- CK_ULONG key_length = 0;
- CK_RV crv = 0;
- CK_KEY_TYPE keyType = CKK_SKIPJACK;
- CK_OBJECT_CLASS classType = CKO_SECRET_KEY;
- CK_BBOOL ckTrue = TRUE;
- CK_BBOOL ckFalse = FALSE;
- int ciRV;
- int personality;
- PK11Attribute *att;
-
- CK_KEA_DERIVE_PARAMS_PTR params;
- FortezzaKey *derivedKey;
- CreateTEKInfo tekInfo;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved (slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- if (pMechanism->mechanism != CKM_KEA_KEY_DERIVE) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_MECHANISM_INVALID);
- }
-
- key = fort11_NewObject (slot);
-
- if (key == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_HOST_MEMORY);
- }
-
- for (i = 0; i < ulAttributeCount; i++) {
- crv = fort11_AddAttributeType (key, fort11_attr_expand(&pTemplate[i]));
- if (crv != CKR_OK) {
- break;
- }
- if (pTemplate[i].type == CKA_KEY_TYPE) {
- keyType = *(CK_KEY_TYPE*)pTemplate[i].pValue;
- } else if (pTemplate[i].type == CKA_VALUE_LEN) {
- key_length = *(CK_ULONG*)pTemplate[i].pValue;
- }
- }
-
- if (crv != CKR_OK) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (crv);
- }
-
- if (key_length == 0) {
- key_length = 12;
- }
-
- classType = CKO_SECRET_KEY;
- crv = fort11_forceAttribute (key, CKA_CLASS, &classType,
- sizeof(classType));
- if (crv != CKR_OK) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (crv);
- }
- crv = fort11_forceAttribute (key, CKA_SENSITIVE, &ckTrue,
- sizeof(CK_BBOOL));
- if (crv != CKR_OK) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (crv);
- }
- crv = fort11_forceAttribute (key, CKA_EXTRACTABLE, &ckFalse,
- sizeof(CK_BBOOL));
- if (crv != CKR_OK) {
- fort11_FreeSession(session);
- fort11_FreeObject(key);
- FORT11_RETURN (crv);
- }
-
- sourceKey = fort11_ObjectFromHandle (hBaseKey, session);
-
- if (sourceKey == NULL) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
- }
-
- att = fort11_FindAttribute(sourceKey,CKA_ID);
- fort11_FreeObject(sourceKey);
- if (att == NULL) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_KEY_TYPE_INCONSISTENT);
- }
- personality = *(int *) att->attrib.pValue;
- fort11_FreeAttribute(att);
-
- params = (CK_KEA_DERIVE_PARAMS_PTR)pMechanism->pParameter;
-
- if (params == NULL) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_MECHANISM_PARAM_INVALID);
- }
-
- ciRV = MACI_SetPersonality(socket->maciSession,personality);
- if (ciRV != CI_OK) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
- /*
- * If we're sending, generate our own RA.
- */
- if (params->isSender) {
- ciRV = MACI_GenerateRa(socket->maciSession,params->pRandomA);
- if (ciRV != CI_OK) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
- }
- PORT_Memcpy (tekInfo.Ra, params->pRandomA, params->ulRandomLen);
- PORT_Memcpy (tekInfo.Rb, params->pRandomB, params->ulRandomLen);
- tekInfo.randomLen = params->ulRandomLen;
- tekInfo.personality = personality;
- tekInfo.flag = (params->isSender) ? CI_INITIATOR_FLAG : CI_RECIPIENT_FLAG;
-
- PORT_Memcpy (tekInfo.pY, params->pPublicData, params->ulPublicDataLen);
- tekInfo.YSize = params->ulPublicDataLen;
-
- FMUTEX_Lock(socket->registersLock);
- derivedKey = NewFortezzaKey(socket, TEK, &tekInfo,
- GetBestKeyRegister(socket));
- FMUTEX_Unlock(socket->registersLock);
-
- if (derivedKey == NULL) {
- fort11_FreeObject(key);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_GENERAL_ERROR);
- }
-
- key->objectInfo = derivedKey;
- key->infoFree = fort11_FreeFortezzaKey;
-
- FMUTEX_Lock(slot->objectLock);
- key->handle = slot->tokenIDCount++;
- key->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- FMUTEX_Unlock(slot->objectLock);
- key->objclass = classType;
- key->slot = slot;
- key->inDB = PR_TRUE;
-
- fort11_AddObject (session, key);
- fort11_FreeSession(session);
-
- SetFortezzaKeyHandle(derivedKey, key->handle);
- *phKey = key->handle;
-
- FORT11_RETURN (CKR_OK);
-}
-
-/*
- **************************** Random Functions: ************************
- */
-
-/* C_SeedRandom mixes additional seed material into the token's random number
- * generator. */
-PR_PUBLIC_API(CK_RV) C_SeedRandom(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pSeed,
- CK_ULONG ulSeedLen) {
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_GenerateRandom generates random data. */
-PR_PUBLIC_API(CK_RV) C_GenerateRandom(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pRandomData,
- CK_ULONG ulRandomLen) {
- FORT11_ENTER()
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- PK11Session *session = fort11_SessionFromHandle(hSession,PR_FALSE);
- CI_RANDOM randomNum;
- CK_ULONG randomSize = sizeof (CI_RANDOM);
- int ciRV;
- CK_ULONG bytesCopied = 0, bytesToCopy;
- CK_ULONG bufferSize = 0, bytesRemaining;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle (hSession, PR_TRUE);
- fort11_TokenRemoved(slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- fort11_FreeSession(session);
- ciRV = MACI_Select(fortezzaSockets[slot->slotID-1].maciSession,
- slot->slotID);
- if (ciRV != CI_OK) {
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- while (bytesCopied < ulRandomLen) {
- bytesRemaining = ulRandomLen - bytesCopied;
- if (bufferSize < bytesRemaining) {
- ciRV =
- MACI_GenerateRandom(fortezzaSockets[slot->slotID-1].maciSession,
- randomNum);
- if (ciRV != CI_OK)
- FORT11_RETURN (CKR_DEVICE_ERROR);
- bufferSize = randomSize;
- }
- bytesToCopy = (bytesRemaining > randomSize) ? randomSize :
- bytesRemaining;
-
- PORT_Memcpy (&pRandomData[bytesCopied],
- &randomNum[randomSize-bufferSize], bytesToCopy);
-
- bytesCopied += bytesToCopy;
- bufferSize -= bytesToCopy;
- }
-
- FORT11_RETURN (CKR_OK);
-}
-
-
-/* C_GetFunctionStatus obtains an updated status of a function running
- * in parallel with an application. */
-PR_PUBLIC_API(CK_RV) C_GetFunctionStatus(CK_SESSION_HANDLE hSession) {
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_CancelFunction cancels a function running in parallel */
-PR_PUBLIC_API(CK_RV) C_CancelFunction(CK_SESSION_HANDLE hSession) {
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-/* C_GetOperationState saves the state of the cryptographic
- *operation in a session. */
-PR_PUBLIC_API(CK_RV) C_GetOperationState(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG_PTR pulOperationStateLen) {
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaContext *context;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved (slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- if (pOperationState == NULL) {
- *pulOperationStateLen = sizeof (FortezzaContext);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_OK);
- }
-
- if (*pulOperationStateLen < sizeof (FortezzaContext)) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_BUFFER_TOO_SMALL);
- }
-
- context = &session->fortezzaContext;
- fort11_FreeSession(session);
- PORT_Memcpy (pOperationState, context, sizeof(FortezzaContext));
- ((FortezzaContext *)pOperationState)->session = NULL;
- ((FortezzaContext *)pOperationState)->fortezzaKey = NULL;
- *pulOperationStateLen = sizeof(FortezzaContext);
- FORT11_RETURN (CKR_OK);
-}
-
-
-
-/* C_SetOperationState restores the state of the cryptographic operation in a session. */
-PR_PUBLIC_API(CK_RV) C_SetOperationState(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pOperationState,
- CK_ULONG ulOperationStateLen,
- CK_OBJECT_HANDLE hEncryptionKey,
- CK_OBJECT_HANDLE hAuthenticationKey){
- FORT11_ENTER()
- PK11Session *session = fort11_SessionFromHandle(hSession, PR_FALSE);
- PK11Slot *slot = fort11_SlotFromSessionHandle(hSession);
- FortezzaContext *context;
- FortezzaContext passedInCxt;
- PK11Object *keyObject;
- FortezzaKey *fortKey;
-
- if (session == NULL) {
- session = fort11_SessionFromHandle(hSession, PR_TRUE);
- fort11_TokenRemoved (slot, session);
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SESSION_HANDLE_INVALID);
- }
-
- if (ulOperationStateLen != sizeof(FortezzaContext)) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SAVED_STATE_INVALID);
- }
-
- PORT_Memcpy(&passedInCxt, pOperationState, sizeof(FortezzaContext));
- if (passedInCxt.fortezzaSocket->slotID != slot->slotID) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SAVED_STATE_INVALID);
- }
- passedInCxt.session = NULL;
- passedInCxt.fortezzaKey = NULL;
-
- if (hEncryptionKey != 0) {
- keyObject = fort11_ObjectFromHandle(hEncryptionKey, session);
- if (keyObject == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_KEY_HANDLE_INVALID);
- }
- fortKey = (FortezzaKey*)keyObject->objectInfo;
- fort11_FreeObject(keyObject);
- if (fortKey == NULL) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_SAVED_STATE_INVALID);
- }
- if (fortKey->keyRegister == KeyNotLoaded) {
- if (LoadKeyIntoRegister (fortKey) == KeyNotLoaded) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
- }
- passedInCxt.fortezzaKey = fortKey;
-
- }
- if (hAuthenticationKey != 0) {
- fort11_FreeSession(session);
- FORT11_RETURN (CKR_DEVICE_ERROR);
- }
-
- passedInCxt.session = session;
- context = &session->fortezzaContext;
- fort11_FreeSession (session);
- PORT_Memcpy (context, &passedInCxt, sizeof(passedInCxt));
-
- FORT11_RETURN (CKR_OK);
-}
-
-/* Dual-function cryptographic operations */
-
-/* C_DigestEncryptUpdate continues a multiple-part digesting and
- encryption operation. */
-PR_PUBLIC_API(CK_RV) C_DigestEncryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen){
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_DecryptDigestUpdate continues a multiple-part decryption and digesting
- operation. */
-PR_PUBLIC_API(CK_RV) C_DecryptDigestUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG ulEncryptedPartLen,
- CK_BYTE_PTR pPart,
- CK_ULONG_PTR pulPartLen){
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_SignEncryptUpdate continues a multiple-part signing and encryption
- operation. */
-PR_PUBLIC_API(CK_RV) C_SignEncryptUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pPart,
- CK_ULONG ulPartLen,
- CK_BYTE_PTR pEncryptedPart,
- CK_ULONG_PTR pulEncryptedPartLen){
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-
-/* C_DecryptVerifyUpdate continues a multiple-part decryption and verify
- operation. */
-PR_PUBLIC_API(CK_RV) C_DecryptVerifyUpdate(CK_SESSION_HANDLE hSession,
- CK_BYTE_PTR pEncryptedData,
- CK_ULONG ulEncryptedDataLen,
- CK_BYTE_PTR pData,
- CK_ULONG_PTR pulDataLen){
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-/* C_DigestKey continues a multi-part message-digesting operation,
- * by digesting the value of a secret key as part of the data already digested.
- */
-PR_PUBLIC_API(CK_RV) C_DigestKey(CK_SESSION_HANDLE hSession,
- CK_OBJECT_HANDLE hKey) {
- return CKR_FUNCTION_NOT_SUPPORTED;
-}
-
-PR_PUBLIC_API(CK_RV) C_WaitForSlotEvent(CK_FLAGS flags,
- CK_SLOT_ID_PTR pSlot,
- CK_VOID_PTR pRserved) {
- return CKR_FUNCTION_FAILED;
-}
-