Blame snmplib/pkcs.c

Packit fcad23
/*
Packit fcad23
 * Copyright Copyright 2003 Sun Microsystems, Inc. All rights reserved.
Packit fcad23
 * Use is subject to license terms specified in the COPYING file
Packit fcad23
 * distributed with the Net-SNMP package.
Packit fcad23
 */
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * pkcs.c
Packit fcad23
 */
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-config.h>
Packit fcad23
#ifdef NETSNMP_USE_PKCS11
Packit fcad23
#include <net-snmp/types.h>
Packit fcad23
#include <net-snmp/output_api.h>
Packit fcad23
#include <net-snmp/config_api.h>
Packit fcad23
#include <net-snmp/library/snmp_api.h>
Packit fcad23
#include <net-snmp/library/tools.h>
Packit fcad23
#include <net-snmp/library/keytools.h>
Packit fcad23
#include <net-snmp/library/scapi.h>
Packit fcad23
#include <net-snmp/library/callback.h>
Packit fcad23
#include <security/cryptoki.h>
Packit fcad23
Packit fcad23
typedef struct netsnmp_pkcs_slot_session_s {
Packit fcad23
    CK_SLOT_ID        sid;
Packit fcad23
    CK_SESSION_HANDLE hdl;
Packit fcad23
} netsnmp_pkcs_slot_session; 
Packit fcad23
Packit fcad23
typedef struct netsnmp_pkcs_slot_info_s {
Packit fcad23
    int count;
Packit fcad23
    netsnmp_pkcs_slot_session *pSession; 
Packit fcad23
} netsnmp_pkcs_slot_info;
Packit fcad23
Packit fcad23
static CK_RV get_session_handle(CK_MECHANISM_TYPE, CK_FLAGS,\
Packit fcad23
                                CK_SESSION_HANDLE_PTR);
Packit fcad23
static CK_RV get_slot_session_handle(netsnmp_pkcs_slot_session *,\
Packit fcad23
                                     CK_SESSION_HANDLE_PTR);
Packit fcad23
static char *pkcserr_string(CK_RV);
Packit fcad23
static int free_slots(int, int, void *, void *);
Packit fcad23
Packit fcad23
static netsnmp_pkcs_slot_info *pSlot = NULL;
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * initialize the Cryptoki library.
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
pkcs_init(void)
Packit fcad23
{
Packit fcad23
    CK_RV          rv;
Packit fcad23
    CK_ULONG       slotcount;
Packit fcad23
    CK_SLOT_ID_PTR pSlotList = NULL;
Packit fcad23
    netsnmp_pkcs_slot_session    *tmp;
Packit fcad23
    int            i, rval = SNMPERR_SUCCESS;
Packit fcad23
    /* Initialize pkcs */
Packit fcad23
    if ((rv = C_Initialize(NULL)) != CKR_OK) {
Packit fcad23
        DEBUGMSGTL(("pkcs_init", "C_Initialize failed: %s",
Packit fcad23
                pkcserr_string(rv)));
Packit fcad23
        return SNMPERR_SC_NOT_CONFIGURED;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /* Get slot count */
Packit fcad23
    rv = C_GetSlotList(1, NULL_PTR, &slotcount);
Packit fcad23
    if (rv != CKR_OK || slotcount == 0) {
Packit fcad23
        DEBUGMSGTL(("pkcs_init", "C_GetSlotList failed: %s", 
Packit fcad23
                pkcserr_string(rv)));
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_init_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /* Found at least one slot, allocate memory for slot list */
Packit fcad23
    pSlotList = malloc(slotcount * sizeof (CK_SLOT_ID));
Packit fcad23
    pSlot = malloc(sizeof (netsnmp_pkcs_slot_info));
Packit fcad23
    pSlot->pSession = malloc(slotcount * sizeof (netsnmp_pkcs_slot_session));
Packit fcad23
Packit fcad23
    if (pSlotList == NULL_PTR ||
Packit fcad23
        pSlot == NULL_PTR ||
Packit fcad23
        pSlot->pSession == NULL_PTR) {
Packit fcad23
        DEBUGMSGTL(("pkcs_init","malloc failed.")); 
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_init_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /* Get the list of slots */
Packit fcad23
    if ((rv = C_GetSlotList(1, pSlotList, &slotcount)) != CKR_OK) {
Packit fcad23
        DEBUGMSGTL(("pkcs_init", "C_GetSlotList failed: %s", 
Packit fcad23
                pkcserr_string(rv)));
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_init_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /* initialize Slots structure */
Packit fcad23
    pSlot->count = slotcount;
Packit fcad23
    for (i = 0, tmp = pSlot->pSession; i < slotcount; i++, tmp++) {
Packit fcad23
        tmp->sid = pSlotList[i]; 
Packit fcad23
        tmp->hdl = NULL;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_SHUTDOWN,
Packit fcad23
                        free_slots, NULL);
Packit fcad23
Packit fcad23
  pkcs_init_quit:
Packit fcad23
    SNMP_FREE(pSlotList);
Packit fcad23
    return rval;
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * close all the opened sessions when finished with Cryptoki library.
Packit fcad23
 */
Packit fcad23
static int
Packit fcad23
free_slots(int majorID, int minorID, void *serverarg, void *clientarg)
Packit fcad23
{
Packit fcad23
    int            slotcount, i;
Packit fcad23
Packit fcad23
    if (pSlot != NULL) {
Packit fcad23
        slotcount = pSlot->count;
Packit fcad23
        for (i = 0; i < slotcount; i++) {
Packit fcad23
            if (pSlot->pSession->hdl != NULL) {
Packit fcad23
                free(pSlot->pSession->hdl);
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
        free(pSlot);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    (void) C_Finalize(NULL);
Packit fcad23
    return 0;
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * generate random data
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
pkcs_random(u_char * buf, size_t buflen)
Packit fcad23
{
Packit fcad23
    CK_SESSION_HANDLE hSession;
Packit fcad23
Packit fcad23
    if (pSlot != NULL &&
Packit fcad23
        get_slot_session_handle(pSlot->pSession, &hSession) == CKR_OK &&
Packit fcad23
        C_GenerateRandom(hSession, buf, buflen) == CKR_OK) {
Packit fcad23
        return SNMPERR_SUCCESS;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    return SNMPERR_GENERR;
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * retrieve the session handle from the first slot that supports the specified
Packit fcad23
 * mechanism.
Packit fcad23
 */
Packit fcad23
static CK_RV
Packit fcad23
get_session_handle(CK_MECHANISM_TYPE mech_type, CK_FLAGS flag,
Packit fcad23
                CK_SESSION_HANDLE_PTR sess)
Packit fcad23
{
Packit fcad23
    CK_RV             rv = CKR_OK;
Packit fcad23
    CK_MECHANISM_INFO info;
Packit fcad23
    netsnmp_pkcs_slot_session       *p = NULL;
Packit fcad23
    int               i, slotcount = 0;
Packit fcad23
            
Packit fcad23
    if (pSlot) {
Packit fcad23
        slotcount = pSlot->count;
Packit fcad23
        p = pSlot->pSession;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /* Find a slot with matching mechanism */
Packit fcad23
    for (i = 0; i < slotcount; i++, p++) {
Packit fcad23
        rv = C_GetMechanismInfo(p->sid, mech_type, &info;;
Packit fcad23
Packit fcad23
        if (rv != CKR_OK) {
Packit fcad23
            continue; /* to the next slot */
Packit fcad23
        } else {
Packit fcad23
            if (info.flags & flag) {
Packit fcad23
                rv = get_slot_session_handle(p, sess);
Packit fcad23
                break; /* found */
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /* Show error if no matching mechanism found */
Packit fcad23
    if (i == slotcount) {
Packit fcad23
        DEBUGMSGTL(("pkcs_init","No cryptographic provider for %s",
Packit fcad23
                mech_type)); 
Packit fcad23
        return CKR_SESSION_HANDLE_INVALID;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    return rv;
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * retrieve the session handle from the specified slot.
Packit fcad23
 */
Packit fcad23
static CK_RV
Packit fcad23
get_slot_session_handle(netsnmp_pkcs_slot_session *p,
Packit fcad23
                        CK_SESSION_HANDLE_PTR sess)
Packit fcad23
{
Packit fcad23
    CK_RV rv = CKR_OK;
Packit fcad23
    if (p == NULL) {
Packit fcad23
        *sess = NULL;
Packit fcad23
        return CKR_SESSION_HANDLE_INVALID;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (p->hdl == NULL) {
Packit fcad23
        /* Open a session */
Packit fcad23
        rv = C_OpenSession(p->sid, CKF_SERIAL_SESSION,
Packit fcad23
                NULL_PTR, NULL, &p->hdl);
Packit fcad23
Packit fcad23
        if (rv != CKR_OK) {
Packit fcad23
            DEBUGMSGTL(("get_slot_session_handle","can not open PKCS #11 session: %s",
Packit fcad23
                        pkcserr_string(rv)));
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
    *sess = p->hdl;
Packit fcad23
Packit fcad23
    return rv;
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * perform a signature operation to generate MAC.
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
pkcs_sign(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen,
Packit fcad23
          u_char * msg, u_int msglen, u_char * mac, size_t * maclen)
Packit fcad23
{
Packit fcad23
    /*
Packit fcad23
     * Key template 
Packit fcad23
     */
Packit fcad23
    CK_OBJECT_CLASS class = CKO_SECRET_KEY;
Packit fcad23
    CK_KEY_TYPE keytype = CKK_GENERIC_SECRET;
Packit fcad23
    CK_BBOOL truevalue = TRUE;
Packit fcad23
    CK_BBOOL falsevalue= FALSE;
Packit fcad23
    CK_ATTRIBUTE template[] = {
Packit fcad23
        {CKA_CLASS, &class, sizeof (class)},
Packit fcad23
        {CKA_KEY_TYPE, &keytype, sizeof (keytype)},
Packit fcad23
        {CKA_SIGN, &truevalue, sizeof (truevalue)},
Packit fcad23
        {CKA_TOKEN, &falsevalue, sizeof (falsevalue)},
Packit fcad23
        {CKA_VALUE, key, keylen}
Packit fcad23
    };
Packit fcad23
    CK_SESSION_HANDLE hSession;
Packit fcad23
    CK_MECHANISM mech;
Packit fcad23
    CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0;
Packit fcad23
    int                rval = SNMPERR_SUCCESS;
Packit fcad23
    if (get_session_handle(mech_type, CKF_SIGN, &hSession) != CKR_OK ||
Packit fcad23
        hSession == NULL) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /* create a key object */
Packit fcad23
    if (C_CreateObject(hSession, template,
Packit fcad23
        (sizeof (template) / sizeof (CK_ATTRIBUTE)), &hkey) != CKR_OK) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    mech.mechanism = mech_type;
Packit fcad23
    mech.pParameter = NULL_PTR;
Packit fcad23
    mech.ulParameterLen = 0;
Packit fcad23
Packit fcad23
    /* initialize a signature operation */
Packit fcad23
    if (C_SignInit(hSession, &mech, hkey) != CKR_OK ) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
Packit fcad23
    }
Packit fcad23
    /* continue a multiple-part signature operation */
Packit fcad23
    if (C_SignUpdate(hSession, msg, msglen) != CKR_OK) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
Packit fcad23
    }
Packit fcad23
    /* finish a multiple-part signature operation */
Packit fcad23
    if (C_SignFinal(hSession, mac, maclen) != CKR_OK) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_sign_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
  pkcs_sign_quit:
Packit fcad23
Packit fcad23
    if (key != (CK_OBJECT_HANDLE) 0) {
Packit fcad23
        (void) C_DestroyObject(hSession, hkey);
Packit fcad23
    }
Packit fcad23
    return rval;
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * perform a message-digesting operation.
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
pkcs_digest(CK_MECHANISM_TYPE mech_type, u_char * msg, u_int msglen,
Packit fcad23
            u_char * digest, size_t * digestlen)
Packit fcad23
{
Packit fcad23
    int               rval = SNMPERR_SUCCESS;
Packit fcad23
    CK_SESSION_HANDLE hSession;
Packit fcad23
    CK_MECHANISM      mech;
Packit fcad23
    if (get_session_handle(mech_type, CKF_DIGEST, &hSession) != CKR_OK ||
Packit fcad23
        hSession == NULL) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    mech.mechanism = mech_type;
Packit fcad23
    mech.pParameter = NULL_PTR;
Packit fcad23
    mech.ulParameterLen = 0;
Packit fcad23
Packit fcad23
    /* initialize a message-digesting operation */
Packit fcad23
    if (C_DigestInit(hSession, &mech)!= CKR_OK ) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
Packit fcad23
    }
Packit fcad23
    /* continue a multiple-part message-digesting operation */
Packit fcad23
    if (C_DigestUpdate(hSession, msg, msglen) != CKR_OK ) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
Packit fcad23
    }
Packit fcad23
    /* finish a multiple-part message-digesting operation */
Packit fcad23
    if (C_DigestFinal(hSession, digest, digestlen) != CKR_OK) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_digest_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
  pkcs_digest_quit:
Packit fcad23
    return rval;
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * encrypt plaintext into ciphertext using key and iv.   
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
pkcs_encrpyt(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen,
Packit fcad23
             u_char * iv, u_int ivlen,
Packit fcad23
             u_char * plaintext, u_int ptlen,
Packit fcad23
             u_char * ciphertext, size_t * ctlen)
Packit fcad23
{
Packit fcad23
    int                rval = SNMPERR_SUCCESS;
Packit fcad23
    int                pad_size, offset;
Packit fcad23
    /*
Packit fcad23
     * Key template 
Packit fcad23
     */
Packit fcad23
    CK_OBJECT_CLASS class = CKO_SECRET_KEY;
Packit fcad23
    CK_KEY_TYPE keytype = CKK_DES;
Packit fcad23
    /* CK_KEY_TYPE AESkeytype = CKK_AES; */
Packit fcad23
    CK_BBOOL truevalue = TRUE;
Packit fcad23
    CK_BBOOL falsevalue = FALSE;
Packit fcad23
Packit fcad23
    CK_ATTRIBUTE template[] = {
Packit fcad23
        {CKA_CLASS, &class, sizeof (class)},
Packit fcad23
        {CKA_KEY_TYPE, &keytype, sizeof (keytype)},
Packit fcad23
        {CKA_ENCRYPT, &truevalue, sizeof (truevalue)},
Packit fcad23
        {CKA_TOKEN, &falsevalue, sizeof (falsevalue)},
Packit fcad23
        {CKA_VALUE, key, keylen} 
Packit fcad23
    };
Packit fcad23
Packit fcad23
    CK_SESSION_HANDLE hSession;
Packit fcad23
    CK_MECHANISM mech;
Packit fcad23
    CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0;
Packit fcad23
Packit fcad23
    if (get_session_handle(mech_type, CKF_ENCRYPT,
Packit fcad23
                           &hSession) != CKR_OK ||
Packit fcad23
        hSession == NULL) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (C_CreateObject(hSession, template,
Packit fcad23
        (sizeof (template) / sizeof (CK_ATTRIBUTE)),
Packit fcad23
                                &hkey) != CKR_OK) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    mech.mechanism = mech_type;
Packit fcad23
    mech.pParameter = iv;
Packit fcad23
    mech.ulParameterLen = ivlen;
Packit fcad23
Packit fcad23
    /* initialize an encryption operation */
Packit fcad23
    if (C_EncryptInit(hSession, &mech, hkey) != CKR_OK ) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /* for DES */
Packit fcad23
    pad_size = BYTESIZE(SNMP_TRANS_PRIVLEN_1DES);
Packit fcad23
Packit fcad23
    if (ptlen + pad_size - ptlen % pad_size > *ctlen) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);    
Packit fcad23
    }
Packit fcad23
Packit fcad23
    for (offset = 0; offset < ptlen; offset += pad_size) {
Packit fcad23
        /* continue a multiple-part encryption operation */
Packit fcad23
        if (C_EncryptUpdate(hSession, plaintext + offset, pad_size,
Packit fcad23
                            ciphertext + offset, ctlen) != CKR_OK) {
Packit fcad23
            QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /* finish a multiple-part encryption operation */
Packit fcad23
    if (C_EncryptFinal(hSession, ciphertext + offset, ctlen) != CKR_OK) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_encrypt_quit);
Packit fcad23
    }
Packit fcad23
    *ctlen = offset;
Packit fcad23
Packit fcad23
  pkcs_encrypt_quit:
Packit fcad23
    if (key != (CK_OBJECT_HANDLE) 0) {
Packit fcad23
        (void) C_DestroyObject(hSession, hkey);
Packit fcad23
    }
Packit fcad23
    return rval;
Packit fcad23
}
Packit fcad23
Packit fcad23
/* 
Packit fcad23
 * decrypt ciphertext into plaintext using key and iv.
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
pkcs_decrpyt(CK_MECHANISM_TYPE mech_type, u_char * key, u_int keylen,
Packit fcad23
             u_char * iv, u_int ivlen,
Packit fcad23
             u_char * ciphertext, u_int ctlen,
Packit fcad23
             u_char * plaintext, size_t * ptlen)
Packit fcad23
{
Packit fcad23
    int            rval = SNMPERR_SUCCESS;
Packit fcad23
    /*
Packit fcad23
     * Key template 
Packit fcad23
     */
Packit fcad23
    CK_OBJECT_CLASS class = CKO_SECRET_KEY;
Packit fcad23
    CK_KEY_TYPE keytype = CKK_DES;
Packit fcad23
    /* CK_KEY_TYPE AESkeytype = CKK_AES; */
Packit fcad23
    CK_BBOOL truevalue = TRUE;
Packit fcad23
    CK_BBOOL falsevalue= FALSE;
Packit fcad23
    CK_ATTRIBUTE template[] = {
Packit fcad23
        {CKA_CLASS, &class, sizeof (class)},
Packit fcad23
        {CKA_KEY_TYPE, &keytype, sizeof (keytype)},
Packit fcad23
        {CKA_DECRYPT, &truevalue, sizeof (truevalue)},
Packit fcad23
        {CKA_TOKEN, &falsevalue, sizeof (falsevalue)},
Packit fcad23
        {CKA_VALUE, key, keylen}
Packit fcad23
    };
Packit fcad23
    CK_SESSION_HANDLE hSession;
Packit fcad23
    CK_MECHANISM mech;
Packit fcad23
    CK_OBJECT_HANDLE hkey = (CK_OBJECT_HANDLE) 0;
Packit fcad23
Packit fcad23
    if (get_session_handle(mech_type, CKF_DECRYPT, &hSession) != CKR_OK ||
Packit fcad23
        hSession == NULL) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (C_CreateObject(hSession, template,
Packit fcad23
        (sizeof (template) / sizeof (CK_ATTRIBUTE)), &hkey) != CKR_OK) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    mech.mechanism = mech_type;
Packit fcad23
    mech.pParameter = iv;
Packit fcad23
    mech.ulParameterLen = ivlen;
Packit fcad23
Packit fcad23
    /* initialize a decryption operation */
Packit fcad23
    if (C_DecryptInit(hSession, &mech, hkey) != CKR_OK ) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
Packit fcad23
    }
Packit fcad23
    /* continue a multiple-part decryption operation */
Packit fcad23
    if (C_DecryptUpdate(hSession, ciphertext, ctlen, plaintext,
Packit fcad23
                                        ptlen) != CKR_OK) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
Packit fcad23
    }
Packit fcad23
    /* finish a multiple-part decryption operation */
Packit fcad23
    if (C_DecryptFinal(hSession, plaintext, ptlen) != CKR_OK) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_decrypt_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
  pkcs_decrypt_quit:
Packit fcad23
    if (key != (CK_OBJECT_HANDLE) 0) {
Packit fcad23
        (void) C_DestroyObject(hSession, hkey);
Packit fcad23
    }
Packit fcad23
    return rval;
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * Convert a passphrase into a master user key, Ku, according to the
Packit fcad23
 * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM)
Packit fcad23
 */
Packit fcad23
int
Packit fcad23
pkcs_generate_Ku(CK_MECHANISM_TYPE mech_type, u_char * passphrase, u_int pplen,
Packit fcad23
                 u_char * Ku, size_t * kulen)
Packit fcad23
{
Packit fcad23
    int                rval = SNMPERR_SUCCESS, nbytes = USM_LENGTH_EXPANDED_PASSPHRASE;
Packit fcad23
    CK_SESSION_HANDLE hSession;
Packit fcad23
    CK_MECHANISM mech;
Packit fcad23
    u_int        i, pindex = 0;
Packit fcad23
    u_char        buf[USM_LENGTH_KU_HASHBLOCK], *bufp;
Packit fcad23
Packit fcad23
    if (get_session_handle(mech_type, CKF_DIGEST, &hSession) != CKR_OK ||
Packit fcad23
        hSession == NULL) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    mech.mechanism = mech_type;
Packit fcad23
    mech.pParameter = NULL_PTR;
Packit fcad23
    mech.ulParameterLen = 0;
Packit fcad23
Packit fcad23
    /* initialize a message-digesting operation */
Packit fcad23
    if (C_DigestInit(hSession, &mech)!= CKR_OK ) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    while (nbytes > 0) {
Packit fcad23
        bufp = buf;
Packit fcad23
        for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) {
Packit fcad23
           /*
Packit fcad23
	    * fill a buffer with the supplied passphrase.  When the end
Packit fcad23
            * of the passphrase is reachedcycle back to the beginning.
Packit fcad23
            */
Packit fcad23
            *bufp++ = passphrase[pindex++ % pplen];
Packit fcad23
        }
Packit fcad23
        /* continue a multiple-part message-digesting operation */
Packit fcad23
        if (C_DigestUpdate(hSession, buf, USM_LENGTH_KU_HASHBLOCK) != CKR_OK ) {
Packit fcad23
            QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
Packit fcad23
        }
Packit fcad23
        nbytes -= USM_LENGTH_KU_HASHBLOCK;
Packit fcad23
    }
Packit fcad23
    /* finish a multiple-part message-digesting operation */
Packit fcad23
    if (C_DigestFinal(hSession, Ku, kulen) != CKR_OK) {
Packit fcad23
        QUITFUN(SNMPERR_GENERR, pkcs_generate_Ku_quit);
Packit fcad23
    }
Packit fcad23
Packit fcad23
  pkcs_generate_Ku_quit:
Packit fcad23
    return rval;
Packit fcad23
}
Packit fcad23
   
Packit fcad23
/*
Packit fcad23
 * pkcserr_stringor: returns a string representation of the given 
Packit fcad23
 * return code.
Packit fcad23
 */
Packit fcad23
static char *
Packit fcad23
pkcserr_string(CK_RV rv)
Packit fcad23
{
Packit fcad23
    static char errstr[128];
Packit fcad23
    switch (rv) {
Packit fcad23
    case CKR_OK:
Packit fcad23
        return ("CKR_OK");
Packit fcad23
        break;
Packit fcad23
    case CKR_CANCEL:
Packit fcad23
        return ("CKR_CANCEL");
Packit fcad23
        break;
Packit fcad23
    case CKR_HOST_MEMORY:
Packit fcad23
        return ("CKR_HOST_MEMORY");
Packit fcad23
        break;
Packit fcad23
    case CKR_SLOT_ID_INVALID:
Packit fcad23
        return ("CKR_SLOT_ID_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_GENERAL_ERROR:
Packit fcad23
        return ("CKR_GENERAL_ERROR");
Packit fcad23
        break;
Packit fcad23
    case CKR_FUNCTION_FAILED:
Packit fcad23
        return ("CKR_FUNCTION_FAILED");
Packit fcad23
        break;
Packit fcad23
    case CKR_ARGUMENTS_BAD:
Packit fcad23
        return ("CKR_ARGUMENTS_BAD");
Packit fcad23
        break;
Packit fcad23
    case CKR_NO_EVENT:
Packit fcad23
        return ("CKR_NO_EVENT");
Packit fcad23
        break;
Packit fcad23
    case CKR_NEED_TO_CREATE_THREADS:
Packit fcad23
        return ("CKR_NEED_TO_CREATE_THREADS");
Packit fcad23
        break;
Packit fcad23
    case CKR_CANT_LOCK:
Packit fcad23
        return ("CKR_CANT_LOCK");
Packit fcad23
        break;
Packit fcad23
    case CKR_ATTRIBUTE_READ_ONLY:
Packit fcad23
        return ("CKR_ATTRIBUTE_READ_ONLY");
Packit fcad23
        break;
Packit fcad23
    case CKR_ATTRIBUTE_SENSITIVE:
Packit fcad23
        return ("CKR_ATTRIBUTE_SENSITIVE");
Packit fcad23
        break;
Packit fcad23
    case CKR_ATTRIBUTE_TYPE_INVALID:
Packit fcad23
        return ("CKR_ATTRIBUTE_TYPE_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_ATTRIBUTE_VALUE_INVALID:
Packit fcad23
        return ("CKR_ATTRIBUTE_VALUE_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_DATA_INVALID:
Packit fcad23
        return ("CKR_DATA_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_DATA_LEN_RANGE:
Packit fcad23
        return ("CKR_DATA_LEN_RANGE");
Packit fcad23
        break;
Packit fcad23
    case CKR_DEVICE_ERROR:
Packit fcad23
        return ("CKR_DEVICE_ERROR");
Packit fcad23
        break;
Packit fcad23
    case CKR_DEVICE_MEMORY:
Packit fcad23
        return ("CKR_DEVICE_MEMORY");
Packit fcad23
        break;
Packit fcad23
    case CKR_DEVICE_REMOVED:
Packit fcad23
        return ("CKR_DEVICE_REMOVED");
Packit fcad23
        break;
Packit fcad23
    case CKR_ENCRYPTED_DATA_INVALID:
Packit fcad23
        return ("CKR_ENCRYPTED_DATA_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_ENCRYPTED_DATA_LEN_RANGE:
Packit fcad23
        return ("CKR_ENCRYPTED_DATA_LEN_RANGE");
Packit fcad23
        break;
Packit fcad23
    case CKR_FUNCTION_CANCELED:
Packit fcad23
        return ("CKR_FUNCTION_CANCELED");
Packit fcad23
        break;
Packit fcad23
    case CKR_FUNCTION_NOT_PARALLEL:
Packit fcad23
        return ("CKR_FUNCTION_NOT_PARALLEL");
Packit fcad23
        break;
Packit fcad23
    case CKR_FUNCTION_NOT_SUPPORTED:
Packit fcad23
        return ("CKR_FUNCTION_NOT_SUPPORTED");
Packit fcad23
        break;
Packit fcad23
    case CKR_KEY_HANDLE_INVALID:
Packit fcad23
        return ("CKR_KEY_HANDLE_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_KEY_SIZE_RANGE:
Packit fcad23
        return ("CKR_KEY_SIZE_RANGE");
Packit fcad23
        break;
Packit fcad23
    case CKR_KEY_TYPE_INCONSISTENT:
Packit fcad23
        return ("CKR_KEY_TYPE_INCONSISTENT");
Packit fcad23
        break;
Packit fcad23
    case CKR_KEY_NOT_NEEDED:
Packit fcad23
        return ("CKR_KEY_NOT_NEEDED");
Packit fcad23
        break;
Packit fcad23
    case CKR_KEY_CHANGED:
Packit fcad23
        return ("CKR_KEY_CHANGED");
Packit fcad23
        break;
Packit fcad23
    case CKR_KEY_NEEDED:
Packit fcad23
        return ("CKR_KEY_NEEDED");
Packit fcad23
        break;
Packit fcad23
    case CKR_KEY_INDIGESTIBLE:
Packit fcad23
        return ("CKR_KEY_INDIGESTIBLE");
Packit fcad23
        break;
Packit fcad23
    case CKR_KEY_FUNCTION_NOT_PERMITTED:
Packit fcad23
        return ("CKR_KEY_FUNCTION_NOT_PERMITTED");
Packit fcad23
        break;
Packit fcad23
    case CKR_KEY_NOT_WRAPPABLE:
Packit fcad23
        return ("CKR_KEY_NOT_WRAPPABLE");
Packit fcad23
        break;
Packit fcad23
    case CKR_KEY_UNEXTRACTABLE:
Packit fcad23
        return ("CKR_KEY_UNEXTRACTABLE");
Packit fcad23
        break;
Packit fcad23
    case CKR_MECHANISM_INVALID:
Packit fcad23
        return ("CKR_MECHANISM_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_MECHANISM_PARAM_INVALID:
Packit fcad23
        return ("CKR_MECHANISM_PARAM_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_OBJECT_HANDLE_INVALID:
Packit fcad23
        return ("CKR_OBJECT_HANDLE_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_OPERATION_ACTIVE:
Packit fcad23
        return ("CKR_OPERATION_ACTIVE");
Packit fcad23
        break;
Packit fcad23
    case CKR_OPERATION_NOT_INITIALIZED:
Packit fcad23
        return ("CKR_OPERATION_NOT_INITIALIZED");
Packit fcad23
        break;
Packit fcad23
    case CKR_PIN_INCORRECT:
Packit fcad23
        return ("CKR_PIN_INCORRECT");
Packit fcad23
        break;
Packit fcad23
    case CKR_PIN_INVALID:
Packit fcad23
        return ("CKR_PIN_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_PIN_LEN_RANGE:
Packit fcad23
        return ("CKR_PIN_LEN_RANGE");
Packit fcad23
        break;
Packit fcad23
    case CKR_PIN_EXPIRED:
Packit fcad23
        return ("CKR_PIN_EXPIRED");
Packit fcad23
        break;
Packit fcad23
    case CKR_PIN_LOCKED:
Packit fcad23
        return ("CKR_PIN_LOCKED");
Packit fcad23
        break;
Packit fcad23
    case CKR_SESSION_CLOSED:
Packit fcad23
        return ("CKR_SESSION_CLOSED");
Packit fcad23
        break;
Packit fcad23
    case CKR_SESSION_COUNT:
Packit fcad23
        return ("CKR_SESSION_COUNT");
Packit fcad23
        break;
Packit fcad23
    case CKR_SESSION_HANDLE_INVALID:
Packit fcad23
        return ("CKR_SESSION_HANDLE_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
Packit fcad23
        return ("CKR_SESSION_PARALLEL_NOT_SUPPORTED");
Packit fcad23
        break;
Packit fcad23
    case CKR_SESSION_READ_ONLY:
Packit fcad23
        return ("CKR_SESSION_READ_ONLY");
Packit fcad23
        break;
Packit fcad23
    case CKR_SESSION_EXISTS:
Packit fcad23
        return ("CKR_SESSION_EXISTS");
Packit fcad23
        break;
Packit fcad23
    case CKR_SESSION_READ_ONLY_EXISTS:
Packit fcad23
        return ("CKR_SESSION_READ_ONLY_EXISTS");
Packit fcad23
        break;
Packit fcad23
    case CKR_SESSION_READ_WRITE_SO_EXISTS:
Packit fcad23
        return ("CKR_SESSION_READ_WRITE_SO_EXISTS");
Packit fcad23
        break;
Packit fcad23
    case CKR_SIGNATURE_INVALID:
Packit fcad23
        return ("CKR_SIGNATURE_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_SIGNATURE_LEN_RANGE:
Packit fcad23
        return ("CKR_SIGNATURE_LEN_RANGE");
Packit fcad23
        break;
Packit fcad23
    case CKR_TEMPLATE_INCOMPLETE:
Packit fcad23
        return ("CKR_TEMPLATE_INCOMPLETE");
Packit fcad23
        break;
Packit fcad23
    case CKR_TEMPLATE_INCONSISTENT:
Packit fcad23
        return ("CKR_TEMPLATE_INCONSISTENT");
Packit fcad23
        break;
Packit fcad23
    case CKR_TOKEN_NOT_PRESENT:
Packit fcad23
        return ("CKR_TOKEN_NOT_PRESENT");
Packit fcad23
        break;
Packit fcad23
    case CKR_TOKEN_NOT_RECOGNIZED:
Packit fcad23
        return ("CKR_TOKEN_NOT_RECOGNIZED");
Packit fcad23
        break;
Packit fcad23
    case CKR_TOKEN_WRITE_PROTECTED:
Packit fcad23
        return ("CKR_TOKEN_WRITE_PROTECTED");
Packit fcad23
        break;
Packit fcad23
    case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
Packit fcad23
        return ("CKR_UNWRAPPING_KEY_HANDLE_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_UNWRAPPING_KEY_SIZE_RANGE:
Packit fcad23
        return ("CKR_UNWRAPPING_KEY_SIZE_RANGE");
Packit fcad23
        break;
Packit fcad23
    case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
Packit fcad23
        return ("CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT");
Packit fcad23
        break;
Packit fcad23
    case CKR_USER_ALREADY_LOGGED_IN:
Packit fcad23
        return ("CKR_USER_ALREADY_LOGGED_IN");
Packit fcad23
        break;
Packit fcad23
    case CKR_USER_NOT_LOGGED_IN:
Packit fcad23
        return ("CKR_USER_NOT_LOGGED_IN");
Packit fcad23
        break;
Packit fcad23
    case CKR_USER_PIN_NOT_INITIALIZED:
Packit fcad23
        return ("CKR_USER_PIN_NOT_INITIALIZED");
Packit fcad23
        break;
Packit fcad23
    case CKR_USER_TYPE_INVALID:
Packit fcad23
        return ("CKR_USER_TYPE_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
Packit fcad23
        return ("CKR_USER_ANOTHER_ALREADY_LOGGED_IN");
Packit fcad23
        break;
Packit fcad23
    case CKR_USER_TOO_MANY_TYPES:
Packit fcad23
        return ("CKR_USER_TOO_MANY_TYPES");
Packit fcad23
        break;
Packit fcad23
    case CKR_WRAPPED_KEY_INVALID:
Packit fcad23
        return ("CKR_WRAPPED_KEY_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_WRAPPED_KEY_LEN_RANGE:
Packit fcad23
        return ("CKR_WRAPPED_KEY_LEN_RANGE");
Packit fcad23
        break;
Packit fcad23
    case CKR_WRAPPING_KEY_HANDLE_INVALID:
Packit fcad23
        return ("CKR_WRAPPING_KEY_HANDLE_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_WRAPPING_KEY_SIZE_RANGE:
Packit fcad23
        return ("CKR_WRAPPING_KEY_SIZE_RANGE");
Packit fcad23
        break;
Packit fcad23
    case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
Packit fcad23
        return ("CKR_WRAPPING_KEY_TYPE_INCONSISTENT");
Packit fcad23
        break;
Packit fcad23
    case CKR_RANDOM_SEED_NOT_SUPPORTED:
Packit fcad23
        return ("CKR_RANDOM_SEED_NOT_SUPPORTED");
Packit fcad23
        break;
Packit fcad23
    case CKR_RANDOM_NO_RNG:
Packit fcad23
        return ("CKR_RANDOM_NO_RNG");
Packit fcad23
        break;
Packit fcad23
    case CKR_DOMAIN_PARAMS_INVALID:
Packit fcad23
        return ("CKR_DOMAIN_PARAMS_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_BUFFER_TOO_SMALL:
Packit fcad23
        return ("CKR_BUFFER_TOO_SMALL");
Packit fcad23
        break;
Packit fcad23
    case CKR_SAVED_STATE_INVALID:
Packit fcad23
        return ("CKR_SAVED_STATE_INVALID");
Packit fcad23
        break;
Packit fcad23
    case CKR_INFORMATION_SENSITIVE:
Packit fcad23
        return ("CKR_INFORMATION_SENSITIVE");
Packit fcad23
        break;
Packit fcad23
    case CKR_STATE_UNSAVEABLE:
Packit fcad23
        return ("CKR_STATE_UNSAVEABLE");
Packit fcad23
        break;
Packit fcad23
    case CKR_CRYPTOKI_NOT_INITIALIZED:
Packit fcad23
        return ("CKR_CRYPTOKI_NOT_INITIALIZED");
Packit fcad23
        break;
Packit fcad23
    case CKR_CRYPTOKI_ALREADY_INITIALIZED:
Packit fcad23
        return ("CKR_CRYPTOKI_ALREADY_INITIALIZED");
Packit fcad23
        break;
Packit fcad23
    case CKR_MUTEX_BAD:
Packit fcad23
        return ("CKR_MUTEX_BAD");
Packit fcad23
        break;
Packit fcad23
    case CKR_MUTEX_NOT_LOCKED:
Packit fcad23
        return ("CKR_MUTEX_NOT_LOCKED");
Packit fcad23
        break;
Packit fcad23
    case CKR_VENDOR_DEFINED:
Packit fcad23
        return ("CKR_VENDOR_DEFINED");
Packit fcad23
        break;
Packit fcad23
    default:
Packit fcad23
        /* rv not found */
Packit fcad23
        snprintf(errstr, sizeof (errstr),
Packit fcad23
            "Unknown return code: 0x%x", rv);
Packit fcad23
        return (errstr);
Packit fcad23
        break;
Packit fcad23
    }
Packit fcad23
}
Packit fcad23
#else
Packit fcad23
int pkcs_unused;	/* Suppress "empty translation unit" warning */
Packit fcad23
#endif