|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* COPYRIGHT (c) International Business Machines Corp. 2001-2017
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* This program is provided under the terms of the Common Public License,
|
|
Packit |
8681c6 |
* version 1.0 (CPL-1.0). Any use, reproduction or distribution for this
|
|
Packit |
8681c6 |
* software constitutes recipient's acceptance of CPL-1.0 terms which can be
|
|
Packit |
8681c6 |
* found in the file LICENSE file or at
|
|
Packit |
8681c6 |
* https://opensource.org/licenses/cpl1.0.php
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include <pthread.h>
|
|
Packit |
8681c6 |
#include <stdio.h>
|
|
Packit |
8681c6 |
#include <stdlib.h>
|
|
Packit |
8681c6 |
#include <string.h>
|
|
Packit |
8681c6 |
#include <unistd.h>
|
|
Packit |
8681c6 |
#include <sys/types.h>
|
|
Packit |
8681c6 |
#include <pthread.h>
|
|
Packit |
8681c6 |
#include <sys/stat.h>
|
|
Packit |
8681c6 |
#include <sys/ipc.h>
|
|
Packit |
8681c6 |
#include <sys/shm.h>
|
|
Packit |
8681c6 |
#include <errno.h>
|
|
Packit |
8681c6 |
#include <pwd.h>
|
|
Packit |
8681c6 |
#include <grp.h>
|
|
Packit |
8681c6 |
#include <pthread.h>
|
|
Packit |
8681c6 |
#include <openssl/evp.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include "pkcs11types.h"
|
|
Packit |
8681c6 |
#include "defs.h"
|
|
Packit |
8681c6 |
#include "host_defs.h"
|
|
Packit |
8681c6 |
#include "h_extern.h"
|
|
Packit |
8681c6 |
#include "tok_spec_struct.h"
|
|
Packit |
8681c6 |
#include "pkcs32.h"
|
|
Packit |
8681c6 |
#include "shared_memory.h"
|
|
Packit |
8681c6 |
#include "trace.h"
|
|
Packit |
8681c6 |
#include "ock_syslog.h"
|
|
Packit Service |
8aa27d |
#include "slotmgr.h" // for ock_snprintf
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
#include <sys/file.h>
|
|
Packit |
8681c6 |
#include <syslog.h>
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Function: dlist_add_as_first()
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Adds the specified node to the start of the list
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Returns: pointer to the start of the list
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
DL_NODE *dlist_add_as_first(DL_NODE *list, void *data)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
DL_NODE *node = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!data)
|
|
Packit |
8681c6 |
return list;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
node = (DL_NODE *) malloc(sizeof(DL_NODE));
|
|
Packit |
8681c6 |
if (!node)
|
|
Packit |
8681c6 |
return NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
node->data = data;
|
|
Packit |
8681c6 |
node->prev = NULL;
|
|
Packit |
8681c6 |
node->next = list;
|
|
Packit |
8681c6 |
if (list)
|
|
Packit |
8681c6 |
list->prev = node;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return node;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Function: dlist_add_as_last()
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Adds the specified node to the end of the list
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Returns: pointer to the start of the list
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
DL_NODE *dlist_add_as_last(DL_NODE *list, void *data)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
DL_NODE *node = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!data)
|
|
Packit |
8681c6 |
return list;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
node = (DL_NODE *) malloc(sizeof(DL_NODE));
|
|
Packit |
8681c6 |
if (!node)
|
|
Packit |
8681c6 |
return NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
node->data = data;
|
|
Packit |
8681c6 |
node->next = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!list) {
|
|
Packit |
8681c6 |
node->prev = NULL;
|
|
Packit |
8681c6 |
return node;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
DL_NODE *temp = dlist_get_last(list);
|
|
Packit |
8681c6 |
temp->next = node;
|
|
Packit |
8681c6 |
node->prev = temp;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return list;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Function: dlist_find()
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
DL_NODE *dlist_find(DL_NODE *list, void *data)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
DL_NODE *node = list;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
while (node && node->data != data)
|
|
Packit |
8681c6 |
node = node->next;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return node;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Function: dlist_get_first()
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Returns the last node in the list or NULL if list is empty
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
DL_NODE *dlist_get_first(DL_NODE *list)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
DL_NODE *temp = list;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!list)
|
|
Packit |
8681c6 |
return NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
while (temp->prev != NULL)
|
|
Packit |
8681c6 |
temp = temp->prev;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return temp;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Function: dlist_get_last()
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Returns the last node in the list or NULL if list is empty
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
DL_NODE *dlist_get_last(DL_NODE *list)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
DL_NODE *temp = list;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!list)
|
|
Packit |
8681c6 |
return NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
while (temp->next != NULL)
|
|
Packit |
8681c6 |
temp = temp->next;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return temp;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_ULONG dlist_length(DL_NODE *list)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
DL_NODE *temp = list;
|
|
Packit |
8681c6 |
CK_ULONG len = 0;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
while (temp) {
|
|
Packit |
8681c6 |
len++;
|
|
Packit |
8681c6 |
temp = temp->next;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return len;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
DL_NODE *dlist_next(DL_NODE *node)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
if (!node)
|
|
Packit |
8681c6 |
return NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return node->next;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
DL_NODE *dlist_prev(DL_NODE *node)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
if (!node)
|
|
Packit |
8681c6 |
return NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return node->prev;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
void dlist_purge(DL_NODE *list)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
DL_NODE *node;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!list)
|
|
Packit |
8681c6 |
return;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
do {
|
|
Packit |
8681c6 |
node = list->next;
|
|
Packit |
8681c6 |
free(list);
|
|
Packit |
8681c6 |
list = node;
|
|
Packit |
8681c6 |
} while (list);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Function: dlist_remove_node()
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Attempts to remove the specified node from the list. The caller is
|
|
Packit |
8681c6 |
// responsible for freeing the data associated with the node prior to
|
|
Packit |
8681c6 |
// calling this routine
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
DL_NODE *dlist_remove_node(DL_NODE *list, DL_NODE *node)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
DL_NODE *temp = list;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!list || !node)
|
|
Packit |
8681c6 |
return NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// special case: removing head of the list
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
if (list == node) {
|
|
Packit |
8681c6 |
temp = list->next;
|
|
Packit |
8681c6 |
if (temp)
|
|
Packit |
8681c6 |
temp->prev = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
free(list);
|
|
Packit |
8681c6 |
return temp;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// we have no guarantee that the node is in the list
|
|
Packit |
8681c6 |
// so search through the list to find it
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
while ((temp != NULL) && (temp->next != node))
|
|
Packit |
8681c6 |
temp = temp->next;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (temp != NULL) {
|
|
Packit |
8681c6 |
DL_NODE *next = node->next;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
temp->next = next;
|
|
Packit |
8681c6 |
if (next)
|
|
Packit |
8681c6 |
next->prev = temp;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
free(node);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return list;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV CreateXProcLock(char *tokname, STDLL_TokData_t *tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit Service |
8aa27d |
char lockfile[PATH_MAX];
|
|
Packit Service |
8aa27d |
char lockdir[PATH_MAX];
|
|
Packit |
8681c6 |
struct group *grp;
|
|
Packit |
8681c6 |
struct stat statbuf;
|
|
Packit |
8681c6 |
mode_t mode = (S_IRUSR | S_IRGRP);
|
|
Packit |
8681c6 |
int ret = -1;
|
|
Packit Service |
8aa27d |
char *toklockname;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd == -1) {
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (token_specific.t_creatlock != NULL) {
|
|
Packit |
8681c6 |
tokdata->spinxplfd = token_specific.t_creatlock();
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd != -1)
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
else
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit Service |
8aa27d |
toklockname = (strlen(tokname) > 0) ? tokname : SUB_DIR;
|
|
Packit Service |
8aa27d |
|
|
Packit Service |
8aa27d |
|
|
Packit |
8681c6 |
/** create lock subdir for each token if it doesn't exist.
|
|
Packit |
8681c6 |
* The root directory should be created in slotmgr daemon **/
|
|
Packit Service |
8aa27d |
if (ock_snprintf(lockdir, PATH_MAX, "%s/%s",
|
|
Packit Service |
8aa27d |
LOCKDIR_PATH, toklockname) != 0) {
|
|
Packit Service |
8aa27d |
OCK_SYSLOG(LOG_ERR, "lock directory path too long\n");
|
|
Packit Service |
8aa27d |
TRACE_ERROR("lock directory path too long\n");
|
|
Packit Service |
8aa27d |
goto err;
|
|
Packit Service |
8aa27d |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
ret = stat(lockdir, &statbuf);
|
|
Packit |
8681c6 |
if (ret != 0 && errno == ENOENT) {
|
|
Packit |
8681c6 |
/* dir does not exist, try to create it */
|
|
Packit |
8681c6 |
ret = mkdir(lockdir, S_IRWXU | S_IRWXG);
|
|
Packit |
8681c6 |
if (ret != 0) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR,
|
|
Packit |
8681c6 |
"Directory(%s) missing: %s\n",
|
|
Packit |
8681c6 |
lockdir, strerror(errno));
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
grp = getgrnam("pkcs11");
|
|
Packit |
8681c6 |
if (grp == NULL) {
|
|
Packit |
8681c6 |
fprintf(stderr, "getgrname(pkcs11): %s", strerror(errno));
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
/* set ownership to euid, and pkcs11 group */
|
|
Packit |
8681c6 |
if (chown(lockdir, geteuid(), grp->gr_gid) != 0) {
|
|
Packit |
8681c6 |
fprintf(stderr, "Failed to set owner:group \
|
|
Packit |
8681c6 |
ownership on %s directory", lockdir);
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
/* mkdir does not set group permission right, so
|
|
Packit |
8681c6 |
** trying explictly here again */
|
|
Packit |
8681c6 |
if (chmod(lockdir, S_IRWXU | S_IRWXG) != 0) {
|
|
Packit |
8681c6 |
fprintf(stderr, "Failed to change \
|
|
Packit |
8681c6 |
permissions on %s directory", lockdir);
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* create user lock file */
|
|
Packit Service |
8aa27d |
if (ock_snprintf(lockfile, sizeof(lockfile), "%s/%s/LCK..%s",
|
|
Packit Service |
8aa27d |
LOCKDIR_PATH, toklockname, toklockname) != 0) {
|
|
Packit Service |
8aa27d |
OCK_SYSLOG(LOG_ERR, "lock file path too long\n");
|
|
Packit Service |
8aa27d |
TRACE_ERROR("lock file path too long\n");
|
|
Packit Service |
8aa27d |
goto err;
|
|
Packit Service |
8aa27d |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (stat(lockfile, &statbuf) == 0) {
|
|
Packit |
8681c6 |
tokdata->spinxplfd = open(lockfile, O_RDONLY, mode);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
tokdata->spinxplfd = open(lockfile, O_CREAT | O_RDONLY, mode);
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd != -1) {
|
|
Packit |
8681c6 |
/* umask may prevent correct mode,so set it. */
|
|
Packit |
8681c6 |
if (fchmod(tokdata->spinxplfd, mode) == -1) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "fchmod(%s): %s\n",
|
|
Packit |
8681c6 |
lockfile, strerror(errno));
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
grp = getgrnam("pkcs11");
|
|
Packit |
8681c6 |
if (grp != NULL) {
|
|
Packit |
8681c6 |
if (fchown(tokdata->spinxplfd, -1, grp->gr_gid) == -1) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR,
|
|
Packit |
8681c6 |
"fchown(%s): %s\n",
|
|
Packit |
8681c6 |
lockfile, strerror(errno));
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "getgrnam(): %s\n", strerror(errno));
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd == -1) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "open(%s): %s\n", lockfile, strerror(errno));
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
err:
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd != -1)
|
|
Packit |
8681c6 |
close(tokdata->spinxplfd);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
void CloseXProcLock(STDLL_TokData_t *tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd != -1)
|
|
Packit |
8681c6 |
close(tokdata->spinxplfd);
|
|
Packit |
8681c6 |
pthread_mutex_destroy(&tokdata->spinxplfd_mutex);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV XThreadLock(STDLL_TokData_t *tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
if (pthread_mutex_lock(&tokdata->spinxplfd_mutex)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Lock failed.\n");
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV XThreadUnLock(STDLL_TokData_t *tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
if (pthread_mutex_unlock(&tokdata->spinxplfd_mutex)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Unlock failed.\n");
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV XProcLock(STDLL_TokData_t *tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
if (XThreadLock(tokdata) != CKR_OK)
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd < 0) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("No file descriptor to lock with.\n");
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd_count == 0) {
|
|
Packit |
8681c6 |
if (flock(tokdata->spinxplfd, LOCK_EX) != 0) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("flock has failed.\n");
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
tokdata->spinxplfd_count++;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV XProcUnLock(STDLL_TokData_t *tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd < 0) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("No file descriptor to unlock with.\n");
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd_count == 0) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("No file lock is held.\n");
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (tokdata->spinxplfd_count == 1) {
|
|
Packit |
8681c6 |
if (flock(tokdata->spinxplfd, LOCK_UN) != 0) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("flock has failed.\n");
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
tokdata->spinxplfd_count--;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (XThreadUnLock(tokdata) != CKR_OK)
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV XProcLock_Init(STDLL_TokData_t *tokdata)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
pthread_mutexattr_t attr;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tokdata->spinxplfd = -1;
|
|
Packit |
8681c6 |
tokdata->spinxplfd_count = 0;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (pthread_mutexattr_init(&attr)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Mutex attribute init failed.\n");
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Mutex attribute set failed.\n");
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
if (pthread_mutex_init(&tokdata->spinxplfd_mutex, &attr)) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Mutex init failed.\n");
|
|
Packit |
8681c6 |
return CKR_CANT_LOCK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
extern const char manuf[];
|
|
Packit |
8681c6 |
extern const char model[];
|
|
Packit |
8681c6 |
extern const char descr[];
|
|
Packit |
8681c6 |
extern const char label[];
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
void init_slotInfo(CK_SLOT_INFO *slot_info)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
memset(slot_info->slotDescription, ' ', sizeof(slot_info->slotDescription));
|
|
Packit |
8681c6 |
memset(slot_info->manufacturerID, ' ', sizeof(slot_info->manufacturerID));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(slot_info->slotDescription, descr, strlen(descr));
|
|
Packit |
8681c6 |
memcpy(slot_info->manufacturerID, manuf, strlen(manuf));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
slot_info->hardwareVersion.major = 1;
|
|
Packit |
8681c6 |
slot_info->hardwareVersion.minor = 0;
|
|
Packit |
8681c6 |
slot_info->firmwareVersion.major = 1;
|
|
Packit |
8681c6 |
slot_info->firmwareVersion.minor = 0;
|
|
Packit |
8681c6 |
slot_info->flags = CKF_TOKEN_PRESENT | CKF_HW_SLOT;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
void init_tokenInfo(TOKEN_DATA *nv_token_data)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_TOKEN_INFO_32 *token_info = &nv_token_data->token_info;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memset(token_info->label, ' ', sizeof(token_info->label));
|
|
Packit |
8681c6 |
memset(token_info->manufacturerID, ' ', sizeof(token_info->manufacturerID));
|
|
Packit |
8681c6 |
memset(token_info->model, ' ', sizeof(token_info->model));
|
|
Packit |
8681c6 |
memset(token_info->serialNumber, ' ', sizeof(token_info->serialNumber));
|
|
Packit |
8681c6 |
memset(token_info->utcTime, ' ', sizeof(token_info->utcTime));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(token_info->label, label, strlen(label));
|
|
Packit |
8681c6 |
memcpy(token_info->manufacturerID, manuf, strlen(manuf));
|
|
Packit |
8681c6 |
memcpy(token_info->model, model, strlen(model));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Unused
|
|
Packit |
8681c6 |
// memcpy(token_info->serialNumber, "123", 3);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// I don't see any API support for changing the clock so
|
|
Packit |
8681c6 |
// we will use the system clock for the token's clock.
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
token_info->flags = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_CLOCK_ON_TOKEN |
|
|
Packit |
8681c6 |
CKF_SO_PIN_TO_BE_CHANGED;
|
|
Packit |
8681c6 |
// XXX New in v2.11 - KEY
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (memcmp(nv_token_data->user_pin_sha, "00000000000000000000",
|
|
Packit |
8681c6 |
SHA1_HASH_SIZE) != 0)
|
|
Packit |
8681c6 |
token_info->flags |= CKF_USER_PIN_INITIALIZED;
|
|
Packit |
8681c6 |
else
|
|
Packit |
8681c6 |
token_info->flags |= CKF_USER_PIN_TO_BE_CHANGED;
|
|
Packit |
8681c6 |
// XXX New in v2.11 - KEY
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// For the release, we made these
|
|
Packit |
8681c6 |
// values as CK_UNAVAILABLE_INFORMATION or CK_EFFECTIVELY_INFINITE
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
token_info->ulMaxSessionCount = (CK_ULONG_32) CK_EFFECTIVELY_INFINITE;
|
|
Packit |
8681c6 |
token_info->ulSessionCount = (CK_ULONG_32) CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
token_info->ulMaxRwSessionCount = (CK_ULONG_32) CK_EFFECTIVELY_INFINITE;
|
|
Packit |
8681c6 |
token_info->ulRwSessionCount = (CK_ULONG_32) CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
token_info->ulMaxPinLen = MAX_PIN_LEN;
|
|
Packit |
8681c6 |
token_info->ulMinPinLen = MIN_PIN_LEN;
|
|
Packit |
8681c6 |
token_info->ulTotalPublicMemory = (CK_ULONG_32) CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
token_info->ulFreePublicMemory = (CK_ULONG_32) CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
token_info->ulTotalPrivateMemory = (CK_ULONG_32) CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
token_info->ulFreePrivateMemory = (CK_ULONG_32) CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
token_info->hardwareVersion.major = 0;
|
|
Packit |
8681c6 |
token_info->hardwareVersion.minor = 0;
|
|
Packit |
8681c6 |
token_info->firmwareVersion.major = 0;
|
|
Packit |
8681c6 |
token_info->firmwareVersion.minor = 0;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV init_token_data(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
TOKEN_DATA_VERSION *dat = &tokdata->nv_token_data->dat;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memset((char *) tokdata->nv_token_data, 0, sizeof(TOKEN_DATA));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// the normal USER pin is not set when the token is initialized
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
if (tokdata->version < TOK_NEW_DATA_STORE) {
|
|
Packit |
8681c6 |
memcpy(tokdata->nv_token_data->user_pin_sha, "00000000000000000000",
|
|
Packit |
8681c6 |
SHA1_HASH_SIZE);
|
|
Packit |
8681c6 |
memcpy(tokdata->nv_token_data->so_pin_sha, default_so_pin_sha,
|
|
Packit |
8681c6 |
SHA1_HASH_SIZE);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memset(tokdata->user_pin_md5, 0x0, MD5_HASH_SIZE);
|
|
Packit |
8681c6 |
memcpy(tokdata->so_pin_md5, default_so_pin_md5, MD5_HASH_SIZE);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
int rv;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
dat->version = tokdata->version;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* SO login key */
|
|
Packit |
8681c6 |
dat->so_login_it = SO_KDF_LOGIN_IT;
|
|
Packit |
8681c6 |
memcpy(dat->so_login_salt, SO_KDF_LOGIN_PURPOSE, 32);
|
|
Packit |
8681c6 |
rng_generate(tokdata, dat->so_login_salt + 32, 32);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rv = PKCS5_PBKDF2_HMAC(SO_PIN_DEFAULT, strlen(SO_PIN_DEFAULT),
|
|
Packit |
8681c6 |
dat->so_login_salt, 64,
|
|
Packit |
8681c6 |
dat->so_login_it, EVP_sha512(),
|
|
Packit |
8681c6 |
256 / 8, dat->so_login_key);
|
|
Packit |
8681c6 |
if (rv != 1) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("PBKDF2 failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* SO wrap key */
|
|
Packit |
8681c6 |
dat->so_wrap_it = SO_KDF_WRAP_IT;
|
|
Packit |
8681c6 |
memcpy(dat->so_wrap_salt, SO_KDF_WRAP_PURPOSE, 32);
|
|
Packit |
8681c6 |
rng_generate(tokdata, dat->so_wrap_salt + 32, 32);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rv = PKCS5_PBKDF2_HMAC(SO_PIN_DEFAULT, strlen(SO_PIN_DEFAULT),
|
|
Packit |
8681c6 |
dat->so_wrap_salt, 64,
|
|
Packit |
8681c6 |
dat->so_wrap_it, EVP_sha512(),
|
|
Packit |
8681c6 |
256 / 8, tokdata->so_wrap_key);
|
|
Packit |
8681c6 |
if (rv != 1) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("PBKDF2 failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* User login key */
|
|
Packit |
8681c6 |
dat->user_login_it = USER_KDF_LOGIN_IT;
|
|
Packit |
8681c6 |
memcpy(dat->user_login_salt, USER_KDF_LOGIN_PURPOSE, 32);
|
|
Packit |
8681c6 |
rng_generate(tokdata, dat->user_login_salt + 32, 32);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rv = PKCS5_PBKDF2_HMAC(USER_PIN_DEFAULT, strlen(USER_PIN_DEFAULT),
|
|
Packit |
8681c6 |
dat->user_login_salt, 64,
|
|
Packit |
8681c6 |
dat->user_login_it, EVP_sha512(),
|
|
Packit |
8681c6 |
256 / 8, dat->user_login_key);
|
|
Packit |
8681c6 |
if (rv != 1) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("PBKDF2 failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* User wrap key */
|
|
Packit |
8681c6 |
dat->user_wrap_it = USER_KDF_WRAP_IT;
|
|
Packit |
8681c6 |
memcpy(dat->user_wrap_salt, USER_KDF_WRAP_PURPOSE, 32);
|
|
Packit |
8681c6 |
rng_generate(tokdata, dat->user_wrap_salt + 32, 32);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rv = PKCS5_PBKDF2_HMAC(USER_PIN_DEFAULT, strlen(USER_PIN_DEFAULT),
|
|
Packit |
8681c6 |
dat->user_wrap_salt, 64,
|
|
Packit |
8681c6 |
dat->user_wrap_it, EVP_sha512(),
|
|
Packit |
8681c6 |
256 / 8, tokdata->user_wrap_key);
|
|
Packit |
8681c6 |
if (rv != 1) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("PBKDF2 failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memcpy(tokdata->nv_token_data->next_token_object_name, "00000000", 8);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// generate the master key used for signing the Operation State information
|
|
Packit |
8681c6 |
// `
|
|
Packit |
8681c6 |
memset(tokdata->nv_token_data->token_info.label, ' ',
|
|
Packit |
8681c6 |
sizeof(tokdata->nv_token_data->token_info.label));
|
|
Packit |
8681c6 |
memcpy(tokdata->nv_token_data->token_info.label, label,
|
|
Packit |
8681c6 |
strlen(label));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
tokdata->nv_token_data->tweak_vector.allow_weak_des = TRUE;
|
|
Packit |
8681c6 |
tokdata->nv_token_data->tweak_vector.check_des_parity = FALSE;
|
|
Packit |
8681c6 |
tokdata->nv_token_data->tweak_vector.allow_key_mods = TRUE;
|
|
Packit |
8681c6 |
tokdata->nv_token_data->tweak_vector.netscape_mods = TRUE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
init_tokenInfo(tokdata->nv_token_data);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (token_specific.t_init_token_data) {
|
|
Packit |
8681c6 |
rc = token_specific.t_init_token_data(tokdata, slot_id);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// FIXME: erase the token object index file (and all token objects)
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
rc = generate_master_key(tokdata, tokdata->master_key);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("generate_master_key failed.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = save_masterkey_so(tokdata);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("save_masterkey_so failed.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = save_token_data(tokdata, slot_id);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// Function: compute_next_token_obj_name()
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Given a token object name (8 bytes in the range [0-9A-Z]) increment by one
|
|
Packit |
8681c6 |
// adjusting as necessary
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// This gives us a namespace of 36^8 = 2,821,109,907,456 objects before wrapping
|
|
Packit |
8681c6 |
// around
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
// Note: If the current name contains an invalid character (i.e. not within
|
|
Packit |
8681c6 |
// [0-9A-Z]), then this character is set to '0' in the next name and
|
|
Packit |
8681c6 |
// the following characters are incremented by 1 adjusting as necessary.
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV compute_next_token_obj_name(CK_BYTE *current, CK_BYTE *next)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
int val[8];
|
|
Packit |
8681c6 |
int i;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (!current || !next) {
|
|
Packit |
8681c6 |
TRACE_ERROR("Invalid function arguments.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// Convert to integral base 36
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
for (i = 0; i < 8; i++) {
|
|
Packit |
8681c6 |
if (current[i] >= '0' && current[i] <= '9')
|
|
Packit |
8681c6 |
val[i] = current[i] - '0';
|
|
Packit |
8681c6 |
else if (current[i] >= 'A' && current[i] <= 'Z')
|
|
Packit |
8681c6 |
val[i] = current[i] - 'A' + 10;
|
|
Packit |
8681c6 |
else
|
|
Packit |
8681c6 |
val[i] = 36;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
val[0]++;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
i = 0;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
while (val[i] > 35) {
|
|
Packit |
8681c6 |
val[i] = 0;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (i + 1 < 8) {
|
|
Packit |
8681c6 |
val[i + 1]++;
|
|
Packit |
8681c6 |
i++;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
val[0]++;
|
|
Packit |
8681c6 |
i = 0; // start pass 2
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
// now, convert back to [0-9A-Z]
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
for (i = 0; i < 8; i++) {
|
|
Packit |
8681c6 |
if (val[i] < 10)
|
|
Packit |
8681c6 |
next[i] = '0' + val[i];
|
|
Packit |
8681c6 |
else
|
|
Packit |
8681c6 |
next[i] = 'A' + val[i] - 10;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV build_attribute(CK_ATTRIBUTE_TYPE type,
|
|
Packit |
8681c6 |
CK_BYTE *data, CK_ULONG data_len, CK_ATTRIBUTE **attrib)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
attr = (CK_ATTRIBUTE *) malloc(sizeof(CK_ATTRIBUTE) + data_len);
|
|
Packit |
8681c6 |
if (!attr) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_HOST_MEMORY));
|
|
Packit |
8681c6 |
return CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
attr->type = type;
|
|
Packit |
8681c6 |
attr->ulValueLen = data_len;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (data_len > 0) {
|
|
Packit |
8681c6 |
attr->pValue = (CK_BYTE *) attr + sizeof(CK_ATTRIBUTE);
|
|
Packit |
8681c6 |
memcpy(attr->pValue, data, data_len);
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
attr->pValue = NULL;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
*attrib = attr;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* Find an attribute in an attribute array.
|
|
Packit |
8681c6 |
*
|
|
Packit |
8681c6 |
* Returns CKR_FUNCTION_FAILED when attribute is not found,
|
|
Packit |
8681c6 |
* CKR_ATTRIBUTE_TYPE_INVALID when length doesn't match the expected and
|
|
Packit |
8681c6 |
* CKR_OK when values is returned in the `value` argument.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
CK_RV find_bbool_attribute(CK_ATTRIBUTE *attrs, CK_ULONG attrs_len,
|
|
Packit |
8681c6 |
CK_ATTRIBUTE_TYPE type, CK_BBOOL *value)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_ULONG i;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
for (i = 0; i < attrs_len; i++) {
|
|
Packit |
8681c6 |
if (attrs[i].type == type) {
|
|
Packit |
8681c6 |
/* Check size */
|
|
Packit |
8681c6 |
if (attrs[i].ulValueLen != sizeof(*value))
|
|
Packit |
8681c6 |
return CKR_ATTRIBUTE_TYPE_INVALID;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Get value */
|
|
Packit |
8681c6 |
*value = *((CK_BBOOL *) attrs[i].pValue);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV add_pkcs_padding(CK_BYTE *ptr,
|
|
Packit |
8681c6 |
CK_ULONG block_size, CK_ULONG data_len,
|
|
Packit |
8681c6 |
CK_ULONG total_len)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_ULONG i, pad_len;
|
|
Packit |
8681c6 |
CK_BYTE pad_value;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
pad_len = block_size - (data_len % block_size);
|
|
Packit |
8681c6 |
pad_value = (CK_BYTE) pad_len;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (data_len + pad_len > total_len) {
|
|
Packit |
8681c6 |
TRACE_ERROR("The total length is too small to add padding.\n");
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
for (i = 0; i < pad_len; i++)
|
|
Packit |
8681c6 |
ptr[i] = pad_value;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV strip_pkcs_padding(CK_BYTE *ptr, CK_ULONG total_len, CK_ULONG *data_len)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_BYTE pad_value;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
pad_value = ptr[total_len - 1];
|
|
Packit |
8681c6 |
if (pad_value > total_len) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_ENCRYPTED_DATA_INVALID));
|
|
Packit |
8681c6 |
return CKR_ENCRYPTED_DATA_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
// thus, we have 'pad_value' bytes of 'pad_value' appended to the end
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
*data_len = total_len - pad_value;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_BYTE parity_adjust(CK_BYTE b)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
if (parity_is_odd(b) == FALSE)
|
|
Packit |
8681c6 |
b = (b & 0xFE) | ((~b) & 0x1);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return b;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
//
|
|
Packit |
8681c6 |
CK_RV parity_is_odd(CK_BYTE b)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
b = ((b >> 4) ^ b) & 0x0f;
|
|
Packit |
8681c6 |
b = ((b >> 2) ^ b) & 0x03;
|
|
Packit |
8681c6 |
b = ((b >> 1) ^ b) & 0x01;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (b == 1)
|
|
Packit |
8681c6 |
return TRUE;
|
|
Packit |
8681c6 |
else
|
|
Packit |
8681c6 |
return FALSE;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV attach_shm(STDLL_TokData_t *tokdata, CK_SLOT_ID slot_id)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
int ret;
|
|
Packit |
8681c6 |
char buf[PATH_MAX];
|
|
Packit |
8681c6 |
LW_SHM_TYPE **shm = &tokdata->global_shm;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (token_specific.t_attach_shm != NULL)
|
|
Packit |
8681c6 |
return token_specific.t_attach_shm(tokdata, slot_id);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = XProcLock(tokdata);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* Attach to an existing shared memory region or create it if it doesn't
|
|
Packit |
8681c6 |
* exists. When it's created (ret=0) the region is initialized with
|
|
Packit |
8681c6 |
* zeros.
|
|
Packit |
8681c6 |
*/
|
|
Packit Service |
8aa27d |
if (get_pk_dir(tokdata, buf, PATH_MAX) == NULL) {
|
|
Packit Service |
8aa27d |
TRACE_ERROR("pk_dir buffer overflow");
|
|
Packit Service |
8aa27d |
rc = CKR_FUNCTION_FAILED;
|
|
Packit Service |
8aa27d |
goto err;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
ret = sm_open(buf, 0666, (void **) shm, sizeof(**shm), 0);
|
|
Packit |
8681c6 |
if (ret < 0) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("sm_open failed.\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return XProcUnLock(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
err:
|
|
Packit |
8681c6 |
XProcUnLock(tokdata);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV detach_shm(STDLL_TokData_t *tokdata, CK_BBOOL ignore_ref_count)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = XProcLock(tokdata);
|
|
Packit |
8681c6 |
if (rc != CKR_OK)
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (sm_close((void *) tokdata->global_shm, 0, ignore_ref_count)) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("sm_close failed.\n");
|
|
Packit |
8681c6 |
rc = CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
goto err;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return XProcUnLock(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
err:
|
|
Packit |
8681c6 |
XProcUnLock(tokdata);
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV get_sha_size(CK_ULONG mech, CK_ULONG *hsize)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
switch (mech) {
|
|
Packit |
8681c6 |
case CKM_SHA_1:
|
|
Packit |
8681c6 |
*hsize = SHA1_HASH_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_SHA224:
|
|
Packit |
8681c6 |
case CKM_SHA512_224:
|
|
Packit |
8681c6 |
*hsize = SHA224_HASH_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_SHA256:
|
|
Packit |
8681c6 |
case CKM_SHA512_256:
|
|
Packit |
8681c6 |
*hsize = SHA256_HASH_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_SHA384:
|
|
Packit |
8681c6 |
*hsize = SHA384_HASH_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_SHA512:
|
|
Packit |
8681c6 |
*hsize = SHA512_HASH_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_IBM_SHA3_224:
|
|
Packit |
8681c6 |
*hsize = SHA3_224_HASH_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_IBM_SHA3_256:
|
|
Packit |
8681c6 |
*hsize = SHA3_256_HASH_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_IBM_SHA3_384:
|
|
Packit |
8681c6 |
*hsize = SHA3_384_HASH_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_IBM_SHA3_512:
|
|
Packit |
8681c6 |
*hsize = SHA3_512_HASH_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
return CKR_MECHANISM_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV get_sha_block_size(CK_ULONG mech, CK_ULONG *bsize)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
switch (mech) {
|
|
Packit |
8681c6 |
case CKM_SHA_1:
|
|
Packit |
8681c6 |
*bsize = SHA1_BLOCK_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_SHA224:
|
|
Packit |
8681c6 |
*bsize = SHA224_BLOCK_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_SHA256:
|
|
Packit |
8681c6 |
*bsize = SHA256_BLOCK_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_SHA384:
|
|
Packit |
8681c6 |
*bsize = SHA384_BLOCK_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_SHA512:
|
|
Packit |
8681c6 |
case CKM_SHA512_224:
|
|
Packit |
8681c6 |
case CKM_SHA512_256:
|
|
Packit |
8681c6 |
*bsize = SHA512_BLOCK_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_IBM_SHA3_224:
|
|
Packit |
8681c6 |
*bsize = SHA3_224_BLOCK_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_IBM_SHA3_256:
|
|
Packit |
8681c6 |
*bsize = SHA3_256_BLOCK_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_IBM_SHA3_384:
|
|
Packit |
8681c6 |
*bsize = SHA3_384_BLOCK_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
case CKM_IBM_SHA3_512:
|
|
Packit |
8681c6 |
*bsize = SHA3_512_BLOCK_SIZE;
|
|
Packit |
8681c6 |
break;
|
|
Packit |
8681c6 |
default:
|
|
Packit |
8681c6 |
return CKR_MECHANISM_INVALID;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit Service |
8aa27d |
CK_RV get_hmac_digest(CK_ULONG mech, CK_ULONG *digest_mech, CK_BBOOL *general)
|
|
Packit Service |
8aa27d |
{
|
|
Packit Service |
8aa27d |
switch (mech) {
|
|
Packit Service |
8aa27d |
case CKM_MD2_HMAC:
|
|
Packit Service |
8aa27d |
case CKM_MD2_HMAC_GENERAL:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_MD2;
|
|
Packit Service |
8aa27d |
*general = (mech == CKM_MD2_HMAC_GENERAL);
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_MD5_HMAC:
|
|
Packit Service |
8aa27d |
case CKM_MD5_HMAC_GENERAL:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_MD5;
|
|
Packit Service |
8aa27d |
*general = (mech == CKM_MD5_HMAC_GENERAL);
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_RIPEMD128_HMAC:
|
|
Packit Service |
8aa27d |
case CKM_RIPEMD128_HMAC_GENERAL:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_RIPEMD128;
|
|
Packit Service |
8aa27d |
*general = (mech == CKM_RIPEMD128_HMAC_GENERAL);
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_SHA_1_HMAC:
|
|
Packit Service |
8aa27d |
case CKM_SHA_1_HMAC_GENERAL:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_SHA_1;
|
|
Packit Service |
8aa27d |
*general = (mech == CKM_SHA_1_HMAC_GENERAL);
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_SHA224_HMAC:
|
|
Packit Service |
8aa27d |
case CKM_SHA224_HMAC_GENERAL:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_SHA224;
|
|
Packit Service |
8aa27d |
*general = (mech == CKM_SHA224_HMAC_GENERAL);
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_SHA256_HMAC:
|
|
Packit Service |
8aa27d |
case CKM_SHA256_HMAC_GENERAL:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_SHA256;
|
|
Packit Service |
8aa27d |
*general = (mech == CKM_SHA256_HMAC_GENERAL);
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_SHA384_HMAC:
|
|
Packit Service |
8aa27d |
case CKM_SHA384_HMAC_GENERAL:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_SHA384;
|
|
Packit Service |
8aa27d |
*general = (mech == CKM_SHA384_HMAC_GENERAL);
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_SHA512_HMAC:
|
|
Packit Service |
8aa27d |
case CKM_SHA512_HMAC_GENERAL:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_SHA512;
|
|
Packit Service |
8aa27d |
*general = (mech == CKM_SHA512_HMAC_GENERAL);
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_SHA512_224_HMAC:
|
|
Packit Service |
8aa27d |
case CKM_SHA512_224_HMAC_GENERAL:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_SHA512_224;
|
|
Packit Service |
8aa27d |
*general = (mech == CKM_SHA512_224_HMAC_GENERAL);
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_SHA512_256_HMAC:
|
|
Packit Service |
8aa27d |
case CKM_SHA512_256_HMAC_GENERAL:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_SHA512_256;
|
|
Packit Service |
8aa27d |
*general = (mech == CKM_SHA512_256_HMAC_GENERAL);
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_IBM_SHA3_224_HMAC:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_IBM_SHA3_224;
|
|
Packit Service |
8aa27d |
*general = FALSE;
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_IBM_SHA3_256_HMAC:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_IBM_SHA3_256;
|
|
Packit Service |
8aa27d |
*general = FALSE;
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_IBM_SHA3_384_HMAC:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_IBM_SHA3_384;
|
|
Packit Service |
8aa27d |
*general = FALSE;
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
case CKM_IBM_SHA3_512_HMAC:
|
|
Packit Service |
8aa27d |
*digest_mech = CKM_IBM_SHA3_512;
|
|
Packit Service |
8aa27d |
*general = FALSE;
|
|
Packit Service |
8aa27d |
break;
|
|
Packit Service |
8aa27d |
default:
|
|
Packit Service |
8aa27d |
return CKR_MECHANISM_INVALID;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
return CKR_OK;
|
|
Packit Service |
8aa27d |
}
|
|
Packit Service |
8aa27d |
|
|
Packit |
8681c6 |
/* Compute specified SHA using either software or token implementation */
|
|
Packit |
8681c6 |
CK_RV compute_sha(STDLL_TokData_t *tokdata, CK_BYTE *data, CK_ULONG len,
|
|
Packit |
8681c6 |
CK_BYTE *hash, CK_ULONG mech)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
DIGEST_CONTEXT ctx;
|
|
Packit |
8681c6 |
CK_ULONG hash_len;
|
|
Packit |
8681c6 |
CK_RV rv;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memset(&ctx, 0x0, sizeof(ctx));
|
|
Packit |
8681c6 |
ctx.mech.mechanism = mech;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rv = get_sha_size(mech, &hash_len);
|
|
Packit |
8681c6 |
if (rv != CKR_OK)
|
|
Packit |
8681c6 |
return rv;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rv = sha_init(tokdata, NULL, &ctx, &ctx.mech);
|
|
Packit |
8681c6 |
if (rv != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEBUG("failed to create digest.\n");
|
|
Packit |
8681c6 |
return rv;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
rv = sha_hash(tokdata, NULL, FALSE, &ctx, data, len, hash, &hash_len);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
digest_mgr_cleanup(&ctx;;
|
|
Packit |
8681c6 |
return rv;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Compute SHA1 using software implementation */
|
|
Packit |
8681c6 |
CK_RV compute_sha1(STDLL_TokData_t *tokdata, CK_BYTE *data, CK_ULONG len,
|
|
Packit |
8681c6 |
CK_BYTE *hash)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
// XXX KEY
|
|
Packit |
8681c6 |
DIGEST_CONTEXT ctx;
|
|
Packit |
8681c6 |
CK_ULONG hash_len = SHA1_HASH_SIZE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memset(&ctx, 0x0, sizeof(ctx));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
sw_sha1_init(&ctx;;
|
|
Packit |
8681c6 |
if (ctx.context == NULL)
|
|
Packit |
8681c6 |
return CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return sw_sha1_hash(&ctx, data, len, hash, &hash_len);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV compute_md5(STDLL_TokData_t *tokdata, CK_BYTE *data, CK_ULONG len,
|
|
Packit |
8681c6 |
CK_BYTE *hash)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
DIGEST_CONTEXT ctx;
|
|
Packit |
8681c6 |
CK_ULONG hash_len = MD5_HASH_SIZE;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
UNUSED(tokdata);
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
memset(&ctx, 0x0, sizeof(ctx));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
sw_md5_init(&ctx;;
|
|
Packit |
8681c6 |
if (ctx.context == NULL)
|
|
Packit |
8681c6 |
return CKR_HOST_MEMORY;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return sw_md5_hash(&ctx, data, len, hash, &hash_len);
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV get_keytype(STDLL_TokData_t *tokdata, CK_OBJECT_HANDLE hkey,
|
|
Packit |
8681c6 |
CK_KEY_TYPE *keytype)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
CK_RV rc;
|
|
Packit |
8681c6 |
OBJECT *key_obj = NULL;
|
|
Packit |
8681c6 |
CK_ATTRIBUTE *attr = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
rc = object_mgr_find_in_map1(tokdata, hkey, &key_obj, READ_LOCK);
|
|
Packit |
8681c6 |
if (rc != CKR_OK) {
|
|
Packit |
8681c6 |
TRACE_DEVEL("object_mgr_find_in_map1 failed.\n");
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
rc = template_attribute_find(key_obj->template, CKA_KEY_TYPE, &attr);
|
|
Packit |
8681c6 |
if (rc == FALSE) {
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_KEY_TYPE_INCONSISTENT));
|
|
Packit |
8681c6 |
rc = CKR_KEY_TYPE_INCONSISTENT;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
*keytype = *(CK_KEY_TYPE *) attr->pValue;
|
|
Packit |
8681c6 |
rc = CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
object_put(tokdata, key_obj, TRUE);
|
|
Packit |
8681c6 |
key_obj = NULL;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return rc;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
CK_RV check_user_and_group()
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
int i;
|
|
Packit |
8681c6 |
uid_t uid, euid;
|
|
Packit |
8681c6 |
struct passwd *pw, *epw;
|
|
Packit |
8681c6 |
struct group *grp;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* Check for root user or Group PKCS#11 Membershp.
|
|
Packit |
8681c6 |
* Only these are allowed.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
uid = getuid();
|
|
Packit |
8681c6 |
euid = geteuid();
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/* Root or effective Root is ok */
|
|
Packit |
8681c6 |
if (uid == 0 || euid == 0)
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
/*
|
|
Packit |
8681c6 |
* Check for member of group. SAB get login seems to not work
|
|
Packit |
8681c6 |
* with some instances of application invocations (particularly
|
|
Packit |
8681c6 |
* when forked). So we need to get the group information.
|
|
Packit |
8681c6 |
* Really need to take the uid and map it to a name.
|
|
Packit |
8681c6 |
*/
|
|
Packit |
8681c6 |
grp = getgrnam("pkcs11");
|
|
Packit |
8681c6 |
if (grp == NULL) {
|
|
Packit |
8681c6 |
OCK_SYSLOG(LOG_ERR, "getgrnam() failed: %s\n", strerror(errno));
|
|
Packit |
8681c6 |
goto error;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (getgid() == grp->gr_gid || getegid() == grp->gr_gid)
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
/* Check if user or effective user is member of pkcs11 group */
|
|
Packit |
8681c6 |
pw = getpwuid(uid);
|
|
Packit |
8681c6 |
epw = getpwuid(euid);
|
|
Packit |
8681c6 |
for (i = 0; grp->gr_mem[i]; i++) {
|
|
Packit |
8681c6 |
if ((pw && (strncmp(pw->pw_name, grp->gr_mem[i],
|
|
Packit |
8681c6 |
strlen(pw->pw_name)) == 0)) ||
|
|
Packit |
8681c6 |
(epw && (strncmp(epw->pw_name, grp->gr_mem[i],
|
|
Packit |
8681c6 |
strlen(epw->pw_name)) == 0)))
|
|
Packit |
8681c6 |
return CKR_OK;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
error:
|
|
Packit |
8681c6 |
TRACE_ERROR("%s\n", ock_err(ERR_FUNCTION_FAILED));
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
return CKR_FUNCTION_FAILED;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
void copy_token_contents_sensibly(CK_TOKEN_INFO_PTR pInfo,
|
|
Packit |
8681c6 |
TOKEN_DATA *nv_token_data)
|
|
Packit |
8681c6 |
{
|
|
Packit |
8681c6 |
memcpy(pInfo, &nv_token_data->token_info, sizeof(CK_TOKEN_INFO_32));
|
|
Packit |
8681c6 |
pInfo->flags = nv_token_data->token_info.flags;
|
|
Packit |
8681c6 |
pInfo->ulMaxPinLen = nv_token_data->token_info.ulMaxPinLen;
|
|
Packit |
8681c6 |
pInfo->ulMinPinLen = nv_token_data->token_info.ulMinPinLen;
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (nv_token_data->token_info.ulTotalPublicMemory ==
|
|
Packit |
8681c6 |
(CK_ULONG_32) CK_UNAVAILABLE_INFORMATION) {
|
|
Packit |
8681c6 |
pInfo->ulTotalPublicMemory = (CK_ULONG) CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
pInfo->ulTotalPublicMemory =
|
|
Packit |
8681c6 |
nv_token_data->token_info.ulTotalPublicMemory;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (nv_token_data->token_info.ulFreePublicMemory ==
|
|
Packit |
8681c6 |
(CK_ULONG_32) CK_UNAVAILABLE_INFORMATION) {
|
|
Packit |
8681c6 |
pInfo->ulFreePublicMemory = (CK_ULONG) CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
pInfo->ulFreePublicMemory =
|
|
Packit |
8681c6 |
nv_token_data->token_info.ulFreePublicMemory;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (nv_token_data->token_info.ulTotalPrivateMemory ==
|
|
Packit |
8681c6 |
(CK_ULONG_32) CK_UNAVAILABLE_INFORMATION) {
|
|
Packit |
8681c6 |
pInfo->ulTotalPrivateMemory = (CK_ULONG) CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
pInfo->ulTotalPrivateMemory =
|
|
Packit |
8681c6 |
nv_token_data->token_info.ulTotalPrivateMemory;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
if (nv_token_data->token_info.ulFreePrivateMemory ==
|
|
Packit |
8681c6 |
(CK_ULONG_32) CK_UNAVAILABLE_INFORMATION) {
|
|
Packit |
8681c6 |
pInfo->ulFreePrivateMemory = (CK_ULONG) CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
} else {
|
|
Packit |
8681c6 |
pInfo->ulFreePrivateMemory =
|
|
Packit |
8681c6 |
nv_token_data->token_info.ulFreePrivateMemory;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|
|
Packit |
8681c6 |
pInfo->hardwareVersion = nv_token_data->token_info.hardwareVersion;
|
|
Packit |
8681c6 |
pInfo->firmwareVersion = nv_token_data->token_info.firmwareVersion;
|
|
Packit |
8681c6 |
pInfo->ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
|
|
Packit |
8681c6 |
/* pInfo->ulSessionCount is set at the API level */
|
|
Packit |
8681c6 |
pInfo->ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
|
|
Packit |
8681c6 |
pInfo->ulRwSessionCount = CK_UNAVAILABLE_INFORMATION;
|
|
Packit |
8681c6 |
}
|
|
Packit |
8681c6 |
|