summaryrefslogtreecommitdiff
path: root/ckcapi-session.c
diff options
context:
space:
mode:
Diffstat (limited to 'ckcapi-session.c')
-rw-r--r--ckcapi-session.c199
1 files changed, 199 insertions, 0 deletions
diff --git a/ckcapi-session.c b/ckcapi-session.c
index 46de60a..0745cb7 100644
--- a/ckcapi-session.c
+++ b/ckcapi-session.c
@@ -23,10 +23,20 @@
#include "ckcapi-builtin.h"
#include "ckcapi-cert.h"
#include "ckcapi-object.h"
+#include "ckcapi-rsa.h"
#include "ckcapi-session.h"
#include "ckcapi-token.h"
#include "ckcapi-trust.h"
+/* For operation_type in CkCapiSession */
+enum
+{
+ OPERATION_NONE,
+ OPERATION_FIND,
+ OPERATION_SIGN,
+ OPERATION_DECRYPT
+};
+
static CkCapiArray* all_sessions = NULL;
static void
@@ -721,3 +731,192 @@ ckcapi_session_find_final(CkCapiSession* sess)
}
+/* ----------------------------------------------------------------------------
+ * CRYPTO OPERATIONS
+ */
+
+typedef struct _CryptoContext
+{
+ CK_MECHANISM_TYPE mech_type;
+ CkCapiDestroyFunc mech_cleanup;
+ void* mech_data;
+}
+CryptoContext;
+
+void
+cleanup_crypto_operation(CkCapiSession* sess)
+{
+ CryptoContext* ctx;
+
+ if(sess->operation_data)
+ {
+ ctx = (CryptoContext*)sess->operation_data;
+ if(ctx->mech_cleanup)
+ (ctx->mech_cleanup)(ctx->mech_data);
+ free(ctx);
+ }
+
+ sess->operation_type = OPERATION_NONE;
+ sess->operation_data = NULL;
+ sess->operation_cancel = NULL;
+}
+
+CK_RV
+ckcapi_session_sign_init(CkCapiSession* sess, CK_MECHANISM_PTR mech,
+ CkCapiObjectData *objdata)
+{
+ CryptoContext* ctx;
+ CK_RV ret;
+
+ ASSERT(sess);
+ ASSERT(mech);
+ ASSERT(objdata);
+
+ if(sess->operation_type != OPERATION_NONE)
+ return CKR_OPERATION_ACTIVE;
+
+ ctx = calloc(1, sizeof(CryptoContext));
+ if(!ctx)
+ return CKR_HOST_MEMORY;
+
+ ctx->mech_type = mech->mechanism;
+
+ switch(mech->mechanism)
+ {
+ case CKM_RSA_PKCS:
+ ret = ckcapi_rsa_pkcs_sign_init(objdata, &ctx->mech_data);
+ ctx->mech_cleanup = ckcapi_rsa_pkcs_sign_cleanup;
+ default:
+ ret = CKR_MECHANISM_INVALID;
+ };
+
+ if(ret != CKR_OK)
+ {
+ free(ctx);
+ ASSERT(!sess->operation_data);
+ return ret;
+ }
+
+ sess->operation_type = OPERATION_SIGN;
+ sess->operation_data = ctx;
+ sess->operation_cancel = cleanup_crypto_operation;
+ return CKR_OK;
+}
+
+CK_RV
+ckcapi_session_sign(CkCapiSession* sess, CK_BYTE_PTR data, CK_ULONG n_data,
+ CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
+{
+ CryptoContext *ctx;
+ BOOL incomplete;
+ CK_RV ret;
+
+ ASSERT(sess);
+ ASSERT(data);
+ ASSERT(n_data);
+
+ if(sess->operation_type != OPERATION_SIGN)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ ctx = (CryptoContext*)sess->operation_data;
+ switch(ctx->mech_type)
+ {
+ case CKM_RSA_PKCS:
+ ret = ckcapi_rsa_pkcs_sign_perform(data, n_data, signature, n_signature,
+ &ctx->mech_data);
+ break;
+
+ default:
+ ASSERT(FALSE);
+ ret = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ /* Buffer calculation, we don't end operation */
+ incomplete = (ret == CKR_BUFFER_TOO_SMALL || (ret == CKR_OK && !signature));
+
+ if(!incomplete)
+ cleanup_crypto_operation(sess);
+
+ return ret;
+}
+
+CK_RV
+ckcapi_session_decrypt_init(CkCapiSession* sess, CK_MECHANISM_PTR mech,
+ CkCapiObjectData *objdata)
+{
+ CryptoContext* ctx;
+ CK_RV ret;
+
+ ASSERT(sess);
+ ASSERT(mech);
+ ASSERT(objdata);
+
+ if(sess->operation_type != OPERATION_NONE)
+ return CKR_OPERATION_ACTIVE;
+
+ ctx = calloc(1, sizeof(CryptoContext));
+ if(!ctx)
+ return CKR_HOST_MEMORY;
+
+ ctx->mech_type = mech->mechanism;
+
+ switch(mech->mechanism)
+ {
+ case CKM_RSA_PKCS:
+ ret = ckcapi_rsa_pkcs_decrypt_init(objdata, &ctx->mech_data);
+ ctx->mech_cleanup = ckcapi_rsa_pkcs_decrypt_cleanup;
+ default:
+ ret = CKR_MECHANISM_INVALID;
+ };
+
+ if(ret != CKR_OK)
+ {
+ free(ctx);
+ ASSERT(!sess->operation_data);
+ return ret;
+ }
+
+ sess->operation_type = OPERATION_DECRYPT;
+ sess->operation_data = ctx;
+ sess->operation_cancel = cleanup_crypto_operation;
+ return CKR_OK;
+}
+
+CK_RV
+ckcapi_session_decrypt(CkCapiSession* sess, CK_BYTE_PTR encdata, CK_ULONG n_encdata,
+ CK_BYTE_PTR result, CK_ULONG_PTR n_result)
+{
+ CryptoContext *ctx;
+ BOOL incomplete;
+ CK_RV ret;
+
+ ASSERT(sess);
+ ASSERT(encdata);
+ ASSERT(n_encdata);
+
+ if(sess->operation_type != OPERATION_DECRYPT)
+ return CKR_OPERATION_NOT_INITIALIZED;
+
+ ctx = (CryptoContext*)sess->operation_data;
+ switch(ctx->mech_type)
+ {
+ case CKM_RSA_PKCS:
+ ret = ckcapi_rsa_pkcs_decrypt_perform(encdata, n_encdata, result, n_result,
+ &ctx->mech_data);
+ break;
+
+ default:
+ ASSERT(FALSE);
+ ret = CKR_GENERAL_ERROR;
+ break;
+ }
+
+ /* Buffer calculation, we don't end operation */
+ incomplete = (ret == CKR_BUFFER_TOO_SMALL || (ret == CKR_OK && !result));
+
+ if(!incomplete)
+ cleanup_crypto_operation(sess);
+
+ return ret;
+}