Ejemplo n.º 1
0
CK_DEFINE_FUNCTION(CK_RV, C_InitPIN)
(
    CK_SESSION_HANDLE hSession,
    CK_UTF8CHAR_PTR pPin,
    CK_ULONG ulPinLen
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret != CKR_OK) return ret;

    if(pSession->State != RWSecurityOfficer)
    {
        return CKR_USER_NOT_LOGGED_IN;
    }
    
    if(pSession->Token->SessionMgmt != NULL && pSession->Token->SessionMgmt->InitPin != NULL)
    {
        ret = pSession->Token->SessionMgmt->InitPin(&pSession->Context, pPin, ulPinLen);
    }
    else
    {
        ret = CKR_FUNCTION_NOT_SUPPORTED;
    }
    
    return ret;
}
Ejemplo n.º 2
0
/* C_Logout logs a user out from a token. */
CK_DEFINE_FUNCTION(CK_RV, C_Logout)
(
  CK_SESSION_HANDLE hSession  /* the session's handle */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret != CKR_OK) return ret;

    if(pSession->State <= RWPublic && pSession->State != ROUser) return CKR_USER_NOT_LOGGED_IN;

    if(pSession->Token->SessionMgmt == NULL)
    {
        ret = pSession->Token->SessionMgmt->Logout(&pSession->Context);
    }

    // back to public session (ro or rw)
    pSession->State = (CryptokiSessionState)((pSession->State & ReadWriteFlag) | ROPublic);

    if(pSession->IsLoginContext)
    {
        pSession->IsLoginContext = FALSE;
    }
    else
    {
        pSession->Token->TokenWideState = ROPublic;
    }

    return ret;
}
Ejemplo n.º 3
0
/* C_DestroyObject destroys an object. */
CK_DEFINE_FUNCTION(CK_RV, C_DestroyObject)
(
  CK_SESSION_HANDLE hSession,  /* the session's handle */
  CK_OBJECT_HANDLE  hObject    /* the object's handle */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret != CKR_OK) return ret;

    if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->DestroyObject)
    {
        ret = pSession->Token->ObjectMgmt->DestroyObject(&pSession->Context, hObject);

#ifdef _DEBUG
        pSession->RemoveObjectHandle(hObject);
#endif        
        
        return ret;
    }

    return CKR_FUNCTION_NOT_SUPPORTED;
}
Ejemplo n.º 4
0
/* C_CopyObject copies an object, creating a new object for the
 * copy. */
CK_DEFINE_FUNCTION(CK_RV, C_CopyObject)
(
  CK_SESSION_HANDLE    hSession,    /* the session's handle */
  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
  CK_ULONG             ulCount,     /* attributes in template */
  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret         != CKR_OK) return ret;
    if(pTemplate   == NULL  ) return CKR_ARGUMENTS_BAD;
    if(phNewObject == NULL  ) return CKR_ARGUMENTS_BAD;

    if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->CopyObject)
    {
        ret = pSession->Token->ObjectMgmt->CopyObject(&pSession->Context, hObject, pTemplate, ulCount, phNewObject);
        
#ifdef _DEBUG
        if(ret == CKR_OK)
        {
            pSession->AddObjectHandle(*phNewObject);
        }
#endif

        return ret;
    }

    return CKR_FUNCTION_NOT_SUPPORTED;
}
Ejemplo n.º 5
0
/* C_Login logs a user into a token. */
CK_DEFINE_FUNCTION(CK_RV, C_Login)
(
  CK_SESSION_HANDLE hSession,  /* the session's handle */
  CK_USER_TYPE      userType,  /* the user type */
  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
  CK_ULONG          ulPinLen   /* the length of the PIN */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret != CKR_OK) return ret;
    if(userType > 2 ) return CKR_USER_TYPE_INVALID;

    if(pSession->State > RWPublic || pSession->State == ROUser)             return CKR_USER_ALREADY_LOGGED_IN;
    if(pSession->Token->TokenInfo.ulSessionCount > 0 && userType == CKU_SO) return CKR_SESSION_READ_ONLY_EXISTS;
    if(pSession->Token->TokenWideState != ROPublic)                         return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;

    if(pSession->Token->SessionMgmt == NULL)
    {
        if(CKR_OK == (ret = pSession->Token->SessionMgmt->Login(&pSession->Context, userType, pPin, ulPinLen)))
        {
            // use |= to maintain the r/w flag
            pSession->State = (CryptokiSessionState)((pSession->State & ReadWriteFlag) | (userType == CKU_SO ? RWSecurityOfficer : ROUser));
        }
    }
    else
    {
        // TODO: blindly accept or check PIN with encrypted pin stored somewhere?
        pSession->State = (CryptokiSessionState)((pSession->State & ReadWriteFlag) | (userType == CKU_SO ? RWSecurityOfficer : ROUser));
    }

    if(userType == CKU_CONTEXT_SPECIFIC)
    {
        pSession->IsLoginContext = TRUE;
    }
    else
    {
        // don't store read/write since that is session specific
        pSession->Token->TokenWideState = (CryptokiSessionState)(userType == CKU_SO ? ROUser + 1 : ROUser);
    }
    

    return ret;
}
Ejemplo n.º 6
0
/* C_CloseSession closes a session between an application and a
 * Token. */
CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)
(
  CK_SESSION_HANDLE hSession  /* the session's handle */
)
{
    CryptokiSession* pSession = NULL;
    CK_SLOT_ID slotID;

    CK_RV ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret != CKR_OK)
    {
        return ret;
    }

    return CloseSession(pSession, slotID);
}
Ejemplo n.º 7
0
CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)
(
  CK_SESSION_HANDLE   hSession,  /* the session's handle */
  CK_SESSION_INFO_PTR pInfo      /* receives session info */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;
    CK_ULONG devError = 0;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret != CKR_OK) return ret;
    if(pInfo == NULL) return CKR_ARGUMENTS_BAD;

    pInfo->slotID        = slotID;

    pInfo->state         = NETMF_CRYPTOKI_SESSION_STATE_CONVERT(pSession->State);
    pInfo->flags         = CKF_SERIAL_SESSION | (NETMF_CRYPTOKI_SESSION_IS_RW(pSession->State) ? CKF_RW_SESSION : 0);
    pInfo->ulDeviceError = 0;

    if(pSession->Token != NULL && pSession->Token->TokenState)
    {
        if(pSession->Token->TokenState->GetDeviceError != NULL) pSession->Token->TokenState->GetDeviceError(&devError);

        pInfo->ulDeviceError = devError;

        // if this session is not logged in and the CKU_SO or CKU_USER is logged in, then use the token wide
        // session state.
        if( !NETMF_CRYPTOKI_SESSION_IS_PUBLIC(pSession->Token->TokenWideState) && 
            NETMF_CRYPTOKI_SESSION_IS_PUBLIC(pSession->State))
        {
            // RWSecurityOfficer can not change a RO session
            if((pSession->Token->TokenWideState | ReadWriteFlag) != RWSecurityOfficer ||
                NETMF_CRYPTOKI_SESSION_IS_RW(pSession->State))
            {
                pInfo->state = NETMF_CRYPTOKI_SESSION_STATE_CONVERT_TOKEN(pSession->Token->TokenWideState, pSession->State);
            }
        }
    }

    return CKR_OK;
}
Ejemplo n.º 8
0
CK_DEFINE_FUNCTION(CK_RV, C_SetPIN)
(
  CK_SESSION_HANDLE hSession,  /* the session's handle */
  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
  CK_ULONG          ulOldLen,  /* length of the old PIN */
  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
  CK_ULONG          ulNewLen   /* length of the new PIN */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret != CKR_OK) return ret;

    switch(pSession->State)
    {
        case RWPublic:
        case RWUser:
        case RWSecurityOfficer:
            break;

        default:
            return CKR_SESSION_READ_ONLY;
    }

    if(0 == (pSession->Token->TokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH))
    {
        if(pOldPin == NULL || pNewPin == NULL) return CKR_ARGUMENTS_BAD;
    }
    
    if(pSession->Token->SessionMgmt != NULL && pSession->Token->SessionMgmt->SetPin != NULL)
    {
        ret = pSession->Token->SessionMgmt->SetPin(&pSession->Context, pOldPin, ulOldLen, pNewPin, ulNewLen);
    }
    else
    {
        ret = CKR_FUNCTION_NOT_SUPPORTED;
    }
    
    return ret;
}
Ejemplo n.º 9
0
/* C_FindObjectsFinal finishes a search for token and session
 * objects. */
CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsFinal)
(
  CK_SESSION_HANDLE hSession  /* the session's handle */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret != CKR_OK) return ret;

    if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->FindObjectsFinal)
    {
        return pSession->Token->ObjectMgmt->FindObjectsFinal(&pSession->Context);
    }

    return CKR_FUNCTION_NOT_SUPPORTED;
}
Ejemplo n.º 10
0
/* C_FindObjectsInit initializes a search for token and session
 * objects that match a template. */
CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)
(
  CK_SESSION_HANDLE hSession,   /* the session's handle */
  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
  CK_ULONG          ulCount     /* attrs in search template */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret       != CKR_OK) return ret;
    if(pTemplate == NULL  ) return CKR_ARGUMENTS_BAD;

    if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->FindObjectsInit)
    {
        return pSession->Token->ObjectMgmt->FindObjectsInit(&pSession->Context, pTemplate, ulCount);
    }

    return CKR_FUNCTION_NOT_SUPPORTED;
}
Ejemplo n.º 11
0
/* C_GetObjectSize gets the size of an object in bytes. */
CK_DEFINE_FUNCTION(CK_RV, C_GetObjectSize)
(
  CK_SESSION_HANDLE hSession,  /* the session's handle */
  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
  CK_ULONG_PTR      pulSize    /* receives size of object */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret     != CKR_OK) return ret;
    if(pulSize == NULL  ) return CKR_ARGUMENTS_BAD;

    if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->GetObjectSize)
    {
        return pSession->Token->ObjectMgmt->GetObjectSize(&pSession->Context, hObject, pulSize);
    }

    return CKR_FUNCTION_NOT_SUPPORTED;
}
Ejemplo n.º 12
0
/* C_FindObjects continues a search for token and session
 * objects that match a template, obtaining additional object
 * handles. */
CK_DEFINE_FUNCTION(CK_RV, C_FindObjects)
(
 CK_SESSION_HANDLE    hSession,          /* session's handle */
 CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
 CK_ULONG             ulMaxObjectCount,  /* max handles to get */
 CK_ULONG_PTR         pulObjectCount     /* actual # returned */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret            != CKR_OK) return ret;
    if(pulObjectCount == NULL  ) return CKR_ARGUMENTS_BAD;

    if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->FindObjects)
    {
        return pSession->Token->ObjectMgmt->FindObjects(&pSession->Context, phObject, ulMaxObjectCount, pulObjectCount);
    }

    return CKR_FUNCTION_NOT_SUPPORTED;
}
Ejemplo n.º 13
0
/* C_SetAttributeValue modifies the value of one or more object
 * attributes */
CK_DEFINE_FUNCTION(CK_RV, C_SetAttributeValue)
(
  CK_SESSION_HANDLE hSession,   /* the session's handle */
  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
  CK_ULONG          ulCount     /* attributes in template */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret       != CKR_OK) return ret;
    if(pTemplate == NULL  ) return CKR_ARGUMENTS_BAD;

    if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->SetAttributeValue)
    {
        return pSession->Token->ObjectMgmt->SetAttributeValue(&pSession->Context, hObject, pTemplate, ulCount);
    }

    return CKR_FUNCTION_NOT_SUPPORTED;
}
int ssl_connect_internal(int sd, const char* szTargetHost, int sslContextHandle)
{
    int err = SOCK_SOCKET_ERROR;
    SSL *ssl = NULL;
    int nonblock = 0;

    // Retrieve SSL struct from g_SSL_Driver    
    if((sslContextHandle >= ARRAYSIZE(g_SSL_Driver.m_sslContextArray)) || (sslContextHandle < 0))
    {
        goto error;
    }
    
    // sd should already have been created
    // Now do the SSL negotiation   
    ssl = (SSL*)g_SSL_Driver.m_sslContextArray[sslContextHandle].SslContext;
    if (ssl == NULL) goto error;

    if (!SSL_set_fd(ssl, sd))
    {
        goto error;
    }

    if(ssl->verify_mode != SSL_VERIFY_NONE)
    {
        SSL_CTX* pCtx = SSL_get_SSL_CTX(ssl);

        if(pCtx != NULL)
        {
            X509_STORE *pStore = SSL_CTX_get_cert_store(pCtx);

            if(sk_num(&pStore->objs->stack) == 0)
            {
                CryptokiSession* pSession;
                CK_SLOT_ID  slotID;
                OBJECT_DATA* pObj;
                CK_ATTRIBUTE attribs[2];
                CK_OBJECT_CLASS cls = SwapEndianIfBEc32(CKO_CERTIFICATE);
                LPSTR label = "CA";
                CK_SESSION_HANDLE hSess;

                if(CKR_OK == C_OpenSession(0, CKF_SERIAL_SESSION, NULL, NULL, &hSess) && 
                   CKR_OK == Cryptoki_GetSlotIDFromSession(hSess, &slotID, &pSession))
                {
                    attribs[0].type = CKA_CLASS;
                    attribs[0].pValue = &cls;
                    attribs[0].ulValueLen = sizeof(cls);

                    attribs[1].type = CKA_LABEL;
                    attribs[1].pValue = label;
                    attribs[1].ulValueLen = 2;

                    if(CKR_OK == C_FindObjectsInit(hSess, attribs, ARRAYSIZE(attribs)))
                    {
                        CK_OBJECT_HANDLE hObjs[20];
                        CK_ULONG cnt = 0;

                        if(CKR_OK == C_FindObjects(hSess, hObjs, ARRAYSIZE(hObjs), &cnt) && cnt > 0)
                        {
                            for(int i=0; i<cnt; i++)
                            {
                                pObj = PKCS11_Objects_OpenSSL::GetObjectFromHandle(&pSession->Context, hObjs[i]);

                                if(pObj != NULL && pObj->Type == 3 /*CertificateType*/)
                                {
                                    CERT_DATA* pCert = (CERT_DATA*)pObj->Data;

                                    X509_STORE_add_cert(pStore, pCert->cert);
                                }
                            }
                        }

                        C_FindObjectsFinal(hSess);
                    }
                }

                if(pStore->objs == NULL || 0 == sk_num(&pStore->objs->stack))
                {
                    ssl->verify_mode = SSL_VERIFY_NONE;
                }

                C_CloseSession(hSess);
            }
        }
    }

    if(szTargetHost != NULL && szTargetHost[0] != 0)
    {
        SSL_set_tlsext_host_name(ssl, szTargetHost);
    }

    SOCK_ioctl(sd, SOCK_FIONBIO, &nonblock);

    err = SSL_connect (ssl);    

    nonblock = 1;
    SOCK_ioctl(sd, SOCK_FIONBIO, &nonblock);

    err = SSL_get_error(ssl,err);
      
    if(err == SSL_ERROR_WANT_READ)
    {
        err = SOCK_EWOULDBLOCK;
#if !defined(TCPIP_LWIP) && !defined(TCPIP_LWIP_OS)
        SOCKET_DRIVER.ClearStatusBitsForSocket( sd, FALSE );        
#endif
    }
    else if(err == SSL_ERROR_WANT_WRITE)
    {
        err = SOCK_TRY_AGAIN;
#if !defined(TCPIP_LWIP) && !defined(TCPIP_LWIP_OS)
        SOCKET_DRIVER.ClearStatusBitsForSocket( sd, TRUE );        
#endif
    }

    SOCKET_DRIVER.SetSocketSslData(sd, (void*)ssl);

error:
    return err;
}
Ejemplo n.º 15
0
/* C_CreateObject creates a new object. */
CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)
(
  CK_SESSION_HANDLE hSession,    /* the session's handle */
  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
  CK_ULONG          ulCount,     /* attributes in template */
  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
)
{
    CK_RV ret;
    CK_SLOT_ID slotID;
    CryptokiSession* pSession;
    CK_ULONG i = 0;

    ret = Cryptoki_GetSlotIDFromSession(hSession, &slotID, &pSession);

    if(ret       != CKR_OK) return ret;
    if(pTemplate == NULL  ) return CKR_ARGUMENTS_BAD;
    if(phObject  == NULL  ) return CKR_ARGUMENTS_BAD;

    *phObject = (CK_OBJECT_HANDLE)-1;
    
    if(pTemplate[i].type == CKA_CLASS && pTemplate[i].ulValueLen == sizeof(CK_OBJECT_CLASS))
    {
        CK_OBJECT_CLASS cls = SwapEndianIfBEc32(*(CK_OBJECT_CLASS*)pTemplate[i].pValue);

        i++; if(i > ulCount) return CKR_ARGUMENTS_BAD;

        switch(cls)
        {
            case CKO_SECRET_KEY:
                if(pSession->Token->KeyMgmt != NULL && pSession->Token->KeyMgmt->LoadSecretKey != NULL )
                {
                    if(pTemplate[i].type == CKA_KEY_TYPE)
                    {
                        CK_KEY_TYPE type = SwapEndianIfBEc32(*(CK_KEY_TYPE*)pTemplate[i].pValue);

                        i++; if(i > ulCount) return CKR_ARGUMENTS_BAD;
                        
                        if(pTemplate[i].type == CKA_VALUE)
                        {
                            ret = pSession->Token->KeyMgmt->LoadSecretKey(&pSession->Context, type, (const UINT8*)pTemplate[i].pValue, pTemplate[i].ulValueLen, phObject);
                            
#ifdef _DEBUG
                            if(ret == CKR_OK)
                            {
                                pSession->AddObjectHandle(*phObject);
                            }
#endif
                            
                            return ret;
                        }
                    }
                }
                break;
            case CKO_PRIVATE_KEY:
            case CKO_PUBLIC_KEY:
                if(pSession->Token->KeyMgmt != NULL)
                {
                    if(pTemplate[i].type == CKA_KEY_TYPE)
                    {
                        CK_KEY_TYPE type = SwapEndianIfBEc32(*(CK_KEY_TYPE*)pTemplate[i].pValue);

                        bool bPrivate = (cls == CKO_PRIVATE_KEY);
                        
                        if(type == CKK_DSA && pSession->Token->KeyMgmt->LoadDsaKey != NULL)
                        {
                            DsaKeyData dsaKeyData;

                            memset(&dsaKeyData, 0, sizeof(dsaKeyData));
                           
                            i++;

                            for(;i<ulCount; i++)
                            {
                                switch(pTemplate[i].type)
                                {
                                    case CKA_PRIME:
                                        dsaKeyData.Prime_p        = (PBYTE)pTemplate[i].pValue;
                                        dsaKeyData.Prime_p_len    = pTemplate[i].ulValueLen;
                                        break;
 
                                    case CKA_SUBPRIME:
                                        dsaKeyData.Subprime_q     = (PBYTE)pTemplate[i].pValue;
                                        dsaKeyData.Subprime_q_len = pTemplate[i].ulValueLen;
                                        break;
                                        
                                    case CKA_BASE:
                                        dsaKeyData.Base_g         = (PBYTE)pTemplate[i].pValue;
                                        dsaKeyData.Base_g_len     = pTemplate[i].ulValueLen;
                                        break;
 
                                     case CKA_PRIVATE_EXPONENT:
                                         dsaKeyData.Private_x     = (PBYTE)pTemplate[i].pValue;
                                         dsaKeyData.Private_x_len = pTemplate[i].ulValueLen;
                                         break;
                                         
                                    case CKA_VALUE:
                                        if(bPrivate)
                                        {
                                            dsaKeyData.Private_x     = (PBYTE)pTemplate[i].pValue;
                                            dsaKeyData.Private_x_len = pTemplate[i].ulValueLen;
                                        }
                                        else
                                        {
                                            dsaKeyData.Public_y      = (PBYTE)pTemplate[i].pValue;
                                            dsaKeyData.Public_y_len  = pTemplate[i].ulValueLen;
                                        }
                                        break;

                                    // public and private in same key
                                    case CKA_PUBLIC_EXPONENT:
                                        if(bPrivate)
                                        {
                                            dsaKeyData.Public_y      = (PBYTE)pTemplate[i].pValue;
                                            dsaKeyData.Public_y_len  = pTemplate[i].ulValueLen;
                                        }
                                        break;
                                }
                            }

                            dsaKeyData.Seed_len = dsaKeyData.Base_g_len;

                            ret = pSession->Token->KeyMgmt->LoadDsaKey(&pSession->Context, dsaKeyData, bPrivate, phObject);
                            
#ifdef _DEBUG
                            if(ret == CKR_OK)
                            {
                                pSession->AddObjectHandle(*phObject);
                            }
#endif

                            return ret;
                        }
                        else if(type == CKK_RSA && pSession->Token->KeyMgmt->LoadRsaKey != NULL)
                        {
                            PBYTE    pRawData = NULL;
                            CK_ULONG rawDataLen = 0;
                            RsaKeyData pParams;

                            memset(&pParams, 0, sizeof(pParams));
                            
                            i++;

                            for(;i<ulCount; i++)
                            {
                                switch(pTemplate[i].type)
                                {
                                    case CKA_MODULUS:
                                        pParams.Modulus             = (PBYTE)pTemplate[i].pValue;
                                        pParams.Modulus_len         = pTemplate[i].ulValueLen;
                                        break;

                                    case CKA_PUBLIC_EXPONENT:
                                        pParams.PublicExponent      = (PBYTE)pTemplate[i].pValue;
                                        pParams.PublicExponent_len  = pTemplate[i].ulValueLen;
                                        break;
                                        
                                    case CKA_PRIVATE_EXPONENT:
                                        pParams.PrivateExponent     = (PBYTE)pTemplate[i].pValue;
                                        pParams.PrivateExponent_len = pTemplate[i].ulValueLen;
                                        break;

                                    case CKA_PRIME_1:
                                        pParams.Prime1          = (PBYTE)pTemplate[i].pValue;
                                        pParams.Prime1_len      = pTemplate[i].ulValueLen;
                                        break;
                                    case CKA_PRIME_2:
                                        pParams.Prime2          = (PBYTE)pTemplate[i].pValue;
                                        pParams.Prime2_len      = pTemplate[i].ulValueLen;
                                        break;
                                    case CKA_EXPONENT_1:
                                        pParams.Exponent1       = (PBYTE)pTemplate[i].pValue;
                                        pParams.Exponent1_len   = pTemplate[i].ulValueLen;
                                        break;
                                    case CKA_EXPONENT_2:
                                        pParams.Exponent2       = (PBYTE)pTemplate[i].pValue;
                                        pParams.Exponent2_len   = pTemplate[i].ulValueLen;
                                        break;
                                    case CKA_COEFFICIENT:
                                        pParams.Coefficient     = (PBYTE)pTemplate[i].pValue;
                                        pParams.Coefficient_len = pTemplate[i].ulValueLen;
                                        break;                                        

                                    case CKA_VALUE:
                                        pRawData                = (PBYTE)pTemplate[i].pValue;
                                        rawDataLen              = pTemplate[i].ulValueLen;
                                        break;
                                }
                            }

                            if(pRawData != NULL && rawDataLen > 0)
                            {
                                ret = pSession->Token->KeyMgmt->LoadKeyBlob(&pSession->Context, pRawData, rawDataLen, CKK_RSA, Public, phObject);
                            }
                            else
                            {
                                ret = pSession->Token->KeyMgmt->LoadRsaKey(&pSession->Context, pParams, bPrivate, phObject);
                            }
                            
#ifdef _DEBUG
                            if(ret == CKR_OK)
                            {
                                pSession->AddObjectHandle(*phObject);
                            }
#endif
                            
                            return ret;
                        }
                    }
                }
                break;
        }
    }

    // give the drivers object management a chance to handle this
    if(pSession->Token->ObjectMgmt != NULL && pSession->Token->ObjectMgmt->CreateObject != NULL)
    {
        ret = pSession->Token->ObjectMgmt->CreateObject(&pSession->Context, pTemplate, ulCount, phObject);
        
#ifdef _DEBUG
        if(ret == CKR_OK)
        {
            pSession->AddObjectHandle(*phObject);
        }
#endif
        
        return ret;
    }
    
    return CKR_FUNCTION_NOT_SUPPORTED;
}