summaryrefslogtreecommitdiff
path: root/trust/module.c
diff options
context:
space:
mode:
Diffstat (limited to 'trust/module.c')
-rw-r--r--trust/module.c171
1 files changed, 75 insertions, 96 deletions
diff --git a/trust/module.c b/trust/module.c
index ba41884..5f8692b 100644
--- a/trust/module.c
+++ b/trust/module.c
@@ -36,6 +36,7 @@
#define CRYPTOKI_EXPORTS
+#include "argv.h"
#include "array.h"
#include "attrs.h"
#define P11_DEBUG_FLAG P11_DEBUG_TRUST
@@ -133,6 +134,19 @@ lookup_object_inlock (p11_session *session,
return NULL;
}
+static CK_RV
+check_index_writable (p11_session *session,
+ p11_index *index)
+{
+ if (index == p11_token_index (session->token)) {
+ if (!p11_token_is_writable (session->token))
+ return CKR_TOKEN_WRITE_PROTECTED;
+ else if (!session->read_write)
+ return CKR_SESSION_READ_ONLY;
+ }
+
+ return CKR_OK;
+}
static CK_RV
lookup_slot_inlock (CK_SLOT_ID id,
@@ -249,7 +263,8 @@ create_tokens_inlock (p11_array *tokens,
}
static void
-parse_argument (char *arg)
+parse_argument (char *arg,
+ void *unused)
{
char *value;
@@ -268,78 +283,6 @@ parse_argument (char *arg)
}
}
-static void
-parse_arguments (const char *string)
-{
- char quote = '\0';
- char *src, *dup, *at, *arg;
-
- if (!string)
- return;
-
- src = dup = strdup (string);
- if (!dup) {
- p11_message ("couldn't allocate memory for argument string");
- return;
- }
-
- arg = at = src;
- for (src = dup; *src; src++) {
-
- /* Matching quote */
- if (quote == *src) {
- quote = '\0';
-
- /* Inside of quotes */
- } else if (quote != '\0') {
- if (*src == '\\') {
- *at++ = *src++;
- if (!*src) {
- p11_message ("couldn't parse argument string: %s", string);
- goto done;
- }
- if (*src != quote)
- *at++ = '\\';
- }
- *at++ = *src;
-
- /* Space, not inside of quotes */
- } else if (isspace(*src)) {
- *at = 0;
- parse_argument (arg);
- arg = at;
-
- /* Other character outside of quotes */
- } else {
- switch (*src) {
- case '\'':
- case '"':
- quote = *src;
- break;
- case '\\':
- *at++ = *src++;
- if (!*src) {
- p11_message ("couldn't parse argument string: %s", string);
- goto done;
- }
- /* fall through */
- default:
- *at++ = *src;
- break;
- }
- }
- }
-
-
- if (at != arg) {
- *at = 0;
- parse_argument (arg);
- }
-
-done:
- free (dup);
-}
-
static CK_RV
sys_C_Finalize (CK_VOID_PTR reserved)
{
@@ -440,7 +383,7 @@ sys_C_Initialize (CK_VOID_PTR init_args)
p11_debug ("doing initialization");
if (args->pReserved)
- parse_arguments ((const char*)args->pReserved);
+ p11_argv_parse ((const char*)args->pReserved, parse_argument, NULL);
gl.sessions = p11_dict_new (p11_dict_ulongptr_hash,
p11_dict_ulongptr_equal,
@@ -614,7 +557,7 @@ sys_C_GetTokenInfo (CK_SLOT_ID id,
info->firmwareVersion.minor = 0;
info->hardwareVersion.major = PACKAGE_MAJOR;
info->hardwareVersion.minor = PACKAGE_MINOR;
- info->flags = CKF_TOKEN_INITIALIZED | CKF_WRITE_PROTECTED;
+ info->flags = CKF_TOKEN_INITIALIZED;
strncpy ((char*)info->manufacturerID, MANUFACTURER_ID, 32);
strncpy ((char*)info->model, TOKEN_MODEL, 16);
strncpy ((char*)info->serialNumber, TOKEN_SERIAL_NUMBER, 16);
@@ -636,6 +579,9 @@ sys_C_GetTokenInfo (CK_SLOT_ID id,
length = sizeof (info->label);
memset (info->label, ' ', sizeof (info->label));
memcpy (info->label, label, length);
+
+ if (!p11_token_is_writable (token))
+ info->flags |= CKF_WRITE_PROTECTED;
}
p11_unlock ();
@@ -677,8 +623,8 @@ sys_C_InitToken (CK_SLOT_ID id,
CK_ULONG pin_len,
CK_UTF8CHAR_PTR label)
{
- return_val_if_fail (check_slot (id), CKR_SLOT_ID_INVALID);
- return_val_if_reached (CKR_TOKEN_WRITE_PROTECTED);
+ p11_debug ("not supported");
+ return CKR_FUNCTION_NOT_SUPPORTED;
}
static CK_RV
@@ -715,13 +661,16 @@ sys_C_OpenSession (CK_SLOT_ID id,
} else if (!(flags & CKF_SERIAL_SESSION)) {
rv = CKR_SESSION_PARALLEL_NOT_SUPPORTED;
- } else if (flags & CKF_RW_SESSION) {
+ } else if ((flags & CKF_RW_SESSION) &&
+ !p11_token_is_writable (token)) {
rv = CKR_TOKEN_WRITE_PROTECTED;
} else {
session = p11_session_new (token);
if (p11_dict_set (gl.sessions, &session->handle, session)) {
rv = CKR_OK;
+ if (flags & CKF_RW_SESSION)
+ session->read_write = true;
*handle = session->handle;
p11_debug ("session: %lu", *handle);
} else {
@@ -838,7 +787,8 @@ sys_C_InitPIN (CK_SESSION_HANDLE handle,
CK_UTF8CHAR_PTR pin,
CK_ULONG pin_len)
{
- return_val_if_reached (CKR_TOKEN_WRITE_PROTECTED);
+ p11_debug ("not supported");
+ return CKR_FUNCTION_NOT_SUPPORTED;
}
static CK_RV
@@ -848,7 +798,8 @@ sys_C_SetPIN (CK_SESSION_HANDLE handle,
CK_UTF8CHAR_PTR new_pin,
CK_ULONG new_pin_len)
{
- return_val_if_reached (CKR_TOKEN_WRITE_PROTECTED);
+ p11_debug ("not supported");
+ return CKR_FUNCTION_NOT_SUPPORTED;
}
static CK_RV
@@ -921,7 +872,8 @@ sys_C_CreateObject (CK_SESSION_HANDLE handle,
CK_OBJECT_HANDLE_PTR new_object)
{
p11_session *session;
- CK_BBOOL token;
+ p11_index *index;
+ CK_BBOOL val;
CK_RV rv;
return_val_if_fail (new_object != NULL, CKR_ARGUMENTS_BAD);
@@ -932,12 +884,15 @@ sys_C_CreateObject (CK_SESSION_HANDLE handle,
rv = lookup_session (handle, &session);
if (rv == CKR_OK) {
- if (p11_attrs_findn_bool (template, count, CKA_TOKEN, &token) && token)
- rv = CKR_TOKEN_WRITE_PROTECTED;
+ if (p11_attrs_findn_bool (template, count, CKA_TOKEN, &val) && val)
+ index = p11_token_index (session->token);
+ else
+ index = session->index;
+ rv = check_index_writable (session, index);
}
if (rv == CKR_OK)
- rv = p11_index_add (session->index, template, count, new_object);
+ rv = p11_index_add (index, template, count, new_object);
p11_unlock ();
@@ -958,6 +913,7 @@ sys_C_CopyObject (CK_SESSION_HANDLE handle,
p11_session *session;
CK_ATTRIBUTE *original;
CK_ATTRIBUTE *attrs;
+ p11_index *index;
CK_BBOOL val;
CK_RV rv;
@@ -969,21 +925,22 @@ sys_C_CopyObject (CK_SESSION_HANDLE handle,
rv = lookup_session (handle, &session);
if (rv == CKR_OK) {
- original = lookup_object_inlock (session, object, NULL);
+ original = lookup_object_inlock (session, object, &index);
if (original == NULL)
rv = CKR_OBJECT_HANDLE_INVALID;
}
if (rv == CKR_OK) {
- if (p11_attrs_findn_bool (template, count, CKA_TOKEN, &val) && val)
- rv = CKR_TOKEN_WRITE_PROTECTED;
+ if (p11_attrs_findn_bool (template, count, CKA_TOKEN, &val))
+ index = val ? p11_token_index (session->token) : session->index;
+ rv = check_index_writable (session, index);
}
if (rv == CKR_OK) {
attrs = p11_attrs_dup (original);
attrs = p11_attrs_buildn (attrs, template, count);
attrs = p11_attrs_build (attrs, &token, NULL);
- rv = p11_index_take (session->index, attrs, new_object);
+ rv = p11_index_take (index, attrs, new_object);
}
p11_unlock ();
@@ -998,6 +955,9 @@ sys_C_DestroyObject (CK_SESSION_HANDLE handle,
CK_OBJECT_HANDLE object)
{
p11_session *session;
+ CK_ATTRIBUTE *attrs;
+ p11_index *index;
+ CK_BBOOL val;
CK_RV rv;
p11_debug ("in");
@@ -1006,11 +966,19 @@ sys_C_DestroyObject (CK_SESSION_HANDLE handle,
rv = lookup_session (handle, &session);
if (rv == CKR_OK) {
- rv = p11_index_remove (session->index, object);
- if (rv == CKR_OBJECT_HANDLE_INVALID) {
- if (p11_index_lookup (p11_token_index (session->token), object))
- rv = CKR_TOKEN_WRITE_PROTECTED;
+ attrs = lookup_object_inlock (session, object, &index);
+ if (attrs == NULL)
+ rv = CKR_OBJECT_HANDLE_INVALID;
+ else
+ rv = check_index_writable (session, index);
+
+ if (rv == CKR_OK && p11_attrs_find_bool (attrs, CKA_MODIFIABLE, &val) && !val) {
+ /* TODO: This should be replaced with CKR_ACTION_PROHIBITED */
+ rv = CKR_FUNCTION_REJECTED;
}
+
+ if (rv == CKR_OK)
+ rv = p11_index_remove (index, object);
}
p11_unlock ();
@@ -1120,6 +1088,9 @@ sys_C_SetAttributeValue (CK_SESSION_HANDLE handle,
CK_ULONG count)
{
p11_session *session;
+ CK_ATTRIBUTE *attrs;
+ p11_index *index;
+ CK_BBOOL val;
CK_RV rv;
p11_debug ("in");
@@ -1128,11 +1099,19 @@ sys_C_SetAttributeValue (CK_SESSION_HANDLE handle,
rv = lookup_session (handle, &session);
if (rv == CKR_OK) {
- rv = p11_index_set (session->index, object, template, count);
- if (rv == CKR_OBJECT_HANDLE_INVALID) {
- if (p11_index_lookup (p11_token_index (session->token), object))
- rv = CKR_TOKEN_WRITE_PROTECTED;
+ attrs = lookup_object_inlock (session, object, &index);
+ if (attrs == NULL) {
+ rv = CKR_OBJECT_HANDLE_INVALID;
+
+ } else if (p11_attrs_find_bool (attrs, CKA_MODIFIABLE, &val) && !val) {
+ /* TODO: This should be replaced with CKR_ACTION_PROHIBITED */
+ rv = CKR_ATTRIBUTE_READ_ONLY;
}
+
+ if (rv == CKR_OK)
+ rv = check_index_writable (session, index);
+ if (rv == CKR_OK)
+ rv = p11_index_set (index, object, template, count);
}
p11_unlock ();