diff options
Diffstat (limited to 'trust/module.c')
-rw-r--r-- | trust/module.c | 171 |
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 (); |