diff options
author | Stefan Walter <stefw@src.gnome.org> | 2009-01-09 03:05:12 +0000 |
---|---|---|
committer | Stefan Walter <stefw@src.gnome.org> | 2009-01-09 03:05:12 +0000 |
commit | 523429269d3099636615ef9a763bb941fc1bcd3a (patch) | |
tree | efc8ebc20fcff99ff760f283e9fb6b9fedf07f8c /daemon | |
parent | 99efefe14cffb2894b83b52dfa889ec574177cba (diff) |
Make it easier to pick and choose between commonly used code bits in
* common/Makefile.am:
* daemon/Makefile.am:
* daemon/ui/Makefile.am:
* library/Makefile.am:
* pam/Makefile.am:
* pkcs11/gck/tests/Makefile.am:
* pkcs11/roots/Makefile.am:
* pkcs11/ssh-agent/Makefile.am:
* pkcs11/ssh-store/Makefile.am:
* pkcs11/ssh-store/tests/Makefile.am: Make it easier to pick and
choose between commonly used code bits in different modules.
* pkcs11/gck/Makefile.am:
* pkcs11/gck-temporary-test.c: Remove test code.
* daemon/gkr-daemon.c:
* daemon/pkcs11/gkr-pkcs11-auth.c:
* daemon/pkcs11/gkr-pkcs11-daemon.c:
* daemon/pkcs11/gkr-pkcs11-dispatch.c: (removed)
* daemon/pkcs11/gkr-pkcs11-dispatch.h: (removed)
* daemon/pkcs11/gkr-pkcs11-dispatch-session.c: (removed)
* daemon/pkcs11/gkr-pkcs11-dsa.c: (removed)
* daemon/pkcs11/gkr-pkcs11-dsa.h: (removed)
* daemon/pkcs11/gkr-pkcs11-rsa.c: (removed)
* daemon/pkcs11/gkr-pkcs11-rsa.h: (removed)
* daemon/pkcs11/Makefile.am:
* pkcs11/gkr-pkcs11-calls.h: (removed)
* pkcs11/gkr-pkcs11-mechanisms.h: (removed)
* pkcs11/gkr-pkcs11-message.c: (removed)
* pkcs11/gkr-pkcs11-message.h: (removed)
* pkcs11/gkr-pkcs11-module.c: (removed)
* pkcs11/Makefile.am:
* pkcs11/rpc-layer/gck-rpc-daemon-standalone.c:
* pkcs11/rpc-layer/gck-rpc-dispatch.c:
* pkcs11/rpc-layer/gck-rpc-layer.h:
* pkcs11/rpc-layer/gck-rpc-message.c:
* pkcs11/rpc-layer/gck-rpc-module.c:
* pkcs11/rpc-layer/gck-rpc-private.h:
* pkcs11/rpc-layer/Makefile.am:
* pkcs11/rpc-layer/p11-rpc-*: (remove old straggler files)
* configure.in: Integrate modular rpc-layer and remove old
dispatch and module code frome gnome-keyring-daemon.
svn path=/trunk/; revision=1449
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/Makefile.am | 1 | ||||
-rw-r--r-- | daemon/gkr-daemon.c | 27 | ||||
-rw-r--r-- | daemon/pkcs11/Makefile.am | 7 | ||||
-rw-r--r-- | daemon/pkcs11/gkr-pkcs11-auth.c | 3 | ||||
-rw-r--r-- | daemon/pkcs11/gkr-pkcs11-daemon.c | 4 | ||||
-rw-r--r-- | daemon/pkcs11/gkr-pkcs11-dispatch-session.c | 1661 | ||||
-rw-r--r-- | daemon/pkcs11/gkr-pkcs11-dispatch.c | 221 | ||||
-rw-r--r-- | daemon/pkcs11/gkr-pkcs11-dispatch.h | 39 | ||||
-rw-r--r-- | daemon/pkcs11/gkr-pkcs11-dsa.c | 190 | ||||
-rw-r--r-- | daemon/pkcs11/gkr-pkcs11-dsa.h | 42 | ||||
-rw-r--r-- | daemon/pkcs11/gkr-pkcs11-rsa.c | 344 | ||||
-rw-r--r-- | daemon/pkcs11/gkr-pkcs11-rsa.h | 49 | ||||
-rw-r--r-- | daemon/ui/Makefile.am | 2 |
13 files changed, 6 insertions, 2584 deletions
diff --git a/daemon/Makefile.am b/daemon/Makefile.am index a5b5b3cb..0d30ce6a 100644 --- a/daemon/Makefile.am +++ b/daemon/Makefile.am @@ -43,6 +43,7 @@ gnome_keyring_daemon_LDADD = \ $(top_builddir)/daemon/keyrings/libgkr-keyrings.la \ $(top_builddir)/daemon/ui/libgkr-ui.la \ $(top_builddir)/library/libgnome-keyring-common.la \ + $(top_builddir)/pkcs11/rpc-layer/libgck-rpc-layer.la \ $(top_builddir)/pkcs11/ssh-agent/libgck-ssh-agent.la \ $(top_builddir)/pkcs11/ssh-store/libgck-ssh-store.la \ $(top_builddir)/pkcs11/gck/libgck.la \ diff --git a/daemon/gkr-daemon.c b/daemon/gkr-daemon.c index ad6df722..3b2f7a2a 100644 --- a/daemon/gkr-daemon.c +++ b/daemon/gkr-daemon.c @@ -36,17 +36,7 @@ #include "library/gnome-keyring.h" -#include "pk/gkr-pk-object-storage.h" -#ifdef ROOT_CERTIFICATES -#include "pk/gkr-pk-root-storage.h" -#endif - #include "pkcs11/gkr-pkcs11-daemon.h" -#include "pkcs11/gkr-pkcs11-dispatch.h" - -#ifdef WITH_SSH -#include "ssh/gkr-ssh-storage.h" -#endif #include "ui/gkr-ask-daemon.h" @@ -638,32 +628,17 @@ gkr_daemon_complete_initialization(void) if (!gkr_pkcs11_daemon_initialize ()) return FALSE; - /* TODO: OLD, REMOVE */ - if (!gkr_pk_object_storage_initialize ()) - return FALSE; - -#ifdef ROOT_CERTIFICATES - /* TODO: OLD, REMOVE */ - if (!gkr_pk_root_storage_initialize ()) - return FALSE; -#endif - /* Initialize the appropriate components */ #ifdef WITH_SSH if (check_run_component ("ssh")) { if (!gkr_pkcs11_daemon_setup_ssh ()) return FALSE; - - /* TODO: OLD, REMOVE */ - if (!gkr_ssh_storage_initialize ()) - return FALSE; } #endif if (check_run_component ("pkcs11")) { - /* TODO: OLD, REMOVE */ - if (!gkr_pkcs11_dispatch_setup ()) + if (!gkr_pkcs11_daemon_setup_pkcs11 ()) return FALSE; } diff --git a/daemon/pkcs11/Makefile.am b/daemon/pkcs11/Makefile.am index 98982ee7..bcae8ce6 100644 --- a/daemon/pkcs11/Makefile.am +++ b/daemon/pkcs11/Makefile.am @@ -9,12 +9,7 @@ INCLUDES = \ DAEMON_SRCS = \ gkr-pkcs11-auth.c gkr-pkcs11-auth.h gkr-pkcs11-auth-ep.c \ - gkr-pkcs11-daemon.c gkr-pkcs11-daemon.h \ - gkr-pkcs11-dispatch.c gkr-pkcs11-dispatch.h \ - gkr-pkcs11-dispatch-session.c \ - gkr-pkcs11-dsa.c gkr-pkcs11-dsa.h \ - $(top_srcdir)/pkcs11/gkr-pkcs11-message.c \ - gkr-pkcs11-rsa.c gkr-pkcs11-rsa.h + gkr-pkcs11-daemon.c gkr-pkcs11-daemon.h noinst_LTLIBRARIES = libgkr-pkcs11.la diff --git a/daemon/pkcs11/gkr-pkcs11-auth.c b/daemon/pkcs11/gkr-pkcs11-auth.c index 4f948b55..04820f70 100644 --- a/daemon/pkcs11/gkr-pkcs11-auth.c +++ b/daemon/pkcs11/gkr-pkcs11-auth.c @@ -525,8 +525,7 @@ gkr_pkcs11_auth_session_closed_all (CK_SLOT_ID id) g_return_if_fail (per_slot_data); /* Remove all information about this slot */ - if (!g_hash_table_remove (per_slot_data, &id)) - g_return_if_reached (); + g_hash_table_remove (per_slot_data, &id); } void diff --git a/daemon/pkcs11/gkr-pkcs11-daemon.c b/daemon/pkcs11/gkr-pkcs11-daemon.c index 326b8eb0..d404b250 100644 --- a/daemon/pkcs11/gkr-pkcs11-daemon.c +++ b/daemon/pkcs11/gkr-pkcs11-daemon.c @@ -97,7 +97,6 @@ gkr_pkcs11_daemon_initialize (void) return TRUE; } -#if 0 static void pkcs11_rpc_cleanup (gpointer unused) { @@ -135,7 +134,7 @@ gkr_pkcs11_daemon_setup_pkcs11 (void) gkr_async_begin_concurrent (); - sock = gck_rpc_layer_initialize (base_dir, pkcs11_roof, NULL); + sock = gck_rpc_layer_initialize (base_dir, pkcs11_roof); gkr_async_end_concurrent (); @@ -150,7 +149,6 @@ gkr_pkcs11_daemon_setup_pkcs11 (void) return TRUE; } -#endif static void pkcs11_ssh_cleanup (gpointer unused) diff --git a/daemon/pkcs11/gkr-pkcs11-dispatch-session.c b/daemon/pkcs11/gkr-pkcs11-dispatch-session.c deleted file mode 100644 index 96002c17..00000000 --- a/daemon/pkcs11/gkr-pkcs11-dispatch-session.c +++ /dev/null @@ -1,1661 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gkr-pkcs11-dispatch-session.c - PKCS#11 session in daemon - - Copyright (C) 2007, Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter <stef@memberwebs.com> -*/ - -#include "config.h" - -#include <glib.h> - -#include "gkr-pkcs11-dispatch.h" -#include "gkr-pkcs11-dsa.h" -#include "gkr-pkcs11-rsa.h" - -#include "common/gkr-async.h" -#include "common/gkr-buffer.h" -#include "common/gkr-crypto.h" -#include "common/gkr-daemon-util.h" -#include "common/gkr-unix-credentials.h" - -#include "keyrings/gkr-keyring-login.h" - -#include "pk/gkr-pk-object.h" -#include "pk/gkr-pk-manager.h" -#include "pk/gkr-pk-session.h" -#include "pk/gkr-pk-storage.h" -#include "pk/gkr-pk-util.h" - -#include "pkcs11/gkr-pkcs11-message.h" -#include "pkcs11/gkr-pkcs11-calls.h" -#include "pkcs11/pkcs11.h" - -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> - -struct _SessionInfo; -typedef struct _SessionInfo SessionInfo; - -enum -{ - OPERATION_NONE = 0, - OPERATION_FIND, - OPERATION_ENCRYPT, - OPERATION_DECRYPT, - OPERATION_SIGN, - OPERATION_VERIFY -}; - -typedef void (*OperationCleanup) (SessionInfo* sinfo); - -struct _SessionInfo { - pid_t pid; /* Process ID of client */ - gboolean valid; /* Session is valid */ - gboolean readonly; /* Session is readonly */ - - guint operation_type; - GDestroyNotify operation_cleanup; - gpointer operation_data; - - guint deverror; /* The 'device' error code */ - - GkrPkSession *session; /* PK session to be used */ -}; - -/* - * TODO: Would this be the right error to pass back on a message - * parse failure? Or should we just disconnect? - */ -#define PROTOCOL_ERROR CKR_DEVICE_ERROR - -/* ----------------------------------------------------------------------------- - * HELPERS - */ - -static void -begin_operation (SessionInfo *sinfo, guint type, gpointer data, GDestroyNotify cleanup) -{ - g_assert (sinfo); - g_assert (type != OPERATION_NONE); - g_assert (sinfo->operation_type == OPERATION_NONE); - - sinfo->operation_type = type; - sinfo->operation_data = data; - sinfo->operation_cleanup = cleanup; -} - -static void -finish_operation (SessionInfo *sinfo) -{ - if (sinfo->operation_data) { - if (sinfo->operation_cleanup) - (sinfo->operation_cleanup) (sinfo->operation_data); - sinfo->operation_data = NULL; - } - - sinfo->operation_cleanup = NULL; - sinfo->operation_type = OPERATION_NONE; -} - -/* ----------------------------------------------------------------------------- - * PROTOCOL PARSING - */ - -static GArray* -read_attribute_array (GkrPkcs11Message* msg) -{ - CK_ATTRIBUTE attr; - GArray* attrs; - guint32 num, i; - guchar validity; - const guchar *value; - gsize n_value; - - g_assert (msg); - g_assert (gkr_pkcs11_message_verify_part (msg, "aA")); - - /* Get the number of items. We need this value to be correct */ - if (!gkr_buffer_get_uint32 (&msg->buffer, msg->parsed, - &msg->parsed, &num)) - return NULL; /* parse error */ - - attrs = gkr_pk_attributes_new (); - - /* We need to go ahead and read everything in all cases */ - for (i = 0; i < num; ++i) { - - memset (&attr, 0, sizeof (attr)); - - /* The attribute type */ - gkr_buffer_get_uint32 (&msg->buffer, msg->parsed, - &msg->parsed, (guint32*)(&attr.type)); - - /* Attribute validity */ - gkr_buffer_get_byte (&msg->buffer, msg->parsed, - &msg->parsed, &validity); - - /* And the data itself */ - if (validity) - gkr_buffer_get_byte_array (&msg->buffer, msg->parsed, &msg->parsed, - &value, &n_value); - - /* Don't act on this data unless no errors */ - if (gkr_buffer_has_error (&msg->buffer)) - break; - - if (validity) - gkr_pk_attribute_set_data (&attr, value, n_value); - else - attr.ulValueLen = (CK_ULONG)-1; - - /* Transfer ownership of the attribute to the array */ - g_array_append_val (attrs, attr); - } - - if (gkr_buffer_has_error (&msg->buffer)) { - gkr_pk_attributes_free (attrs); - attrs = NULL; - } - - return attrs; -} - -static gboolean -read_byte_array (GkrPkcs11Message *msg, CK_BYTE_PTR *val, CK_ULONG *vlen) -{ - const unsigned char* v; - size_t l; - - g_assert (msg && val && vlen); - g_assert (gkr_pkcs11_message_verify_part (msg, "ay")); - - if (!gkr_buffer_get_byte_array (&msg->buffer, msg->parsed, - &(msg->parsed), &v, &l)) - return FALSE; - - *val = (CK_BYTE_PTR)v; - *vlen = l; - return TRUE; -} - -static gboolean -read_mechanism (GkrPkcs11Message* msg, CK_MECHANISM_PTR mech) -{ - const guchar *value; - gsize n_value; - guint32 num; - - g_assert (msg); - g_assert (gkr_pkcs11_message_verify_part (msg, "M")); - - /* Get the mechanism type */ - if (!gkr_buffer_get_uint32 (&msg->buffer, msg->parsed, &msg->parsed, - &num)) - return FALSE; /* parse error */ - - if (!gkr_buffer_get_byte_array (&msg->buffer, msg->parsed, &msg->parsed, - &value, &n_value)) - return FALSE; /* parse error */ - - mech->mechanism = num; - mech->pParameter = (CK_VOID_PTR)value; - mech->ulParameterLen = n_value; - return TRUE; -} - -static CK_RV -read_object (GkrPkcs11Message *msg, SessionInfo *sinfo, GkrPkObject **res) -{ - CK_OBJECT_HANDLE obj; - GkrPkManager *manager; - - if (gkr_pkcs11_message_read_uint32 (msg, &obj) != CKR_OK) - return PROTOCOL_ERROR; - - /* Find the object in question */ - if (obj & GKR_PK_OBJECT_IS_PERMANENT) - manager = gkr_pk_manager_for_token (); - else - manager = sinfo->session->manager; - - *res = gkr_pk_manager_lookup (manager, obj); - if (!*res) - return CKR_OBJECT_HANDLE_INVALID; - - return CKR_OK; -} - -static void -write_session_info (GkrPkcs11Message *msg, CK_ULONG slot, CK_ULONG state, - CK_ULONG flags, CK_ULONG deverror) -{ - g_assert (msg); - g_assert (gkr_pkcs11_message_verify_part (msg, "I")); - - /* The slot id */ - gkr_buffer_add_uint32 (&msg->buffer, slot); - - /* The state */ - gkr_buffer_add_uint32 (&msg->buffer, state); - - /* The flags */ - gkr_buffer_add_uint32 (&msg->buffer, flags); - - /* The device error code */ - gkr_buffer_add_uint32 (&msg->buffer, deverror); -} - -/* ----------------------------------------------------------------------------- - * SESSION OPERATIONS - */ - -static CK_RV -session_C_OpenSession (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - CK_BYTE_PTR sig = NULL; - CK_ULONG siglen, slotid, flags, pid; - - if (!read_byte_array (req, &sig, &siglen)) - return PROTOCOL_ERROR; - if (gkr_pkcs11_message_read_uint32 (req, &pid) != CKR_OK) - return PROTOCOL_ERROR; - if (gkr_pkcs11_message_read_uint32 (req, &slotid) != CKR_OK) - return PROTOCOL_ERROR; - if (gkr_pkcs11_message_read_uint32 (req, &flags) != CKR_OK) - return PROTOCOL_ERROR; - - /* Verify that the module signature matches */ - if (siglen != GKR_PKCS11_HANDSHAKE_LEN || - memcmp (sig, GKR_PKCS11_HANDSHAKE, siglen) != 0) { - g_warning ("pkcs11 module is not speaking correct protocol"); - return CKR_DEVICE_ERROR; - } - - /* Mark session as valid and ready for action */ - sinfo->readonly = (flags & CKF_RW_SESSION) ? FALSE : TRUE; - sinfo->valid = TRUE; - - /* - * TODO: Once we have support for actually pulling out the - * peer's user/pid, we should use that instead of what the - * client tells us. - */ - sinfo->pid = pid; - sinfo->session = gkr_pk_session_new_for_client (pid); - - gkr_pk_storage_refresh_all (); - - return CKR_OK; -} - -static CK_RV -session_C_GetSessionInfo (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - uint32_t flags, state; - - /* No in arguments */ - - if (gkr_keyring_login_is_unlocked ()) - state = sinfo->readonly ? CKS_RO_USER_FUNCTIONS : CKS_RW_USER_FUNCTIONS; - else - state = sinfo->readonly ? CKS_RO_PUBLIC_SESSION : CKS_RW_PUBLIC_SESSION; - - flags = 0; - if (!sinfo->readonly) - flags |= CKF_RW_SESSION; - - write_session_info (resp, 0, state, flags, sinfo->deverror); - - return CKR_OK; -} - -static CK_RV -session_C_InitPIN (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* We don't support this stuff. We don't support 'SO' logins. */ - return CKR_USER_NOT_LOGGED_IN; -} - -static CK_RV -session_C_SetPIN (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* - * TODO: We may support this in the future. Since we are a - * CKF_PROTECTED_AUTHENTICATION_PATH type token, we would - * not accept a PIN, but instead prompt for it. - */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_GetOperationState (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* Nope, We don't bend that way */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_SetOperationState (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* Nope. We don't bend that way */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_Login (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - CK_BYTE_PTR pin = NULL; - CK_ULONG user_type, pin_len; - - if (gkr_pkcs11_message_read_uint32 (req, &user_type) != CKR_OK) - return PROTOCOL_ERROR; - if (!read_byte_array (req, &pin, &pin_len)) - return PROTOCOL_ERROR; - - if (user_type == CKU_SO) { - - /* Readonly session, SO can't log in */ - if (sinfo->readonly) - return CKR_SESSION_READ_ONLY_EXISTS; - - /* Actually SO can't log in at all ... */ - return CKR_USER_TYPE_INVALID; - - } else { - - return CKR_USER_TYPE_INVALID; - } - - /* - * Implement by unlocking gnome-keyring default keyring, since we - * a CKF_PROTECTED_AUTHENTICATION_PATH type token, we would - * not accept a PIN, but instead prompt for it. - */ - if (!gkr_keyring_login_unlock (NULL)) - return CKR_FUNCTION_FAILED; - - return CKR_OK; -} - -static CK_RV -session_C_Logout (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - if (!gkr_keyring_login_is_unlocked ()) - return CKR_USER_NOT_LOGGED_IN; - - /* - * TODO: What do we do here. I don't think we actually want to - * lock the login keyring. - */ - - return CKR_OK; -} - -/* ----------------------------------------------------------------------------- - * OBJECT OPERATIONS - */ - -static CK_RV -session_C_CreateObject (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - CK_OBJECT_CLASS cls; - GkrPkObject *object = NULL; - GArray *attrs = NULL; - CK_BBOOL token; - CK_RV ret; - - if (!(attrs = read_attribute_array (req))) - return PROTOCOL_ERROR; - - if (!gkr_pk_attributes_ulong (attrs, CKA_CLASS, &cls)) { - ret = CKR_TEMPLATE_INCOMPLETE; - goto done; - } - - /* Can only create public objects unless logged in */ - if (!gkr_keyring_login_is_unlocked () && gkc_pk_class_is_private (cls)) { - ret = CKR_USER_NOT_LOGGED_IN; - goto done; - } - - /* Find out if its a token object or not */ - if (!gkr_pk_attributes_boolean (attrs, CKA_TOKEN, &token)) - token = CK_FALSE; - - /* A readonly session cannot create token objects */ - if (token && sinfo->readonly) { - ret = CKR_SESSION_READ_ONLY; - goto done; - } - - ret = gkr_pk_object_create (sinfo->session, attrs, &object); - - if (ret != CKR_OK) - goto done; - - g_return_val_if_fail (object, CKR_GENERAL_ERROR); - g_return_val_if_fail (object->storage != NULL, CKR_GENERAL_ERROR); - g_return_val_if_fail (object->manager != NULL, CKR_GENERAL_ERROR); - - gkr_pkcs11_message_write_uint32 (resp, object->handle); - ret = CKR_OK; - -done: - if (object) - g_object_unref (object); - gkr_pk_attributes_free (attrs); - return ret; -} - -static CK_RV -session_C_CopyObject (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* - * TODO: We need to implement this, initially perhaps only - * only for session objects. - */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_DestroyObject (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - CK_OBJECT_HANDLE obj; - GkrPkManager *manager; - GkrPkObject *object; - CK_RV ret = CKR_OK; - gboolean res; - GError *err = NULL; - CK_BBOOL priv; - - if (gkr_pkcs11_message_read_uint32 (req, &obj) != CKR_OK) - return PROTOCOL_ERROR; - - /* Find the object in question */ - if (obj & GKR_PK_OBJECT_IS_PERMANENT) - manager = gkr_pk_manager_for_token (); - else - manager = sinfo->session->manager; - - object = gkr_pk_manager_lookup (manager, obj); - if (!object) - return CKR_OBJECT_HANDLE_INVALID; - - /* We can only destroy public objects unless logged in */ - if (!gkr_keyring_login_is_unlocked ()) { - ret = gkr_pk_object_get_bool (object, CKA_PRIVATE, &priv); - g_return_val_if_fail (ret == CKR_OK, CKR_GENERAL_ERROR); - - if (priv) - return CKR_USER_NOT_LOGGED_IN; - } - - /* A readonly session cannot destroy token objects */ - if (sinfo->readonly && obj & GKR_PK_OBJECT_IS_PERMANENT) - return CKR_SESSION_READ_ONLY; - - g_return_val_if_fail (object->storage, CKR_GENERAL_ERROR); - res = gkr_pk_storage_remove (object->storage, object, &err); - if (!res) { - g_message ("couldn't remove object from disk: %s", - err && err->message ? err->message : ""); - g_clear_error (&err); - ret = CKR_FUNCTION_FAILED; - } - - return ret; -} - -static CK_RV -session_C_GetObjectSize (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* TODO: We need to implement this */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_GetAttributeValue (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - GkrPkObject *object; - GArray* attrs; - CK_RV soft_ret = CKR_OK; - CK_RV ret = CKR_OK; - - ret = read_object (req, sinfo, &object); - if (ret != CKR_OK) - return ret; - - if (!(attrs = read_attribute_array (req))) - return PROTOCOL_ERROR; - - ret = gkr_pk_object_get_attributes (object, attrs); - - /* Certain ones aren't real failures */ - switch (ret) { - case CKR_ATTRIBUTE_SENSITIVE: - case CKR_ATTRIBUTE_TYPE_INVALID: - soft_ret = ret; - ret = CKR_OK; - break; - case CKR_BUFFER_TOO_SMALL: - g_assert (FALSE && "we shouldn't be returning this anywhere"); - break; - }; - - if (ret == CKR_OK) { - gkr_pkcs11_message_write_attribute_array (resp, (CK_ATTRIBUTE_PTR)attrs->data, - attrs->len); - gkr_pkcs11_message_write_uint32 (resp, soft_ret); - } - - /* Attributes have been filled in with allocated values, so deep free */ - gkr_pk_attributes_free (attrs); - - return ret; -} - -static CK_RV -session_C_SetAttributeValue (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - GkrPkObject *object; - GArray* attrs; - CK_RV ret; - - ret = read_object (req, sinfo, &object); - if (ret != CKR_OK) - return ret; - - if (!(attrs = read_attribute_array (req))) - return PROTOCOL_ERROR; - - ret = gkr_pk_object_set_attributes (object, attrs); - gkr_pk_attributes_free (attrs); - - return ret; -} - -static void -free_object_list (gpointer data) -{ - GList *l, *objects = data; - for (l = objects; l; l = g_list_next (l)) - g_object_unref (l->data); - g_list_free (objects); -} - -static CK_RV -session_C_FindObjectsInit (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - CK_BBOOL token; - GList *l, *objects = NULL; - GArray *attrs; - gboolean all; - - /* Abandon any current operation */ - if (sinfo->operation_type) { - finish_operation (sinfo); - g_assert (!sinfo->operation_type); - } - - if (!(attrs = read_attribute_array (req))) - return PROTOCOL_ERROR; - - all = !gkr_pk_attributes_boolean (attrs, CKA_TOKEN, &token); - objects = NULL; - - /* All or only token objects? */ - if(all || token) { - l = gkr_pk_manager_find (gkr_pk_manager_for_token (), 0, attrs); - objects = g_list_concat (objects, l); - } - - /* All or only session objects? */ - if (all || !token) { - l = gkr_pk_manager_find (sinfo->session->manager, 0, attrs); - objects = g_list_concat (objects, l); - } - - for (l = objects; l; l = g_list_next (l)) - g_object_ref (GKR_PK_OBJECT (l->data)); - begin_operation (sinfo, OPERATION_FIND, objects, free_object_list); - - gkr_pk_attributes_free (attrs); - - /* No response */ - return CKR_OK; -} - -static CK_RV -session_C_FindObjects (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - GkrPkObject *obj; - GList* objects; - CK_ULONG max, n_objects, i; - - if (sinfo->operation_type != OPERATION_FIND) - return CKR_OPERATION_NOT_INITIALIZED; - - if (gkr_pkcs11_message_read_uint32 (req, &max) != CKR_OK) - return PROTOCOL_ERROR; - - objects = (GList*)sinfo->operation_data; - - /* Write out an array of ulongs */ - g_assert (gkr_pkcs11_message_verify_part (resp, "au")); - - /* First the number returned */ - n_objects = MIN (max, g_list_length (objects)); - gkr_buffer_add_uint32 (&resp->buffer, n_objects); - - /* Now each of them */ - for (i = 0; i < n_objects; ++i) { - obj = GKR_PK_OBJECT (objects->data); - objects = g_list_remove (objects, obj); - - g_assert (obj); - g_assert (obj->handle); - - gkr_buffer_add_uint32 (&resp->buffer, obj->handle); - g_object_unref (obj); - } - - /* In case we get called again, or there are leftovers */ - sinfo->operation_data = objects; - - return CKR_OK; -} - -static CK_RV -session_C_FindObjectsFinal (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - if (sinfo->operation_type != OPERATION_FIND) - return CKR_OPERATION_NOT_INITIALIZED; - - finish_operation (sinfo); - return CKR_OK; -} - -/* ----------------------------------------------------------------------------- - * ENCRYPTION OPERATIONS - */ - -typedef struct _CryptContext { - CK_MECHANISM_TYPE mechanism; - GkrPkObject *key; -} CryptContext; - -static CryptContext* -new_crypt_context (CK_MECHANISM_TYPE mech, GkrPkObject *key) -{ - CryptContext *ctx; - g_assert (key); - ctx = g_new0 (CryptContext, 1); - ctx->mechanism = mech; - ctx->key = key; - g_object_ref (key); - return ctx; -} - -static void -free_crypt_context (gpointer data) -{ - CryptContext *ctx = (CryptContext*)data; - if (ctx->key) - g_object_unref (ctx->key); - g_free (ctx); -} - -static CK_RV -session_C_EncryptInit (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - GkrPkObject *key; - CK_MECHANISM mech; - CK_RV ret; - - /* Abandon any current operation */ - if (sinfo->operation_type) { - finish_operation (sinfo); - g_assert (!sinfo->operation_type); - } - - if (!read_mechanism (req, &mech)) - return PROTOCOL_ERROR; - ret = read_object (req, sinfo, &key); - if (ret != CKR_OK) - return ret; - - switch (mech.mechanism) { - case CKM_RSA_PKCS: - case CKM_RSA_X_509: - ret = gkr_pkcs11_rsa_encrypt (key, NULL, NULL, 0, NULL, 0); - break; - default: - ret = CKR_MECHANISM_INVALID; - break; - }; - - if (ret == CKR_OK) - begin_operation (sinfo, OPERATION_ENCRYPT, - new_crypt_context (mech.mechanism, key), - free_crypt_context); - - return ret; -} - -static CK_RV -session_C_Encrypt (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - CryptContext *ctx; - CK_BYTE_PTR plain; - CK_ULONG n_plain; - gsize n_encrypted; - guchar *encrypted; - CK_RV ret; - - if (sinfo->operation_type != OPERATION_ENCRYPT) - return CKR_OPERATION_NOT_INITIALIZED; - - if (!read_byte_array (req, &plain, &n_plain)) - return PROTOCOL_ERROR; - - ctx = (CryptContext*)sinfo->operation_data; - switch (ctx->mechanism) { - case CKM_RSA_PKCS: - ret = gkr_pkcs11_rsa_encrypt (ctx->key, gkr_crypto_rsa_pad_two, - plain, n_plain, - &encrypted, &n_encrypted); - break; - case CKM_RSA_X_509: - ret = gkr_pkcs11_rsa_encrypt (ctx->key, gkr_crypto_rsa_pad_raw, - plain, n_plain, - &encrypted, &n_encrypted); - break; - default: - g_return_val_if_reached (CKR_GENERAL_ERROR); - break; - }; - - if (ret == CKR_OK) { - g_return_val_if_fail (encrypted, CKR_GENERAL_ERROR); - ret = gkr_pkcs11_message_write_byte_array (resp, encrypted, n_encrypted); - g_free (encrypted); - } - - finish_operation (sinfo); - return ret; -} - -static CK_RV -session_C_EncryptUpdate (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support this incremental encryption */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_EncryptFinal (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support this incremental encryption */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -/* ----------------------------------------------------------------------------- - * DECRYPTION OPERATIONS - */ - -static CK_RV -session_C_DecryptInit (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - GkrPkObject *key; - CK_MECHANISM mech; - CK_RV ret; - - /* Abandon any current operation */ - if (sinfo->operation_type) { - finish_operation (sinfo); - g_assert (!sinfo->operation_type); - } - - if (!read_mechanism (req, &mech)) - return PROTOCOL_ERROR; - ret = read_object (req, sinfo, &key); - if (ret != CKR_OK) - return ret; - - switch (mech.mechanism) { - case CKM_RSA_PKCS: - case CKM_RSA_X_509: - ret = gkr_pkcs11_rsa_decrypt (key, NULL, NULL, 0, NULL, 0); - break; - default: - ret = CKR_MECHANISM_INVALID; - break; - }; - - if (ret == CKR_OK) - begin_operation (sinfo, OPERATION_DECRYPT, - new_crypt_context (mech.mechanism, key), - free_crypt_context); - - return ret; -} - -static CK_RV -session_C_Decrypt (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - CryptContext *ctx; - CK_BYTE_PTR encrypted; - CK_ULONG n_encrypted; - gsize n_data; - guchar *data; - CK_RV ret; - - if (sinfo->operation_type != OPERATION_DECRYPT) - return CKR_OPERATION_NOT_INITIALIZED; - - if (!read_byte_array (req, &encrypted, &n_encrypted)) - return PROTOCOL_ERROR; - - ctx = (CryptContext*)sinfo->operation_data; - switch (ctx->mechanism) { - case CKM_RSA_PKCS: - ret = gkr_pkcs11_rsa_decrypt (ctx->key, gkr_crypto_rsa_unpad_two, - encrypted, n_encrypted, - &data, &n_data); - break; - case CKM_RSA_X_509: - ret = gkr_pkcs11_rsa_decrypt (ctx->key, NULL, - encrypted, n_encrypted, - &data, &n_data); - break; - default: - g_return_val_if_reached (CKR_GENERAL_ERROR); - break; - }; - - if (ret == CKR_OK) { - g_return_val_if_fail (data, CKR_GENERAL_ERROR); - ret = gkr_pkcs11_message_write_byte_array (resp, data, n_data); - g_free (data); - } - - finish_operation (sinfo); - return ret; -} - -static CK_RV -session_C_DecryptUpdate (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support this incremental decryption */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_DecryptFinal (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support this incremental decryption */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -/* ----------------------------------------------------------------------------- - * DIGEST OPERATIONS - */ - -static CK_RV -session_C_DigestInit (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* We don't do digests */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_Digest (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* We don't do digests */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_DigestUpdate (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* We don't do digests */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_DigestKey (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* We don't do digests */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_DigestFinal (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* We don't do digests */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -/* ----------------------------------------------------------------------------- - * SIGN OPERATIONS - */ - -static CK_RV -session_C_SignInit (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - GkrPkObject *key; - CK_MECHANISM mech; - CK_RV ret; - - /* Abandon any current operation */ - if (sinfo->operation_type) { - finish_operation (sinfo); - g_assert (!sinfo->operation_type); - } - - if (!read_mechanism (req, &mech)) - return PROTOCOL_ERROR; - ret = read_object (req, sinfo, &key); - if (ret != CKR_OK) - return ret; - - switch (mech.mechanism) { - case CKM_RSA_PKCS: - case CKM_RSA_X_509: - ret = gkr_pkcs11_rsa_sign (key, NULL, NULL, 0, NULL, 0); - break; - case CKM_DSA: - ret = gkr_pkcs11_dsa_sign (key, NULL, 0, NULL, 0); - break; - default: - ret = CKR_MECHANISM_INVALID; - break; - }; - - if (ret == CKR_OK) - begin_operation (sinfo, OPERATION_SIGN, - new_crypt_context (mech.mechanism, key), - free_crypt_context); - - return ret; -} - -static CK_RV -session_C_Sign (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - CryptContext *ctx; - CK_BYTE_PTR data; - CK_ULONG n_data; - gsize n_signature; - guchar *signature; - CK_RV ret; - - if (sinfo->operation_type != OPERATION_SIGN) - return CKR_OPERATION_NOT_INITIALIZED; - - if (!read_byte_array (req, &data, &n_data)) - return PROTOCOL_ERROR; - - ctx = (CryptContext*)sinfo->operation_data; - switch (ctx->mechanism) { - case CKM_RSA_PKCS: - ret = gkr_pkcs11_rsa_sign (ctx->key, gkr_crypto_rsa_pad_one, - data, n_data, - &signature, &n_signature); - break; - case CKM_RSA_X_509: - ret = gkr_pkcs11_rsa_sign (ctx->key, gkr_crypto_rsa_pad_raw, - data, n_data, - &signature, &n_signature); - break; - case CKM_DSA: - ret = gkr_pkcs11_dsa_sign (ctx->key, data, n_data, - &signature, &n_signature); - break; - default: - g_return_val_if_reached (CKR_GENERAL_ERROR); - break; - }; - - if (ret == CKR_OK) { - g_return_val_if_fail (signature, CKR_GENERAL_ERROR); - ret = gkr_pkcs11_message_write_byte_array (resp, signature, n_signature); - g_free (signature); - } - - finish_operation (sinfo); - return ret; -} - -static CK_RV -session_C_SignUpdate (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support this incremental signing */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_SignFinal (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support this incremental signing */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_SignRecoverInit (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* TODO: Need to implement */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_SignRecover (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* TODO: Need to implement */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -/* ----------------------------------------------------------------------------- - * VERIFY OPERATIONS - */ - -static CK_RV -session_C_VerifyInit (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - GkrPkObject *key; - CK_MECHANISM mech; - CK_RV ret; - - /* Abandon any current operation */ - if (sinfo->operation_type) { - finish_operation (sinfo); - g_assert (!sinfo->operation_type); - } - - if (!read_mechanism (req, &mech)) - return PROTOCOL_ERROR; - ret = read_object (req, sinfo, &key); - if (ret != CKR_OK) - return ret; - - switch (mech.mechanism) { - case CKM_RSA_PKCS: - case CKM_RSA_X_509: - ret = gkr_pkcs11_rsa_verify (key, NULL, NULL, 0, NULL, 0); - break; - case CKM_DSA: - ret = gkr_pkcs11_dsa_verify (key, NULL, 0, NULL, 0); - break; - default: - ret = CKR_MECHANISM_INVALID; - break; - }; - - if (ret == CKR_OK) - begin_operation (sinfo, OPERATION_VERIFY, - new_crypt_context (mech.mechanism, key), - free_crypt_context); - - return ret; -} - -static CK_RV -session_C_Verify (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - CryptContext *ctx; - CK_BYTE_PTR signature, data; - CK_ULONG n_signature, n_data; - CK_RV ret; - - if (sinfo->operation_type != OPERATION_VERIFY) - return CKR_OPERATION_NOT_INITIALIZED; - - if (!read_byte_array (req, &data, &n_data)) - return PROTOCOL_ERROR; - if (!read_byte_array (req, &signature, &n_signature)) - return PROTOCOL_ERROR; - - ctx = (CryptContext*)sinfo->operation_data; - switch (ctx->mechanism) { - case CKM_RSA_PKCS: - ret = gkr_pkcs11_rsa_verify (ctx->key, gkr_crypto_rsa_pad_one, - data, n_data, - signature, n_signature); - break; - case CKM_RSA_X_509: - ret = gkr_pkcs11_rsa_verify (ctx->key, gkr_crypto_rsa_pad_raw, - data, n_data, - signature, n_signature); - break; - case CKM_DSA: - ret = gkr_pkcs11_dsa_verify (ctx->key, data, n_data, - signature, n_signature); - break; - default: - g_return_val_if_reached (CKR_GENERAL_ERROR); - break; - }; - - finish_operation (sinfo); - return ret; -} - -static CK_RV -session_C_VerifyUpdate (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support this incremental verifying */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_VerifyFinal (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support this incremental verifying */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_VerifyRecoverInit (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support this recoverable signing */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_VerifyRecover (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support this recoverable signing */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -/* ----------------------------------------------------------------------------- - * COMPOUND OPERATIONS - */ - -static CK_RV -session_C_DigestEncryptUpdate (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* We don't do digests */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_DecryptDigestUpdate (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* We don't do digests */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_SignEncryptUpdate (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* Can't do this with an RSA key */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_DecryptVerifyUpdate (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* Can't do this with an RSA key */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -/* ----------------------------------------------------------------------------- - * KEY OPERATIONS - */ - -static CK_RV -session_C_GenerateKey (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* TODO: We need to implement this */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_GenerateKeyPair (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* TODO: We need to implement this */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_WrapKey (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* TODO: We need to implement this */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_UnwrapKey (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* TODO: We need to implement this */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -static CK_RV -session_C_DeriveKey (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* RSA keys don't support derivation */ - return CKR_FUNCTION_NOT_SUPPORTED; -} - -/* ----------------------------------------------------------------------------- - * RANDOM OPERATIONS - */ - -static CK_RV -session_C_SeedRandom (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* We don't have a RNG */ - return CKR_RANDOM_NO_RNG; -} - -static CK_RV -session_C_GenerateRandom (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - /* We don't have a RNG */ - return CKR_RANDOM_NO_RNG; -} - -/* ----------------------------------------------------------------------------- - * SESSION THREAD - */ - -static SessionInfo* -session_info_new () -{ - SessionInfo *sinfo = g_new0 (SessionInfo, 1); - sinfo->session = NULL; /* We assign this when the session opens */ - return sinfo; -} - -static void -session_info_free (SessionInfo *sinfo) -{ - if (sinfo) { - if (sinfo->session) - g_object_unref (sinfo->session); - g_free (sinfo); - } -} - -static gboolean -session_process (SessionInfo *sinfo, GkrPkcs11Message *req, - GkrPkcs11Message *resp) -{ - CK_RV ret = CKR_OK; - - /* This should have been checked by the parsing code */ - g_assert (req->call_id > PKCS11_CALL_ERROR); - g_assert (req->call_id < PKCS11_CALL_MAX); - - /* Prepare a response for the function to fill in */ - gkr_pkcs11_message_prep (resp, req->call_id, GKR_PKCS11_RESPONSE); - - switch(req->call_id) { - - #define CASE_CALL(name) \ - case PKCS11_CALL_##name: \ - ret = session_##name (sinfo, req, resp); \ - break; - CASE_CALL(C_OpenSession) - CASE_CALL(C_GetSessionInfo) - CASE_CALL(C_InitPIN) - CASE_CALL(C_SetPIN) - CASE_CALL(C_GetOperationState) - CASE_CALL(C_SetOperationState) - CASE_CALL(C_Login) - CASE_CALL(C_Logout) - CASE_CALL(C_CreateObject) - CASE_CALL(C_CopyObject) - CASE_CALL(C_DestroyObject) - CASE_CALL(C_GetObjectSize) - CASE_CALL(C_GetAttributeValue) - CASE_CALL(C_SetAttributeValue) - CASE_CALL(C_FindObjectsInit) - CASE_CALL(C_FindObjects) - CASE_CALL(C_FindObjectsFinal) - CASE_CALL(C_EncryptInit) - CASE_CALL(C_Encrypt) - CASE_CALL(C_EncryptUpdate) - CASE_CALL(C_EncryptFinal) - CASE_CALL(C_DecryptInit) - CASE_CALL(C_Decrypt) - CASE_CALL(C_DecryptUpdate) - CASE_CALL(C_DecryptFinal) - CASE_CALL(C_DigestInit) - CASE_CALL(C_Digest) - CASE_CALL(C_DigestUpdate) - CASE_CALL(C_DigestKey) - CASE_CALL(C_DigestFinal) - CASE_CALL(C_SignInit) - CASE_CALL(C_Sign) - CASE_CALL(C_SignUpdate) - CASE_CALL(C_SignFinal) - CASE_CALL(C_SignRecoverInit) - CASE_CALL(C_SignRecover) - CASE_CALL(C_VerifyInit) - CASE_CALL(C_Verify) - CASE_CALL(C_VerifyUpdate) - CASE_CALL(C_VerifyFinal) - CASE_CALL(C_VerifyRecoverInit) - CASE_CALL(C_VerifyRecover) - CASE_CALL(C_DigestEncryptUpdate) - CASE_CALL(C_DecryptDigestUpdate) - CASE_CALL(C_SignEncryptUpdate) - CASE_CALL(C_DecryptVerifyUpdate) - CASE_CALL(C_GenerateKey) - CASE_CALL(C_GenerateKeyPair) - CASE_CALL(C_WrapKey) - CASE_CALL(C_UnwrapKey) - CASE_CALL(C_DeriveKey) - CASE_CALL(C_SeedRandom) - CASE_CALL(C_GenerateRandom) - #undef CASE_CALL - - default: - /* This should have been caught by the parse code */ - g_return_val_if_reached (FALSE); - break; - }; - - /* Parsing errors? */ - if (gkr_pkcs11_message_buffer_error (req)) { - g_warning ("invalid request from module, probably too short"); - ret = PROTOCOL_ERROR; - } - - /* Out of memory errors? */ - if (gkr_pkcs11_message_buffer_error (resp)) { - g_warning ("out of memory error putting together message"); - ret = CKR_DEVICE_MEMORY; - } - - /* A filled in response */ - if (ret == CKR_OK) { - - /* - * Since we're dealing with many many functions above generating - * these messages we want to make sure each of them actually - * does what it's supposed to. - */ - - g_assert (gkr_pkcs11_message_is_verified (resp)); - g_assert (resp->call_type == GKR_PKCS11_RESPONSE); - g_assert (resp->call_id == req->call_id); - g_assert (gkr_pkcs11_calls[resp->call_id].response); - g_assert (strcmp (gkr_pkcs11_calls[resp->call_id].response, - resp->signature) == 0); - - /* Fill in an error respnose */ - } else { - /* - * When there's an error any operation automatically done. - * We make an exception for functions which we don't implement. - */ - if (ret != CKR_FUNCTION_NOT_SUPPORTED && ret != CKR_OPERATION_ACTIVE) - finish_operation (sinfo); - - gkr_pkcs11_message_prep (resp, PKCS11_CALL_ERROR, GKR_PKCS11_RESPONSE); - gkr_buffer_add_uint32 (&resp->buffer, (uint32_t)ret); - - /* Out of memory errors? */ - g_assert (!gkr_pkcs11_message_buffer_error (resp)); - } - - return TRUE; -} - -static gboolean -session_read (int sock, guchar* data, size_t len) -{ - int r; - - g_assert (sock >= 0); - g_assert (data); - g_assert (len > 0); - - while (len > 0) { - - /* Don't block other threads during the read */ - gkr_async_begin_concurrent (); - - r = read (sock, data, len); - - gkr_async_end_concurrent (); - - if (r == 0) { - /* Connection was closed on client */ - return FALSE; - } else if (r == -1) { - if (errno == EBADF || errno == 0) { - /* Connection was closed by main thread */ - return FALSE; - } else if (errno != EAGAIN && errno != EINTR) { - g_warning ("couldn't receive data: %s", strerror (errno)); - return FALSE; - } - } else { - data += r; - len -= r; - } - } - - return TRUE; -} - -static gboolean -session_write (int sock, guchar* data, size_t len) -{ - int r; - - g_assert (sock >= 0); - g_assert (data); - g_assert (len > 0); - - while (len > 0) { - - /* Don't block other threads during the read */ - gkr_async_begin_concurrent (); - - r = write (sock, data, len); - - gkr_async_end_concurrent (); - - if (r == -1) { - if (errno == EPIPE) { - /* Connection closed from client */ - return FALSE; - } else if (errno == EBADF || errno == 0) { - /* Connection closed from main thread */ - return FALSE; - } else if (errno != EAGAIN && errno != EINTR) { - g_warning ("couldn't send data: %s", strerror (errno)); - return FALSE; - } - } else { - data += r; - len -= r; - } - } - - return TRUE; -} - -static gboolean -session_read_credentials (int sock, pid_t *pid, uid_t *uid) -{ - gboolean ret; - - gkr_async_begin_concurrent (); - - ret = gkr_unix_credentials_read (sock, pid, uid) >= 0; - - gkr_async_end_concurrent (); - - return ret; -} - -gpointer -gkr_pkcs11_dispatch_session_thread (gpointer user_data) -{ - SessionInfo *sinfo; - GkrPkcs11Message *req, *resp; - guchar buf[4]; - CK_RV ret; - uint32_t len; - int sock; - uid_t uid; - pid_t pid; - - /* The argument to the worker thread is the socket */ - sock = GPOINTER_TO_INT (user_data); - g_assert (sock >= 0); - - /* Make sure the credentials are appropriate */ - if (!session_read_credentials (sock, &pid, &uid)) - return NULL; - if (getuid() != uid) { - g_warning ("uid mismatch: %u, should be %u\n", (guint)uid, (guint)getuid()); - return NULL; - } - - /* Note the current client application */ - gkr_daemon_client_set_current (pid, NULL, NULL); - - /* Setup our buffers */ - /* TODO: Do these need to be secure buffers? */ - req = gkr_pkcs11_message_new ((GkrBufferAllocator)g_realloc); - resp = gkr_pkcs11_message_new ((GkrBufferAllocator)g_realloc); - if (!req || !resp) - g_error ("out of memory"); - - sinfo = session_info_new (); - - /* The main thread loop */ - while (TRUE) { - - if (gkr_async_is_stopping ()) - break; - - gkr_pkcs11_message_reset (req); - gkr_pkcs11_message_reset (resp); - - /* Read the number of bytes ... */ - if (!session_read (sock, buf, 4)) - break; - len = gkr_buffer_decode_uint32 (buf); - - /* Allocate memory */ - if (len >= 0x0FFFFFFF) { - g_warning ("invalid message size from module: %u bytes", len); - break; - } - - gkr_buffer_reserve (&req->buffer, req->buffer.len + len); - - /* ... and read/parse in the actual message */ - if (!session_read (sock, req->buffer.buf, len)) - break; - gkr_buffer_add_empty (&req->buffer, len); - ret = gkr_pkcs11_message_parse (req, GKR_PKCS11_REQUEST); - if (ret != CKR_OK) - break; - - if (gkr_async_is_stopping ()) - break; - - /* ... send for processing ... */ - if (!session_process (sinfo, req, resp)) - break; - - if (gkr_async_is_stopping ()) - break; - - /* .. send back response length, and then response data */ - gkr_buffer_encode_uint32 (buf, resp->buffer.len); - if(!session_write (sock, buf, 4) || - !session_write (sock, resp->buffer.buf, resp->buffer.len)) - break; - } - - session_info_free (sinfo); - - /* socket is closed elsewhere */ - shutdown (sock, SHUT_RDWR); - - return NULL; -} - diff --git a/daemon/pkcs11/gkr-pkcs11-dispatch.c b/daemon/pkcs11/gkr-pkcs11-dispatch.c deleted file mode 100644 index a25cecc9..00000000 --- a/daemon/pkcs11/gkr-pkcs11-dispatch.c +++ /dev/null @@ -1,221 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gkr-pkcs11-dispatch.c - main connection/thread handling - - Copyright (C) 2007, Nate Nielsen - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Nate Nielsen <nielsen@memberwebs.com> -*/ - -#include <glib.h> - -#include "gkr-pkcs11-dispatch.h" - -#include "common/gkr-async.h" -#include "common/gkr-cleanup.h" -#include "common/gkr-daemon-util.h" -#include "common/gkr-secure-memory.h" - -#include "pkcs11/gkr-pkcs11-calls.h" -#include "pkcs11/gkr-pkcs11-message.h" - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <errno.h> -#include <unistd.h> -#include <string.h> - -#ifdef _DEBUG -#include <assert.h> -#endif - -/* ----------------------------------------------------------------------------- - * LOGGING - * - * Common code used in both the module and the daemon, requires this - * is implemented so that it can log any warnings appropriately. - */ - -void -gkr_pkcs11_warn (const char* msg, ...) -{ - va_list va; - va_start (va, msg); - g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, msg, va); - va_end (va); -} - -/* ----------------------------------------------------------------------------- - * PKCS#11 DISPATCH - */ - -/* The socket path on which we're listening */ -static gchar *pkcs11_socket_path = NULL; -static int pkcs11_socket_fd = -1; -static GIOChannel *pkcs11_socket_channel = NULL; -static GHashTable *session_workers = NULL; - -static void -stop_connection (gpointer key, gpointer value, gpointer data) -{ - GkrAsyncWorker *worker = (GkrAsyncWorker*)key; - int socket = GPOINTER_TO_INT (value); - - g_assert (socket >= 0); - g_assert (worker); - - /* This makes sure the thread isn't blocked listening on the socket */ - shutdown (socket, SHUT_RDWR); - - /* completed_connection will be called to actually close the socket */ - gkr_async_worker_stop (worker); -} - -static void -completed_connection (GkrAsyncWorker* worker, gpointer result, gpointer user_data) -{ - int socket = GPOINTER_TO_INT (user_data); - g_assert (socket >= 0); - close (socket); - - /* This will be NULL when we're shutting down */ - if (session_workers) - g_hash_table_remove (session_workers, worker); -} - -static gboolean -handle_new_connection (GIOChannel *channel, GIOCondition cond, gpointer callback_data) -{ - GkrAsyncWorker *worker; - int fd; - int new_fd; - struct sockaddr_un addr; - socklen_t addrlen; - - g_assert (session_workers); - - fd = g_io_channel_unix_get_fd (channel); - - addrlen = sizeof (addr); - new_fd = accept (fd, (struct sockaddr *) &addr, &addrlen); - if (new_fd < 0) { - g_warning ("cannot accept pkcs11 connection: %s", strerror (errno)); - return TRUE; - } - - /* And create a new thread */ - worker = gkr_async_worker_start (gkr_pkcs11_dispatch_session_thread, - completed_connection, GINT_TO_POINTER (new_fd)); - if (!worker) { - g_warning ("couldn't create new connection session thread"); - close (new_fd); - return TRUE; - } - - g_hash_table_insert (session_workers, worker, GINT_TO_POINTER (new_fd)); - - return TRUE; -} - -static void -pkcs11_dispatch_cleanup (gpointer unused) -{ - if (pkcs11_socket_channel) - g_io_channel_unref (pkcs11_socket_channel); - pkcs11_socket_channel = NULL; - - if (pkcs11_socket_fd != -1) - close (pkcs11_socket_fd); - pkcs11_socket_fd = -1; - - if(pkcs11_socket_path) { - unlink (pkcs11_socket_path); - g_free (pkcs11_socket_path); - pkcs11_socket_path = NULL; - } - - if (session_workers) { - - /* Swap out the hash table, so that completed_connection doesn't remove from it */ - GHashTable *workers = session_workers; - session_workers = NULL; - - g_hash_table_foreach (workers, (GHFunc)stop_connection, NULL); - g_hash_table_destroy (workers); - } -} - -gboolean -gkr_pkcs11_dispatch_setup (void) -{ - struct sockaddr_un addr; - const gchar *tmp_dir; - int sock; - -#ifdef _DEBUG - GKR_PKCS11_CHECK_CALLS (); -#endif - - /* cannot be called more than once */ - g_assert (!pkcs11_socket_path); - g_assert (pkcs11_socket_fd == -1); - g_assert (!pkcs11_socket_channel); - - gkr_cleanup_register (pkcs11_dispatch_cleanup, NULL); - - tmp_dir = gkr_daemon_util_get_master_directory (); - g_return_val_if_fail (tmp_dir, FALSE); - - pkcs11_socket_path = g_strjoin (NULL, tmp_dir, G_DIR_SEPARATOR_S, "socket", - GKR_PKCS11_SOCKET_EXT, NULL); - -#ifdef WITH_TESTS - if (g_getenv ("GNOME_KEYRING_TEST_PATH")) - unlink (pkcs11_socket_path); -#endif - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - g_warning ("couldn't create pkcs11 socket: %s", strerror (errno)); - return FALSE; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - strncpy (addr.sun_path, pkcs11_socket_path, sizeof (addr.sun_path)); - if (bind (sock, (struct sockaddr*)&addr, sizeof (addr)) < 0) { - g_warning ("couldn't bind to pkcs11 socket: %s: %s", - pkcs11_socket_path, strerror (errno)); - return FALSE; - } - - if (listen (sock, 128) < 0) { - g_warning ("couldn't listen on pkcs11 socket: %s: %s", - pkcs11_socket_path, strerror (errno)); - return FALSE; - } - - pkcs11_socket_channel = g_io_channel_unix_new (sock); - g_io_add_watch (pkcs11_socket_channel, G_IO_IN | G_IO_HUP, - handle_new_connection, NULL); - - /* Prep for sessions (ie: connections) */ - session_workers = g_hash_table_new (g_direct_hash, g_direct_equal); - - return TRUE; -} diff --git a/daemon/pkcs11/gkr-pkcs11-dispatch.h b/daemon/pkcs11/gkr-pkcs11-dispatch.h deleted file mode 100644 index 9078c249..00000000 --- a/daemon/pkcs11/gkr-pkcs11-dispatch.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gkr-pkcs11-dispatch.h - entry points for daemon PKCS#11 functionality - - Copyright (C) 2007, Nate Nielsen - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Nate Nielsen <nielsen@memberwebs.com> -*/ - -#ifndef __GKR_PKCS11_DISPATCH_H__ -#define __GKR_PKCS11_DISPATCH_H__ - -/* ----------------------------------------------------------------------------- - * GENERAL FUNCTIONS - */ - -gboolean gkr_pkcs11_dispatch_setup (void); - -/* ----------------------------------------------------------------------------- - * Used by gkr-pkcs11-dispatch.c and gkr-pkcs11-dispatch-session.c - */ - -gpointer gkr_pkcs11_dispatch_session_thread (gpointer user_data); - -#endif /* __GKR_PKCS11_DISPATCH_H__ */ diff --git a/daemon/pkcs11/gkr-pkcs11-dsa.c b/daemon/pkcs11/gkr-pkcs11-dsa.c deleted file mode 100644 index a53ebab1..00000000 --- a/daemon/pkcs11/gkr-pkcs11-dsa.c +++ /dev/null @@ -1,190 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gkr-pkcs11-dsa.c - DSA mechanism code for PKCS#11 - - Copyright (C) 2007, Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter <stef@memberwebs.com> -*/ - -#include "config.h" - -#include "gkr-pkcs11-dsa.h" - -#include "common/gkr-crypto.h" - -#include "pk/gkr-pk-pubkey.h" -#include "pk/gkr-pk-privkey.h" -#include "pk/gkr-pk-util.h" - -static CK_RV -object_to_public_key (GkrPkObject *object, gcry_sexp_t *s_key) -{ - GkrPkPubkey *key; - - /* Validate and extract the key */ - if (!GKR_IS_PK_PUBKEY (object)) - return CKR_KEY_HANDLE_INVALID; - - key = GKR_PK_PUBKEY (object); - if (gkr_pk_pubkey_get_algorithm (key) != GCRY_PK_DSA) - return CKR_KEY_TYPE_INCONSISTENT; - - *s_key = gkr_pk_pubkey_get_key (key); - if (!*s_key) { - /* TODO: This happens when the user doesn't unlock key, proper code */ - g_message ("couldn't get public key"); - return CKR_FUNCTION_FAILED; - } - - return CKR_OK; -} - -static CK_RV -object_to_private_key (GkrPkObject *object, gcry_sexp_t *s_key) -{ - GkrPkPrivkey *key; - - /* Validate and extract the key */ - if (!GKR_IS_PK_PRIVKEY (object)) - return CKR_KEY_HANDLE_INVALID; - - key = GKR_PK_PRIVKEY (object); - if (gkr_pk_privkey_get_algorithm (key) != GCRY_PK_DSA) - return CKR_KEY_TYPE_INCONSISTENT; - - *s_key = gkr_pk_privkey_get_key (key); - if (!*s_key) { - /* TODO: This happens when the user doesn't unlock key, proper code */ - g_message ("couldn't get private key"); - return CKR_FUNCTION_FAILED; - } - - return CKR_OK; -} - -CK_RV -gkr_pkcs11_dsa_sign (GkrPkObject *object, const guchar *plain, gsize n_plain, - guchar **signature, gsize *n_signature) -{ - gcry_sexp_t s_key, ssig, splain; - gcry_error_t gcry; - gcry_mpi_t mpi; - gboolean res; - CK_RV ret; - - g_return_val_if_fail (object, CKR_GENERAL_ERROR); - - ret = object_to_private_key (object, &s_key); - if (ret != CKR_OK) - return ret; - - /* If no output, then don't process */ - if (!signature) - return CKR_OK; - - if (!plain) - return CKR_ARGUMENTS_BAD; - - if (n_plain != 20) - return CKR_DATA_LEN_RANGE; - - /* Prepare the input s-expression */ - gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, plain, n_plain, NULL); - g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR); - gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi); - gcry_mpi_release (mpi); - g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR); - - /* Do the magic */ - gcry = gcry_pk_sign (&ssig, splain, s_key); - gcry_sexp_release (splain); - - /* TODO: Certain codes should be returned (data too big etc... ) */ - if (gcry) { - g_message ("signing of the data failed: %s", gcry_strerror (gcry)); - return CKR_FUNCTION_FAILED; - } - - *signature = g_new0 (guchar, 40); - *n_signature = 40; - - res = gkr_crypto_sexp_extract_mpi_aligned (ssig, *signature, 20, "dsa", "r", NULL) && - gkr_crypto_sexp_extract_mpi_aligned (ssig, *signature + 20, 20, "dsa", "s", NULL); - g_return_val_if_fail (res, CKR_GENERAL_ERROR); - - gcry_sexp_release (ssig); - return CKR_OK; -} - -CK_RV -gkr_pkcs11_dsa_verify (GkrPkObject *object, const guchar *plain, gsize n_plain, - const guchar *signature, gsize n_signature) -{ - gcry_sexp_t s_key, ssig, splain; - gcry_error_t gcry; - gcry_mpi_t mpi, mpi2; - CK_RV ret; - - g_return_val_if_fail (object, CKR_GENERAL_ERROR); - - ret = object_to_public_key (object, &s_key); - if (ret != CKR_OK) - return ret; - - /* If no data, then don't process */ - if (!plain) - return CKR_OK; - - if (!signature) - return CKR_ARGUMENTS_BAD; - if (n_plain != 20) - return CKR_DATA_LEN_RANGE; - if (n_signature != 40) - return CKR_DATA_LEN_RANGE; - - /* Prepare the input s-expressions */ - gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, plain, n_plain, NULL); - g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR); - gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi); - gcry_mpi_release (mpi); - g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR); - - gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, signature, 20, NULL); - g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR); - gcry = gcry_mpi_scan (&mpi2, GCRYMPI_FMT_USG, signature + 20, 20, NULL); - g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR); - gcry = gcry_sexp_build (&ssig, NULL, "(sig-val (dsa (r %m) (s %m)))", mpi, mpi2); - gcry_mpi_release (mpi); - gcry_mpi_release (mpi2); - g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR); - - /* Do the magic */ - gcry = gcry_pk_verify (ssig, splain, s_key); - gcry_sexp_release (splain); - gcry_sexp_release (ssig); - - /* TODO: See if any other codes should be mapped */ - if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) { - return CKR_SIGNATURE_INVALID; - } else if (gcry) { - g_message ("signing of the data failed: %s", gcry_strerror (gcry)); - return CKR_FUNCTION_FAILED; - } - - return CKR_OK; -} diff --git a/daemon/pkcs11/gkr-pkcs11-dsa.h b/daemon/pkcs11/gkr-pkcs11-dsa.h deleted file mode 100644 index 899b6c86..00000000 --- a/daemon/pkcs11/gkr-pkcs11-dsa.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gkr-pkcs11-dsa.h - DSA mechanism code for PKCS#11 - - Copyright (C) 2007, Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter <stef@memberwebs.com> -*/ - -#ifndef GKRPKCS11DSA_H_ -#define GKRPKCS11DSA_H_ - -#include "pk/gkr-pk-object.h" - -#include "pkcs11/pkcs11.h" - -CK_RV gkr_pkcs11_dsa_sign (GkrPkObject *key, - const guchar *plain, gsize n_plain, - guchar **signature, gsize *n_signature); - -CK_RV gkr_pkcs11_dsa_verify (GkrPkObject *key, - const guchar *plain, gsize n_plain, - const guchar *signature, gsize n_signature); - -CK_RV gkr_pkcs11_dsa_create_key (GkrPkManager *manager, - const GArray* attrs, GkrPkObject **key); - -#endif /*GKRPKCS11DSA_H_*/ diff --git a/daemon/pkcs11/gkr-pkcs11-rsa.c b/daemon/pkcs11/gkr-pkcs11-rsa.c deleted file mode 100644 index 8b787afe..00000000 --- a/daemon/pkcs11/gkr-pkcs11-rsa.c +++ /dev/null @@ -1,344 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gkr-pkcs11-rsa.c - RSA mechanism code for PKCS#11 - - Copyright (C) 2007, Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter <stef@memberwebs.com> -*/ - -#include "config.h" - -#include "gkr-pkcs11-rsa.h" - -#include "common/gkr-crypto.h" - -#include "pk/gkr-pk-pubkey.h" -#include "pk/gkr-pk-privkey.h" - -static CK_RV -object_to_public_key (GkrPkObject *object, gcry_sexp_t *s_key) -{ - GkrPkPubkey *key; - - /* Validate and extract the key */ - if (!GKR_IS_PK_PUBKEY (object)) - return CKR_KEY_HANDLE_INVALID; - - key = GKR_PK_PUBKEY (object); - if (gkr_pk_pubkey_get_algorithm (key) != GCRY_PK_RSA) - return CKR_KEY_TYPE_INCONSISTENT; - - *s_key = gkr_pk_pubkey_get_key (key); - if (!*s_key) { - /* TODO: This happens when the user doesn't unlock key, proper code */ - g_message ("couldn't get public key"); - return CKR_FUNCTION_FAILED; - } - - return CKR_OK; -} - -static CK_RV -object_to_private_key (GkrPkObject *object, gcry_sexp_t *s_key) -{ - GkrPkPrivkey *key; - - /* Validate and extract the key */ - if (!GKR_IS_PK_PRIVKEY (object)) - return CKR_KEY_HANDLE_INVALID; - - key = GKR_PK_PRIVKEY (object); - if (gkr_pk_privkey_get_algorithm (key) != GCRY_PK_RSA) - return CKR_KEY_TYPE_INCONSISTENT; - - *s_key = gkr_pk_privkey_get_key (key); - if (!*s_key) { - /* TODO: This happens when the user doesn't unlock key, proper code */ - g_message ("couldn't get private key"); - return CKR_FUNCTION_FAILED; - } - - return CKR_OK; -} - -static CK_RV -data_to_sexp (const gchar *format, guint nbits, GkrCryptoPadding padfunc, - const guchar *data, gsize n_data, gcry_sexp_t *sexp) -{ - guchar *padded = NULL; - gcry_error_t gcry; - gcry_mpi_t mpi; - gsize n_padded; - - g_assert (format); - g_assert (sexp); - - g_return_val_if_fail (data, CKR_ARGUMENTS_BAD); - - if (padfunc) { - padded = (padfunc) (nbits, data, n_data, &n_padded); - if (!padded) - return CKR_DATA_LEN_RANGE; - } - - /* Prepare the input s expression */ - gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, - padded ? padded : data, - padded ? n_padded : n_data, NULL); - g_free (padded); - - g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR); - - gcry = gcry_sexp_build (sexp, NULL, format, mpi); - gcry_mpi_release (mpi); - - g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR); - - g_assert (*sexp); - return CKR_OK; -} - -static CK_RV -sexp_to_data (const gchar* format1, const gchar *format2, const gchar *format3, - guint nbits, GkrCryptoPadding padfunc, gcry_sexp_t sexp, - guchar **data, gsize *n_data) -{ - gboolean res; - - g_assert (format1); - g_assert (sexp); - g_assert (data); - g_assert (n_data); - - /* Now extract and send it back out */ - if (padfunc) { - *data = gkr_crypto_sexp_extract_mpi_padded (sexp, nbits, n_data, padfunc, - format1, format2, format3, NULL); - g_return_val_if_fail (*data, CKR_GENERAL_ERROR); - } else { - *n_data = nbits / 8; - *data = g_malloc0 (*n_data); - res = gkr_crypto_sexp_extract_mpi_aligned (sexp, *data, *n_data, - format1, format2, format3, NULL); - g_return_val_if_fail (res, CKR_GENERAL_ERROR); - } - - return CKR_OK; -} - -CK_RV -gkr_pkcs11_rsa_encrypt (GkrPkObject *key, GkrCryptoPadding padfunc, - const guchar *plain, gsize n_plain, - guchar **encrypted, gsize *n_encrypted) -{ - gcry_sexp_t s_key, splain, senc; - gcry_error_t gcry; - guint nbits; - CK_RV ret; - - g_return_val_if_fail (key, CKR_GENERAL_ERROR); - - ret = object_to_public_key (key, &s_key); - if (ret != CKR_OK) - return ret; - - /* If no output, then don't process */ - if (!plain) - return CKR_OK; - - /* The key size */ - nbits = gcry_pk_get_nbits (s_key); - g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR); - - /* Prepare the input s expression */ - ret = data_to_sexp ("(data (flags raw) (value %m))", - nbits, padfunc, plain, n_plain, &splain); - if (ret != CKR_OK) - return ret; - - /* Do the magic */ - gcry = gcry_pk_encrypt (&senc, splain, s_key); - gcry_sexp_release (splain); - - /* TODO: Certain codes should be returned (data too big etc... ) */ - if (gcry) { - g_message ("encrypting of the data failed: %s", gcry_strerror (gcry)); - return CKR_FUNCTION_FAILED; - } - - /* Now extract and send it back out */ - ret = sexp_to_data ("enc-val", "rsa", "a", nbits, NULL, senc, encrypted, n_encrypted); - gcry_sexp_release (senc); - - return ret; -} - -CK_RV -gkr_pkcs11_rsa_decrypt (GkrPkObject *object, GkrCryptoPadding padfunc, - const guchar *encrypted, gsize n_encrypted, - guchar **plain, gsize *n_plain) -{ - gcry_sexp_t s_key, splain, sdata; - gcry_error_t gcry; - guint nbits; - CK_RV ret; - - g_return_val_if_fail (object, CKR_GENERAL_ERROR); - - ret = object_to_private_key (object, &s_key); - if (ret != CKR_OK) - return ret; - - /* If no output, then don't process */ - if (!plain) - return CKR_OK; - - /* The key size */ - nbits = gcry_pk_get_nbits (s_key); - g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR); - - if (n_encrypted != nbits / 8) - return CKR_DATA_LEN_RANGE; - - /* Prepare the input s expression */ - ret = data_to_sexp ("(enc-val (flags) (rsa (a %m)))", - nbits, NULL, encrypted, n_encrypted, &sdata); - if (ret != CKR_OK) - return ret; -gkr_crypto_sexp_dump (sdata); - - /* Do the magic */ - gcry = gcry_pk_decrypt (&splain, sdata, s_key); - gcry_sexp_release (sdata); - - /* TODO: Certain codes should be returned (data too big etc... ) */ - if (gcry) { - g_message ("decrypting of the data failed: %s", gcry_strerror (gcry)); - return CKR_FUNCTION_FAILED; - } -gkr_crypto_sexp_dump (splain); - - /* Now extract and send it back out */ - ret = sexp_to_data ("value", NULL, NULL, nbits, padfunc, splain, plain, n_plain); - gcry_sexp_release (splain); - - return ret; -} - -CK_RV -gkr_pkcs11_rsa_sign (GkrPkObject *object, GkrCryptoPadding padfunc, - const guchar *input, gsize n_input, - guchar **signature, gsize *n_signature) -{ - gcry_sexp_t s_key, ssig, sdata; - gcry_error_t gcry; - guint nbits; - CK_RV ret; - - g_return_val_if_fail (object, CKR_GENERAL_ERROR); - - ret = object_to_private_key (object, &s_key); - if (ret != CKR_OK) - return ret; - - /* If no output, then don't process */ - if (!signature) - return CKR_OK; - - /* The key size */ - nbits = gcry_pk_get_nbits (s_key); - g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR); - - /* Prepare the input s expression */ - ret = data_to_sexp ("(data (flags raw) (value %m))", - nbits, padfunc, input, n_input, &sdata); - if (ret != CKR_OK) - return ret; - - /* Do the magic */ - gcry = gcry_pk_sign (&ssig, sdata, s_key); - gcry_sexp_release (sdata); - - /* TODO: Certain codes should be returned (data too big etc... ) */ - if (gcry) { - g_message ("signing of the data failed: %s", gcry_strerror (gcry)); - return CKR_FUNCTION_FAILED; - } - - /* Now extract and send it back out */ - ret = sexp_to_data ("rsa", "s", NULL, nbits, NULL, ssig, signature, n_signature); - gcry_sexp_release (ssig); - - return ret; -} - -CK_RV -gkr_pkcs11_rsa_verify (GkrPkObject *object, GkrCryptoPadding padfunc, - const guchar *data, gsize n_data, - const guchar *signature, gsize n_signature) -{ - gcry_sexp_t s_key, ssig, sdata; - gcry_error_t gcry; - guint nbits; - CK_RV ret; - - g_return_val_if_fail (object, CKR_GENERAL_ERROR); - - ret = object_to_public_key (object, &s_key); - if (ret != CKR_OK) - return ret; - - /* If no data, then don't process */ - if (!data) - return CKR_OK; - - g_return_val_if_fail (data, CKR_GENERAL_ERROR); - g_return_val_if_fail (signature, CKR_GENERAL_ERROR); - - /* The key size */ - nbits = gcry_pk_get_nbits (s_key); - g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR); - - /* Prepare the input s expressions */ - ret = data_to_sexp ("(data (flags raw) (value %m))", - nbits, padfunc, data, n_data, &sdata); - if (ret != CKR_OK) - return ret; - - ret = data_to_sexp ("(sig-val (rsa (s %m)))", - nbits, NULL, signature, n_signature, &ssig); - if (ret != CKR_OK) { - gcry_sexp_release (sdata); - return ret; - } - - /* Do the magic */ - gcry = gcry_pk_verify (ssig, sdata, s_key); - gcry_sexp_release (sdata); - gcry_sexp_release (ssig); - - /* TODO: See if any other codes should be mapped */ - if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) { - return CKR_SIGNATURE_INVALID; - } else if (gcry) { - g_message ("signing of the data failed: %s", gcry_strerror (gcry)); - return CKR_FUNCTION_FAILED; - } - - return CKR_OK; -} diff --git a/daemon/pkcs11/gkr-pkcs11-rsa.h b/daemon/pkcs11/gkr-pkcs11-rsa.h deleted file mode 100644 index 67e65e7d..00000000 --- a/daemon/pkcs11/gkr-pkcs11-rsa.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* gkr-pkcs11-rsa.h - RSA mechanism code for PKCS#11 - - Copyright (C) 2007, Stefan Walter - - The Gnome Keyring Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The Gnome Keyring Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the Gnome Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. - - Author: Stef Walter <stef@memberwebs.com> -*/ - -#ifndef GKRPKCS11RSA_H_ -#define GKRPKCS11RSA_H_ - -#include "common/gkr-crypto.h" - -#include "pk/gkr-pk-object.h" - -#include "pkcs11/pkcs11.h" - -CK_RV gkr_pkcs11_rsa_encrypt (GkrPkObject *key, GkrCryptoPadding padfunc, - const guchar *plain, gsize n_plain, - guchar **encrypted, gsize *n_encrypted); - -CK_RV gkr_pkcs11_rsa_decrypt (GkrPkObject *key, GkrCryptoPadding padfunc, - const guchar *encrypted, gsize n_encrypted, - guchar **plain, gsize *n_plain); - -CK_RV gkr_pkcs11_rsa_sign (GkrPkObject *key, GkrCryptoPadding padfunc, - const guchar *data, gsize n_data, - guchar **signature, gsize *n_signature); - -CK_RV gkr_pkcs11_rsa_verify (GkrPkObject *key, GkrCryptoPadding padfunc, - const guchar *data, gsize n_data, - const guchar *signature, gsize n_signature); - -#endif /*GKRPKCS11RSA_H_*/ diff --git a/daemon/ui/Makefile.am b/daemon/ui/Makefile.am index ebe99c84..c6685069 100644 --- a/daemon/ui/Makefile.am +++ b/daemon/ui/Makefile.am @@ -21,7 +21,7 @@ gnome_keyring_ask_SOURCES = \ gkr-ask-request.h gnome_keyring_ask_LDADD = \ - $(top_builddir)/common/libgkr-module-common.la \ + $(top_builddir)/common/libgkr-common-secure.la \ $(GTK_LIBS) noinst_LTLIBRARIES=libgkr-ui.la |