summaryrefslogtreecommitdiffstats
path: root/ipapython/ipap11helper
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2016-01-06 13:10:11 +0100
committerMartin Basti <mbasti@redhat.com>2016-01-21 10:21:32 +0100
commit500ee7e2b1fdaa9669cf136a380907cfe4f0f225 (patch)
tree79b5f3ce0c8d0d6caa68512b468d96c76b2daebf /ipapython/ipap11helper
parentf5f5c8c603e95d246d2cde92f56959fedba4666d (diff)
ipapython: port p11helper C code to Python
This replaces the binary _ipap11helper module with cffi-based Python code. https://fedorahosted.org/freeipa/ticket/5596 Reviewed-By: Martin Basti <mbasti@redhat.com>
Diffstat (limited to 'ipapython/ipap11helper')
-rw-r--r--ipapython/ipap11helper/Makefile19
-rw-r--r--ipapython/ipap11helper/library.c87
-rw-r--r--ipapython/ipap11helper/library.h48
-rw-r--r--ipapython/ipap11helper/p11helper.c2268
-rw-r--r--ipapython/ipap11helper/setup.py43
5 files changed, 0 insertions, 2465 deletions
diff --git a/ipapython/ipap11helper/Makefile b/ipapython/ipap11helper/Makefile
deleted file mode 100644
index f66edb82e..000000000
--- a/ipapython/ipap11helper/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-PYTHON ?= /usr/bin/python2
-PYTHONLIBDIR ?= $(shell $(PYTHON) -c "from distutils.sysconfig import *; print(get_python_lib())")
-
-all:
- $(PYTHON) setup.py build
-
-install:
- if [ "$(DESTDIR)" = "" ]; then \
- $(PYTHON) setup.py install; \
- else \
- $(PYTHON) setup.py install --root $(DESTDIR); \
- fi
-
-clean:
- rm -rf build
-
-distclean: clean
-
-maintainer-clean: distclean
diff --git a/ipapython/ipap11helper/library.c b/ipapython/ipap11helper/library.c
deleted file mode 100644
index acae47e5c..000000000
--- a/ipapython/ipap11helper/library.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2014 FreeIPA Contributors see COPYING for license
- *
- * This code is based on PKCS#11 code from SoftHSM project:
- * https://github.com/opendnssec/SoftHSMv2/
- * Original license follows:
- */
-/*
- * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*****************************************************************************
- library.c
-
- Support function for handling PKCS#11 libraries
- *****************************************************************************/
-
-#include "library.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <dlfcn.h>
-
-// Load the PKCS#11 library
-CK_C_GetFunctionList loadLibrary(const char* module, void** moduleHandle)
-{
- CK_C_GetFunctionList pGetFunctionList = NULL;
-
- void* pDynLib = NULL;
-
- // Load PKCS #11 library
- if (module)
- {
- pDynLib = dlopen(module, RTLD_NOW | RTLD_LOCAL);
- } else {
- return NULL;
- }
-
- if (pDynLib == NULL)
- {
- // Failed to load the PKCS #11 library
- return NULL;
- }
-
- // Retrieve the entry point for C_GetFunctionList
- pGetFunctionList = (CK_C_GetFunctionList) dlsym(pDynLib, "C_GetFunctionList");
- if (pGetFunctionList == NULL)
- {
- dlclose(pDynLib);
- return NULL;
- }
-
- // Store the handle so we can dlclose it later
- *moduleHandle = pDynLib;
-
- return pGetFunctionList;
-}
-
-void unloadLibrary(void* moduleHandle)
-{
- if (moduleHandle)
- {
- dlclose(moduleHandle);
- }
-}
diff --git a/ipapython/ipap11helper/library.h b/ipapython/ipap11helper/library.h
deleted file mode 100644
index afcbd9fd2..000000000
--- a/ipapython/ipap11helper/library.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2014 FreeIPA Contributors see COPYING for license
- *
- * This code is based on PKCS#11 code from SoftHSM project:
- * https://github.com/opendnssec/SoftHSMv2/
- * Original license follows:
- */
-/*
- * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*****************************************************************************
- library.h
-
- Support function for handling PKCS#11 libraries
- *****************************************************************************/
-
-#ifndef _SOFTHSM_V2_BIN_LIBRARY_H
-#define _SOFTHSM_V2_BIN_LIBRARY_H
-
-#include <p11-kit/pkcs11.h>
-
-CK_C_GetFunctionList loadLibrary(const char* module, void** moduleHandle);
-void unloadLibrary(void* moduleHandle);
-
-#endif // !_SOFTHSM_V2_BIN_LIBRARY_H
diff --git a/ipapython/ipap11helper/p11helper.c b/ipapython/ipap11helper/p11helper.c
deleted file mode 100644
index 65bfc07ec..000000000
--- a/ipapython/ipap11helper/p11helper.c
+++ /dev/null
@@ -1,2268 +0,0 @@
-/*
- * Copyright (C) 2014 FreeIPA Contributors see COPYING for license
- *
- * This file includes an "OpenSSL license exception", see the
- * COPYING.openssl file for details.
- *
- * This code is based on PKCS#11 code snippets from NLnetLabs:
- * http://www.nlnetlabs.nl/publications/hsm/examples/pkcs11/
- * Original license follows:
- */
-/*
- * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <Python.h>
-#include "structmember.h"
-
-#include <openssl/asn1.h>
-#include <openssl/x509.h>
-#include <openssl/evp.h>
-#include <openssl/rsa.h>
-#include <openssl/bn.h>
-#include <openssl/bio.h>
-
-#include <p11-kit/pkcs11.h>
-#include <p11-kit/uri.h>
-
-#include "library.h"
-
-#if PY_MAJOR_VERSION >= 3
-// Python 3 uses "PyLong" as the int implementation
-#define PyInt_Check PyLong_Check
-#define PyInt_AsUnsignedLongMask PyLong_AsUnsignedLongMask
-#endif
-
-// compat TODO
-#define CKM_AES_KEY_WRAP (0x2109)
-#define CKM_AES_KEY_WRAP_PAD (0x210a)
-
-// TODO
-#define CKA_COPYABLE (0x0017)
-
-#define CKG_MGF1_SHA1 (0x00000001)
-
-#define CKZ_DATA_SPECIFIED (0x00000001)
-
-struct ck_rsa_pkcs_oaep_params {
- CK_MECHANISM_TYPE hash_alg;
- unsigned long mgf;
- unsigned long source;
- void *source_data;
- unsigned long source_data_len;
-};
-
-typedef struct ck_rsa_pkcs_oaep_params CK_RSA_PKCS_OAEP_PARAMS;
-typedef struct ck_rsa_pkcs_oaep_params *CK_RSA_PKCS_OAEP_PARAMS_PTR;
-
-
-CK_BBOOL true = CK_TRUE;
-CK_BBOOL false = CK_FALSE;
-
-#define MAX_TEMPLATE_LEN 32
-
-/**
- * P11_Helper type
- */
-typedef struct {
- PyObject_HEAD CK_SLOT_ID slot;
- CK_FUNCTION_LIST_PTR p11;
- CK_SESSION_HANDLE session;
- void *module_handle;
-} P11_Helper;
-
-typedef enum {
- sec_en_cka_copyable = 0,
- sec_en_cka_decrypt = 1,
- sec_en_cka_derive = 2,
- sec_en_cka_encrypt = 3,
- sec_en_cka_extractable = 4,
- sec_en_cka_modifiable = 5,
- sec_en_cka_private = 6,
- sec_en_cka_sensitive = 7,
- sec_en_cka_sign = 8,
- sec_en_cka_unwrap = 9,
- sec_en_cka_verify = 10,
- sec_en_cka_wrap = 11,
- sec_en_cka_wrap_with_trusted = 12
-} secrect_key_enum;
-
-typedef enum {
- pub_en_cka_copyable = 0,
- pub_en_cka_derive = 1,
- pub_en_cka_encrypt = 2,
- pub_en_cka_modifiable = 3,
- pub_en_cka_private = 4,
- pub_en_cka_trusted = 5,
- pub_en_cka_verify = 6,
- pub_en_cka_verify_recover = 7,
- pub_en_cka_wrap = 8
-} public_key_enum;
-
-typedef enum {
- priv_en_cka_always_authenticate = 0,
- priv_en_cka_copyable = 1,
- priv_en_cka_decrypt = 2,
- priv_en_cka_derive = 3,
- priv_en_cka_extractable = 4,
- priv_en_cka_modifiable = 5,
- priv_en_cka_private = 6,
- priv_en_cka_sensitive = 7,
- priv_en_cka_sign = 8,
- priv_en_cka_sign_recover = 9,
- priv_en_cka_unwrap = 10,
- priv_en_cka_wrap_with_trusted = 11
-} private_key_enum;
-
-typedef struct {
- PyObject *py_obj;
- CK_BBOOL *bool;
-} PyObj2Bool_mapping_t;
-
-/**
- * Constants
- */
-static const CK_RSA_PKCS_OAEP_PARAMS CONST_RSA_PKCS_OAEP_PARAMS = {
- .hash_alg = CKM_SHA_1,
- .mgf = CKG_MGF1_SHA1,
- .source = CKZ_DATA_SPECIFIED,
- .source_data = NULL,
- .source_data_len = 0
-};
-
-/**
- * ipap11helper Exceptions
- */
-static PyObject *ipap11helperException; // parent class for all exceptions
-
-static PyObject *ipap11helperError; // general error
-static PyObject *ipap11helperNotFound; // key not found
-static PyObject *ipap11helperDuplicationError; // key already exists
-
-/***********************************************************************
- * Support functions
- */
-
-#define GOTO_FAIL \
- do { \
- error = 1; \
- goto final; \
- } while(0);
-
-CK_BBOOL *pyobj_to_bool(PyObject *pyobj) {
- if (PyObject_IsTrue(pyobj))
- return &true;
- return &false;
-
-}
-
-void convert_py2bool(PyObj2Bool_mapping_t *mapping, int length) {
- int i;
- for (i = 0; i < length; ++i) {
- PyObject *py_obj = mapping[i].py_obj;
- if (py_obj != NULL) {
- mapping[i].bool = pyobj_to_bool(py_obj);
- }
- }
-}
-
-PyObject *string_to_pybytes_or_none(const char *str, Py_ssize_t len) {
- if (str == NULL) {
- Py_RETURN_NONE;
- }
- return PyBytes_FromStringAndSize(str, len);
-}
-
-/**
- * Convert a unicode string to the utf8 encoded char array
- * :param unicode: input python unicode object
- * :param l length: of returned string
- * Returns NULL if an error occurs, else pointer to string
- */
-unsigned char *unicode_to_char_array(PyObject *unicode, Py_ssize_t *l) {
- unsigned char *result = NULL;
- PyObject *utf8_str = PyUnicode_AsUTF8String(unicode);
- if (utf8_str == NULL) {
- PyErr_SetString(ipap11helperError, "Unable to encode UTF-8");
- return NULL;
- }
- unsigned char *bytes = (unsigned char *) PyBytes_AS_STRING(utf8_str);
- if (bytes == NULL) {
- PyErr_SetString(ipap11helperError, "Unable to get bytes from string");
- *l = 0;
- } else {
- *l = PyBytes_Size(utf8_str);
-
- /* Copy string first, then DECREF
- * https://docs.python.org/2/c-api/string.html#c.PyString_AS_STRING
- */
- result = (unsigned char *) PyMem_Malloc((size_t) * l);
- if (result == NULL) {
- Py_DECREF(utf8_str);
- PyErr_NoMemory();
- return NULL;
- } else {
- memcpy(result, bytes, *l);
- }
-
- }
- Py_DECREF(utf8_str);
- return result;
-}
-
-/**
- * Convert utf-8 encoded char array to unicode object
- */
-PyObject *char_array_to_unicode(const char *array, unsigned long l) {
- return PyUnicode_DecodeUTF8(array, l, "strict");
-}
-
-/**
- * Tests result value of pkc11 operations
- * :return: 1 if everything is ok, 0 if an error occurs and set the error message
- */
-int check_return_value(CK_RV rv, const char *message) {
- char *errmsg = NULL;
- if (rv != CKR_OK) {
- if (asprintf
- (&errmsg, "Error at %s: 0x%x\n", message, (unsigned int) rv)
- == -1) {
- PyErr_SetString(ipap11helperError,
- "An error occured during error message generation. "
- "Please report this problem. Developers will use "
- "a crystal ball to find out the root cause.");
- return 0;
- }
- if (errmsg != NULL) {
- PyErr_SetString(ipap11helperError, errmsg);
- free(errmsg);
- }
- return 0;
- }
- return 1;
-}
-
-/**
- * Fill template structure with pointers to attributes passed as independent
- * variables.
- * Variables with NULL values will be omitted from template.
- *
- * @warning input variables should not be modified when template is in use
- */
-int _fill_template_from_parts(CK_ATTRIBUTE_PTR attr, CK_ULONG_PTR template_len,
- CK_BYTE_PTR id, CK_ULONG id_len,
- CK_BYTE_PTR label, CK_ULONG label_len,
- CK_OBJECT_CLASS *class, CK_BBOOL *cka_wrap,
- CK_BBOOL *cka_unwrap) {
- int cnt = 0;
- if (label != NULL) {
- attr->type = CKA_LABEL;
- attr->pValue = (void *) label;
- attr->ulValueLen = label_len;
- ++attr;
- ++cnt;
- assert(cnt < *template_len);
- }
- if (id != NULL) {
- attr->type = CKA_ID;
- attr->pValue = (void *) id;
- attr->ulValueLen = id_len;
- ++attr;
- ++cnt;
- assert(cnt < *template_len);
- }
- if (cka_wrap != NULL) {
- attr->type = CKA_WRAP;
- attr->pValue = (void *) cka_wrap;
- attr->ulValueLen = sizeof(CK_BBOOL);
- ++attr;
- ++cnt;
- assert(cnt < *template_len);
- }
- if (cka_unwrap != NULL) {
- attr->type = CKA_UNWRAP;
- attr->pValue = (void *) cka_unwrap;
- attr->ulValueLen = sizeof(CK_BBOOL);
- ++attr;
- ++cnt;
- assert(cnt < *template_len);
- }
-
- if (class != NULL) {
- attr->type = CKA_CLASS;
- attr->pValue = (void *) class;
- attr->ulValueLen = sizeof(CK_OBJECT_CLASS);
- ++attr;
- ++cnt;
- assert(cnt < *template_len);
- }
- *template_len = cnt;
- return 1;
-}
-
-/**
- * Parse string to P11-kit representation of PKCS#11 URI.
- *
- * @pre *urip is NULL
- * @post
- *
- * @retval 0 in case of error
- * @retval 1 when urip is filled with pointer to new URI structure
- */
-int _parse_uri(const char *uri_str, P11KitUri **urip) {
- P11KitUriResult result;
- P11KitUri *uri = NULL;
-
- assert(urip != NULL && *urip == NULL);
-
- uri = p11_kit_uri_new();
- if (!uri) {
- PyErr_SetString(ipap11helperError, "Cannot initialize URI parser");
- return 0;
- }
-
- result = p11_kit_uri_parse(uri_str, P11_KIT_URI_FOR_OBJECT, uri);
- if (result != P11_KIT_URI_OK) {
- PyErr_SetString(ipap11helperError, "Cannot parse URI");
- goto cleanup;
- }
-
- if (p11_kit_uri_any_unrecognized(uri)) {
- PyErr_SetString(ipap11helperError, "PKCS#11 URI contains "
- "unsupported attributes");
- goto cleanup;
- }
-
- *urip = uri;
- return 1;
-
-cleanup:
- p11_kit_uri_free(uri);
- return 0;
-}
-
-/*
- * Find keys matching specified template.
- * Function returns list of key handles via objects parameter.
- *
- * :param template: PKCS#11 template for attribute matching
- * :param objects: found objects, NULL if no objects fit criteria
- * :param objects_count: number of objects in objects array
- * :return: 1 if success, otherwise return 0 and set the exception
- */
-int _find_key(P11_Helper *self, CK_ATTRIBUTE_PTR template,
- CK_ULONG template_len, CK_OBJECT_HANDLE **objects,
- unsigned int *objects_count) {
- CK_OBJECT_HANDLE result_object;
- CK_ULONG objectCount;
- CK_OBJECT_HANDLE *result_objects = NULL;
- CK_OBJECT_HANDLE *tmp_objects_ptr = NULL;
- unsigned int count = 0;
- unsigned int allocated = 0;
- CK_RV rv;
-
- rv = self->p11->C_FindObjectsInit(self->session, template, template_len);
- if (!check_return_value(rv, "Find key init"))
- return 0;
-
- rv = self->p11->C_FindObjects(self->session, &result_object, 1,
- &objectCount);
- if (!check_return_value(rv, "Find key"))
- return 0;
-
- while (objectCount > 0) {
- if (allocated <= count) {
- allocated += 32;
- tmp_objects_ptr = (CK_OBJECT_HANDLE*) realloc(result_objects,
- allocated * sizeof(CK_OBJECT_HANDLE));
- if (tmp_objects_ptr == NULL) {
- *objects_count = 0;
- PyErr_SetString(ipap11helperError, "_find_key realloc failed");
- free(result_objects);
- return 0;
- } else {
- result_objects = tmp_objects_ptr;
- }
- }
- result_objects[count] = result_object;
- count++;
- rv = self->p11->C_FindObjects(self->session, &result_object, 1,
- &objectCount);
- if (!check_return_value(rv, "Check for duplicated key")) {
- free(result_objects);
- return 0;
- }
- }
-
- rv = self->p11->C_FindObjectsFinal(self->session);
- if (!check_return_value(rv, "Find objects final")) {
- free(result_objects);
- return 0;
- }
-
- *objects = result_objects;
- *objects_count = count;
- return 1;
-}
-
-/*
- * Test if object with specified label, id and class exists
- *
- * :param id: key ID, (if value is NULL, will not be used to find key)
- * :param id_len: key ID length
- * :param label key: label (if value is NULL, will not be used to find key)
- * :param label_len: key label length
- * :param class key: class
-
- * :return: 1 if object was found, 0 if object doesnt exists, -1 if error
- * and set the exception
- *
- */
-int _id_exists(P11_Helper *self, CK_BYTE_PTR id, CK_ULONG id_len,
- CK_OBJECT_CLASS class) {
-
- CK_RV rv;
- CK_ULONG object_count = 0;
- CK_OBJECT_HANDLE result_object = 0;
- CK_OBJECT_CLASS class_sec = CKO_SECRET_KEY;
-
- CK_ATTRIBUTE template_pub_priv[] = {
- { CKA_ID, id, id_len },
- { CKA_CLASS, &class, sizeof(CK_OBJECT_CLASS) }
- };
-
- CK_ATTRIBUTE template_sec[] = {
- { CKA_ID, id, id_len },
- { CKA_CLASS, &class_sec, sizeof(CK_OBJECT_CLASS) }
- };
-
- CK_ATTRIBUTE template_id[] = {
- { CKA_ID, id, id_len }
- };
-
- /*
- * Only one secret key with same ID is allowed
- */
- if (class == CKO_SECRET_KEY) {
- rv = self->p11->C_FindObjectsInit(self->session, template_id, 1);
- if (!check_return_value(rv, "id, label exists init"))
- return -1;
-
- rv = self->p11->C_FindObjects(self->session, &result_object, 1,
- &object_count);
- if (!check_return_value(rv, "id, label exists"))
- return -1;
-
- rv = self->p11->C_FindObjectsFinal(self->session);
- if (!check_return_value(rv, "id, label exists final"))
- return -1;
-
- if (object_count > 0) {
- /* object found */
- return 1;
- }
- return 0;
- }
-
- /*
- * Public and private keys can share one ID, but
- */
-
- /* test if secret key with same ID exists */
- rv = self->p11->C_FindObjectsInit(self->session, template_sec, 2);
- if (!check_return_value(rv, "id, label exists init"))
- return -1;
-
- rv = self->p11->C_FindObjects(self->session, &result_object, 1,
- &object_count);
- if (!check_return_value(rv, "id, label exists"))
- return -1;
-
- rv = self->p11->C_FindObjectsFinal(self->session);
- if (!check_return_value(rv, "id, label exists final"))
- return -1;
-
- if (object_count > 0) {
- /* object found */
- return 1;
- }
-
- /* test if pub/private key with same id exists */
- object_count = 0;
-
- rv = self->p11->C_FindObjectsInit(self->session, template_pub_priv, 2);
- if (!check_return_value(rv, "id, label exists init"))
- return -1;
-
- rv = self->p11->C_FindObjects(self->session, &result_object, 1,
- &object_count);
- if (!check_return_value(rv, "id, label exists"))
- return -1;
-
- rv = self->p11->C_FindObjectsFinal(self->session);
- if (!check_return_value(rv, "id, label exists final"))
- return -1;
-
- if (object_count > 0) {
- return 1; /* Object found*/
- }
-
- return 0; /* Object not found*/
-}
-
-/*
- * Function set default param values for wrapping mechanism
- * :param mech_type: mechanism type
- * :param mech: filled structure with params based on mech type
- *
- * :return: 1 if sucessfull, 0 if error (fill proper exception)
- *
- * Warning: do not dealloc param values, it is static variables
- */
-int _set_wrapping_mech_parameters(CK_MECHANISM_TYPE mech_type,
- CK_MECHANISM *mech) {
- switch (mech_type) {
- case CKM_RSA_PKCS:
- case CKM_AES_KEY_WRAP:
- case CKM_AES_KEY_WRAP_PAD:
- mech->pParameter = NULL;
- mech->ulParameterLen = 0;
- break;
-
- case CKM_RSA_PKCS_OAEP:
- /* Use the same configuration as openSSL
- * https://www.openssl.org/docs/crypto/RSA_public_encrypt.html
- */
- mech->pParameter = (void *) &CONST_RSA_PKCS_OAEP_PARAMS;
- mech->ulParameterLen = sizeof(CONST_RSA_PKCS_OAEP_PARAMS);
- break;
-
- default:
- PyErr_SetString(ipap11helperError,
- "Unsupported wrapping mechanism");
- return 0;
- }
- mech->mechanism = mech_type;
- return 1;
-}
-
-
-/***********************************************************************
- * P11_Helper object
- */
-
-static void P11_Helper_dealloc(P11_Helper *self) {
- Py_TYPE(self)->tp_free((PyObject *) self);
-}
-
-static PyObject *P11_Helper_new(PyTypeObject *type, PyObject *args,
- PyObject *kwds) {
- P11_Helper *self;
-
- self = (P11_Helper *) type->tp_alloc(type, 0);
- if (self != NULL) {
-
- self->slot = 0;
- self->session = 0;
- self->p11 = NULL;
- self->module_handle = NULL;
- }
-
- return (PyObject *) self;
-}
-
-static int P11_Helper_init(P11_Helper *self, PyObject *args, PyObject *kwds) {
- const char *user_pin = NULL;
- const char *library_path = NULL;
- CK_RV rv;
- void *module_handle = NULL;
-
- /* Parse method args */
- if (!PyArg_ParseTuple(args, "iss", &self->slot, &user_pin, &library_path))
- return -1;
-
- CK_C_GetFunctionList pGetFunctionList = loadLibrary(library_path,
- &module_handle);
- if (!pGetFunctionList) {
- PyErr_SetString(ipap11helperError, "Could not load the library.");
- return -1;
- }
-
- self->module_handle = module_handle;
-
- /*
- * Load the function list
- */
- (*pGetFunctionList)(&self->p11);
-
- /*
- * Initialize
- */
- rv = self->p11->C_Initialize(NULL);
- if (!check_return_value(rv, "initialize"))
- return -1;
-
- /*
- *Start session
- */
- rv = self->p11->C_OpenSession(self->slot,
- CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL,
- NULL, &self->session);
- if (!check_return_value(rv, "open session"))
- return -1;
-
- /*
- * Login
- */
- rv = self->p11->C_Login(self->session, CKU_USER, (CK_BYTE *) user_pin,
- strlen((char *) user_pin));
- if (!check_return_value(rv, "log in"))
- return -1;
-
- return 0;
-}
-
-static PyMemberDef P11_Helper_members[] = {
- { NULL } /* Sentinel */
-};
-
-/*
- * Finalize operations with pkcs11 library
- */
-static PyObject *P11_Helper_finalize(P11_Helper *self) {
- CK_RV rv;
-
- if (self->p11 == NULL)
- Py_RETURN_NONE;
-
- /*
- * Logout
- */
- rv = self->p11->C_Logout(self->session);
- if (rv != CKR_USER_NOT_LOGGED_IN) {
- if (!check_return_value(rv, "log out"))
- return NULL;
- }
-
- /*
- * End session
- */
- rv = self->p11->C_CloseSession(self->session);
- if (!check_return_value(rv, "close session"))
- return NULL;
-
- /*
- * Finalize
- */
- self->p11->C_Finalize(NULL);
-
- unloadLibrary(self->module_handle);
-
- self->p11 = NULL;
- self->session = 0;
- self->slot = 0;
- self->module_handle = NULL;
-
- Py_RETURN_NONE;
-}
-
-/********************************************************************
- * Methods working with keys
- */
-
-/**
- * Generate master key
- *
- *:return: master key handle
- */
-static PyObject *P11_Helper_generate_master_key(P11_Helper *self,
- PyObject *args,
- PyObject *kwds) {
- PyObj2Bool_mapping_t attrs[] = {
- { NULL, &true }, // sec_en_cka_copyable
- { NULL, &false }, // sec_en_cka_decrypt
- { NULL, &false }, // sec_en_cka_derive
- { NULL, &false }, // sec_en_cka_encrypt
- { NULL, &true }, // sec_en_cka_extractable
- { NULL, &true }, // sec_en_cka_modifiable
- { NULL, &true }, // sec_en_cka_private
- { NULL, &true }, // sec_en_cka_sensitive
- { NULL, &false }, // sec_en_cka_sign
- { NULL, &true }, // sec_en_cka_unwrap
- { NULL, &false }, // sec_en_cka_verify
- { NULL, &true }, // sec_en_cka_wrap
- { NULL, &false } // sec_en_cka_wrap_with_trusted
- };
-
- CK_ULONG key_length = 16;
- CK_RV rv;
- CK_OBJECT_HANDLE master_key;
- CK_BYTE *id = NULL;
- int id_length = 0;
-
- PyObject *label_unicode = NULL;
- Py_ssize_t label_length = 0;
- CK_BYTE *label = NULL;
- int r;
- int error = 0;
- static char *kwlist[] = { "subject", "id", "key_length", "cka_copyable",
- "cka_decrypt", "cka_derive", "cka_encrypt", "cka_extractable",
- "cka_modifiable", "cka_private", "cka_sensitive", "cka_sign",
- "cka_unwrap", "cka_verify", "cka_wrap", "cka_wrap_with_trusted",
- NULL
- };
- //TODO check long overflow
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "Us#|kOOOOOOOOOOOOO", kwlist,
- &label_unicode, &id, &id_length,
- &key_length,
- &attrs[sec_en_cka_copyable].py_obj,
- &attrs[sec_en_cka_decrypt].py_obj,
- &attrs[sec_en_cka_derive].py_obj,
- &attrs[sec_en_cka_encrypt].py_obj,
- &attrs[sec_en_cka_extractable].py_obj,
- &attrs[sec_en_cka_modifiable].py_obj,
- &attrs[sec_en_cka_private].py_obj,
- &attrs[sec_en_cka_sensitive].py_obj,
- &attrs[sec_en_cka_sign].py_obj,
- &attrs[sec_en_cka_unwrap].py_obj,
- &attrs[sec_en_cka_verify].py_obj,
- &attrs[sec_en_cka_wrap].py_obj,
- &attrs
- [sec_en_cka_wrap_with_trusted].py_obj)) {
- return NULL;
- }
-
- label = (unsigned char *) unicode_to_char_array(label_unicode,
- &label_length);
- if (label == NULL)
- GOTO_FAIL;
-
- CK_MECHANISM mechanism = { //TODO param?
- CKM_AES_KEY_GEN, NULL_PTR, 0
- };
-
- if ((key_length != 16) && (key_length != 24) && (key_length != 32)) {
- PyErr_SetString(ipap11helperError,
- "generate_master_key: key length allowed values are: 16, 24 and 32");
- GOTO_FAIL;
- }
-
- r = _id_exists(self, id, id_length, CKO_SECRET_KEY);
- if (r == 1) {
- PyErr_SetString(ipap11helperDuplicationError,
- "Master key with same ID already exists");
- GOTO_FAIL;
- } else if (r == -1) {
- GOTO_FAIL;
- }
-
- /* Process keyword boolean arguments */
- convert_py2bool(attrs, sizeof(attrs) / sizeof(PyObj2Bool_mapping_t));
-
- CK_ATTRIBUTE symKeyTemplate[] = {
- { CKA_ID, id, id_length },
- { CKA_LABEL, label, label_length },
- { CKA_TOKEN, &true, sizeof(CK_BBOOL) },
- { CKA_VALUE_LEN, &key_length, sizeof(key_length) },
- //{ CKA_COPYABLE, attrs[sec_en_cka_copyable].bool, sizeof(CK_BBOOL) }, //TODO Softhsm doesn't support it
- { CKA_DECRYPT, attrs[sec_en_cka_decrypt].bool, sizeof(CK_BBOOL) },
- { CKA_DERIVE, attrs[sec_en_cka_derive].bool, sizeof(CK_BBOOL) },
- { CKA_ENCRYPT, attrs[sec_en_cka_encrypt].bool, sizeof(CK_BBOOL) },
- { CKA_EXTRACTABLE, attrs[sec_en_cka_extractable].bool, sizeof(CK_BBOOL) },
- { CKA_MODIFIABLE, attrs[sec_en_cka_modifiable].bool, sizeof(CK_BBOOL) },
- { CKA_PRIVATE, attrs[sec_en_cka_private].bool, sizeof(CK_BBOOL) },
- { CKA_SENSITIVE, attrs[sec_en_cka_sensitive].bool, sizeof(CK_BBOOL) },
- { CKA_SIGN, attrs[sec_en_cka_sign].bool, sizeof(CK_BBOOL) },
- { CKA_UNWRAP, attrs[sec_en_cka_unwrap].bool, sizeof(CK_BBOOL) },
- { CKA_VERIFY, attrs[sec_en_cka_verify].bool, sizeof(CK_BBOOL) },
- { CKA_WRAP, attrs[sec_en_cka_wrap].bool, sizeof(CK_BBOOL) },
- { CKA_WRAP_WITH_TRUSTED, attrs[sec_en_cka_wrap_with_trusted].bool, sizeof(CK_BBOOL) }
- };
-
- rv = self->p11->C_GenerateKey(self->session, &mechanism, symKeyTemplate,
- sizeof(symKeyTemplate) /
- sizeof(CK_ATTRIBUTE), &master_key);
- if (!check_return_value(rv, "generate master key")) {
- GOTO_FAIL;
- }
-final:
- if (label != NULL)
- PyMem_Free(label);
-
- if (error)
- return NULL;
- return Py_BuildValue("k", master_key);
-}
-
-/**
- * Generate replica keys
- *
- * :returns: tuple (public_key_handle, private_key_handle)
- */
-static PyObject *P11_Helper_generate_replica_key_pair(P11_Helper *self,
- PyObject *args,
- PyObject *kwds) {
- CK_RV rv;
- int r;
- CK_ULONG modulus_bits = 2048;
- CK_BYTE *id = NULL;
- int id_length = 0;
- PyObject *label_unicode = NULL;
- Py_ssize_t label_length = 0;
- CK_BYTE *label = NULL;
- int error = 0;
-
- PyObj2Bool_mapping_t attrs_pub[] = {
- { NULL, &true }, // pub_en_cka_copyable
- { NULL, &false }, // pub_en_cka_derive
- { NULL, &false }, // pub_en_cka_encrypt
- { NULL, &true }, // pub_en_cka_modifiable
- { NULL, &true }, // pub_en_cka_private
- { NULL, &false }, // pub_en_cka_trusted
- { NULL, &false }, // pub_en_cka_verify
- { NULL, &false }, // pub_en_cka_verify_recover
- { NULL, &true }, // pub_en_cka_wrap
- };
-
- PyObj2Bool_mapping_t attrs_priv[] = {
- { NULL, &false }, // priv_en_cka_always_authenticate
- { NULL, &true }, // priv_en_cka_copyable
- { NULL, &false }, // priv_en_cka_decrypt
- { NULL, &false }, // priv_en_cka_derive
- { NULL, &false }, // priv_en_cka_extractable
- { NULL, &true }, // priv_en_cka_modifiable
- { NULL, &true }, // priv_en_cka_private
- { NULL, &true }, // priv_en_cka_sensitive
- { NULL, &false }, // priv_en_cka_sign
- { NULL, &false }, // priv_en_cka_sign_recover
- { NULL, &true }, // priv_en_cka_unwrap
- { NULL, &false } // priv_en_cka_wrap_with_trusted
- };
-
- static char *kwlist[] = { "label", "id", "modulus_bits",
- /* public key kw */
- "pub_cka_copyable", "pub_cka_derive", "pub_cka_encrypt",
- "pub_cka_modifiable", "pub_cka_private", "pub_cka_trusted",
- "pub_cka_verify", "pub_cka_verify_recover", "pub_cka_wrap",
- /* private key kw */
- "priv_cka_always_authenticate", "priv_cka_copyable",
- "priv_cka_decrypt", "priv_cka_derive", "priv_cka_extractable",
- "priv_cka_modifiable", "priv_cka_private", "priv_cka_sensitive",
- "priv_cka_sign", "priv_cka_sign_recover", "priv_cka_unwrap",
- "priv_cka_wrap_with_trusted", NULL
- };
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "Us#|kOOOOOOOOOOOOOOOOOOOOO",
- kwlist, &label_unicode, &id, &id_length,
- &modulus_bits,
- /* public key kw */
- &attrs_pub[pub_en_cka_copyable].py_obj,
- &attrs_pub[pub_en_cka_derive].py_obj,
- &attrs_pub[pub_en_cka_encrypt].py_obj,
- &attrs_pub[pub_en_cka_modifiable].py_obj,
- &attrs_pub[pub_en_cka_private].py_obj,
- &attrs_pub[pub_en_cka_trusted].py_obj,
- &attrs_pub[pub_en_cka_verify].py_obj,
- &attrs_pub[pub_en_cka_verify_recover].py_obj,
- &attrs_pub[pub_en_cka_wrap].py_obj,
- /* private key kw */
- &attrs_priv[priv_en_cka_always_authenticate].py_obj,
- &attrs_priv[priv_en_cka_copyable].py_obj,
- &attrs_priv[priv_en_cka_decrypt].py_obj,
- &attrs_priv[priv_en_cka_derive].py_obj,
- &attrs_priv[priv_en_cka_extractable].py_obj,
- &attrs_priv[priv_en_cka_modifiable].py_obj,
- &attrs_priv[priv_en_cka_private].py_obj,
- &attrs_priv[priv_en_cka_sensitive].py_obj,
- &attrs_priv[priv_en_cka_sign].py_obj,
- &attrs_priv[priv_en_cka_sign_recover].py_obj,
- &attrs_priv[priv_en_cka_unwrap].py_obj,
- &attrs_priv[priv_en_cka_wrap_with_trusted].py_obj)) {
- return NULL;
- }
-
- label = unicode_to_char_array(label_unicode, &label_length);
- if (label == NULL)
- GOTO_FAIL;
-
- CK_OBJECT_HANDLE public_key, private_key;
- CK_MECHANISM mechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
-
- r = _id_exists(self, id, id_length, CKO_PRIVATE_KEY);
- if (r == 1) {
- PyErr_SetString(ipap11helperDuplicationError,
- "Private key with same ID already exists");
- GOTO_FAIL;
- } else if (r == -1)
- GOTO_FAIL;
-
- r = _id_exists(self, id, id_length, CKO_PUBLIC_KEY);
- if (r == 1) {
- PyErr_SetString(ipap11helperDuplicationError,
- "Public key with same ID already exists");
- GOTO_FAIL;
- } else if (r == -1)
- GOTO_FAIL;
-
- /* Process keyword boolean arguments */
- convert_py2bool(attrs_pub,
- sizeof(attrs_pub) / sizeof(PyObj2Bool_mapping_t));
- convert_py2bool(attrs_priv,
- sizeof(attrs_priv) / sizeof(PyObj2Bool_mapping_t));
-
- CK_BYTE public_exponent[] = { 1, 0, 1 }; /* 65537 (RFC 6376 section 3.3.1) */
- CK_ATTRIBUTE publicKeyTemplate[] = {
- { CKA_ID, id, id_length },
- { CKA_LABEL, label, label_length },
- { CKA_TOKEN, &true, sizeof(true) },
- { CKA_MODULUS_BITS, &modulus_bits, sizeof(modulus_bits) },
- { CKA_PUBLIC_EXPONENT, public_exponent, 3 },
- //{ CKA_COPYABLE, attrs_pub[pub_en_cka_copyable].bool, sizeof(CK_BBOOL) }, //TODO Softhsm doesn't support it
- { CKA_DERIVE, attrs_pub[pub_en_cka_derive].bool, sizeof(CK_BBOOL) },
- { CKA_ENCRYPT, attrs_pub[pub_en_cka_encrypt].bool, sizeof(CK_BBOOL) },
- { CKA_MODIFIABLE, attrs_pub[pub_en_cka_modifiable].bool, sizeof(CK_BBOOL) },
- { CKA_PRIVATE, attrs_pub[pub_en_cka_private].bool, sizeof(CK_BBOOL) },
- { CKA_TRUSTED, attrs_pub[pub_en_cka_trusted].bool, sizeof(CK_BBOOL) },
- { CKA_VERIFY, attrs_pub[pub_en_cka_verify].bool, sizeof(CK_BBOOL) },
- { CKA_VERIFY_RECOVER, attrs_pub[pub_en_cka_verify_recover].bool, sizeof(CK_BBOOL) },
- { CKA_WRAP, attrs_pub[pub_en_cka_wrap].bool, sizeof(CK_BBOOL) }, };
-
- CK_ATTRIBUTE privateKeyTemplate[] = {
- { CKA_ID, id, id_length },
- { CKA_LABEL, label, label_length },
- { CKA_TOKEN, &true, sizeof(true) },
- { CKA_ALWAYS_AUTHENTICATE, attrs_priv[priv_en_cka_always_authenticate].bool, sizeof(CK_BBOOL) },
- //{ CKA_COPYABLE, attrs_priv[priv_en_cka_copyable].bool, sizeof(CK_BBOOL) }, //TODO Softhsm doesn't support it
- { CKA_DECRYPT, attrs_priv[priv_en_cka_decrypt].bool, sizeof(CK_BBOOL) },
- { CKA_DERIVE, attrs_priv[priv_en_cka_derive].bool, sizeof(CK_BBOOL) },
- { CKA_EXTRACTABLE, attrs_priv[priv_en_cka_extractable].bool, sizeof(CK_BBOOL) },
- { CKA_MODIFIABLE, attrs_priv[priv_en_cka_modifiable].bool, sizeof(CK_BBOOL) },
- { CKA_PRIVATE, attrs_priv[priv_en_cka_private].bool, sizeof(CK_BBOOL) },
- { CKA_SENSITIVE, attrs_priv[priv_en_cka_sensitive].bool, sizeof(CK_BBOOL) },
- { CKA_SIGN, attrs_priv[priv_en_cka_sign].bool, sizeof(CK_BBOOL) },
- { CKA_SIGN_RECOVER, attrs_priv[priv_en_cka_sign].bool, sizeof(CK_BBOOL) },
- { CKA_UNWRAP, attrs_priv[priv_en_cka_unwrap].bool, sizeof(CK_BBOOL) },
- { CKA_WRAP_WITH_TRUSTED, attrs_priv[priv_en_cka_wrap_with_trusted].bool, sizeof(CK_BBOOL) }
- };
-
- rv = self->p11->C_GenerateKeyPair(self->session, &mechanism,
- publicKeyTemplate,
- sizeof(publicKeyTemplate) / sizeof(CK_ATTRIBUTE),
- privateKeyTemplate,
- sizeof(privateKeyTemplate) / sizeof(CK_ATTRIBUTE),
- &public_key,
- &private_key);
- if (!check_return_value(rv, "generate key pair"))
- GOTO_FAIL;
-
-final:
- if (label != NULL)
- PyMem_Free(label);
-
- if (error)
- return NULL;
- return Py_BuildValue("(kk)", public_key, private_key);
-}
-
-/**
- * Find key
- */
-static PyObject *P11_Helper_find_keys(P11_Helper *self, PyObject *args,
- PyObject *kwds) {
- CK_OBJECT_CLASS class = CKO_VENDOR_DEFINED;
- CK_OBJECT_CLASS *class_ptr = &class;
- CK_BYTE *id = NULL;
- CK_BBOOL *ckawrap = NULL;
- CK_BBOOL *ckaunwrap = NULL;
- int id_length = 0;
- PyObject *label_unicode = NULL;
- PyObject *cka_wrap_bool = NULL;
- PyObject *cka_unwrap_bool = NULL;
- Py_ssize_t label_length = 0;
- CK_OBJECT_HANDLE *objects = NULL;
- unsigned int objects_len = 0;
- PyObject *result_list = NULL;
- const char *uri_str = NULL;
- P11KitUri *uri = NULL;
- CK_BYTE *label = NULL;
- CK_ATTRIBUTE template_static[MAX_TEMPLATE_LEN];
- CK_ATTRIBUTE_PTR template = template_static;
- CK_ULONG template_len = MAX_TEMPLATE_LEN;
- int error = 0;
-
- static char *kwlist[] = { "objclass", "label", "id", "cka_wrap",
- "cka_unwrap", "uri", NULL
- };
- //TODO check long overflow
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iUz#OOs", kwlist, &class,
- &label_unicode, &id, &id_length,
- &cka_wrap_bool, &cka_unwrap_bool,
- &uri_str)) {
- GOTO_FAIL;
- }
-
- if (label_unicode != NULL) {
- label = (unsigned char *) unicode_to_char_array(label_unicode, &label_length); //TODO verify signed/unsigned
- if (label == NULL)
- GOTO_FAIL;
- }
-
- if (cka_wrap_bool != NULL) {
- if (PyObject_IsTrue(cka_wrap_bool)) {
- ckawrap = &true;
- } else {
- ckawrap = &false;
- }
- }
-
- if (cka_unwrap_bool != NULL) {
- if (PyObject_IsTrue(cka_unwrap_bool)) {
- ckaunwrap = &true;
- } else {
- ckaunwrap = &false;
- }
- }
-
- if (class == CKO_VENDOR_DEFINED)
- class_ptr = NULL;
-
- if (uri_str == NULL)
- _fill_template_from_parts(template, &template_len, id, id_length,
- label, label_length, class_ptr, ckawrap,
- ckaunwrap);
- else {
- if (!_parse_uri(uri_str, &uri)) {
- GOTO_FAIL;
- }
- template = p11_kit_uri_get_attributes(uri, &template_len);
- /* Do not deallocate URI while you are using the template.
- * Template contains pointers to values inside URI! */
- }
-
- if (!_find_key(self, template, template_len, &objects, &objects_len)) {
- GOTO_FAIL;
- }
-
- result_list = PyList_New(objects_len);
- if (result_list == NULL) {
- PyErr_SetString(ipap11helperError,
- "Unable to create list with results");
- GOTO_FAIL;
- }
-
- for (int i = 0; i < objects_len; ++i) {
- if (PyList_SetItem(result_list, i, Py_BuildValue("k", objects[i]))
- == -1) {
- PyErr_SetString(ipap11helperError,
- "Unable to add to value to result list");
- Py_DECREF(result_list);
- GOTO_FAIL;
- }
- }
-final:
- if (label != NULL)
- PyMem_Free(label);
- if (objects != NULL)
- free(objects);
- if (uri != NULL)
- p11_kit_uri_free(uri);
-
- if (error)
- return NULL;
- return result_list;
-}
-
-/**
- * delete key
- */
-static PyObject *P11_Helper_delete_key(P11_Helper *self, PyObject *args,
- PyObject *kwds) {
- CK_RV rv;
- CK_OBJECT_HANDLE key_handle = 0;
- static char *kwlist[] = { "key_handle", NULL };
- //TODO check long overflow
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "k|", kwlist, &key_handle)) {
- return NULL;
- }
- rv = self->p11->C_DestroyObject(self->session, key_handle);
- if (!check_return_value(rv, "object deletion")) {
- return NULL;
- }
-
- Py_RETURN_NONE;
-}
-
-/**
- * export RSA public key
- */
-static PyObject *P11_Helper_export_RSA_public_key(P11_Helper *self,
- CK_OBJECT_HANDLE object) {
- CK_RV rv;
- PyObject *ret = NULL;
-
- int pp_len;
- unsigned char *pp = NULL;
- EVP_PKEY *pkey = NULL;
- BIGNUM *e = NULL;
- BIGNUM *n = NULL;
- RSA *rsa = NULL;
- CK_BYTE_PTR modulus = NULL;
- CK_BYTE_PTR exponent = NULL;
- CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
- CK_KEY_TYPE key_type = CKK_RSA;
- int error = 0;
-
- CK_ATTRIBUTE obj_template[] = {
- { CKA_MODULUS, NULL_PTR, 0 },
- { CKA_PUBLIC_EXPONENT, NULL_PTR, 0 },
- { CKA_CLASS, &class, sizeof(class) },
- { CKA_KEY_TYPE, &key_type, sizeof(key_type) }
- };
-
- rv = self->p11->C_GetAttributeValue(self->session, object, obj_template,
- sizeof(obj_template) / sizeof(CK_ATTRIBUTE));
- if (!check_return_value(rv, "get RSA public key values - prepare"))
- GOTO_FAIL;
-
- /* Set proper size for attributes */
- modulus =
- (CK_BYTE_PTR) PyMem_Malloc(obj_template[0].ulValueLen *
- sizeof(CK_BYTE));
- if (modulus == NULL) {
- PyErr_NoMemory();
- GOTO_FAIL;
- }
- obj_template[0].pValue = modulus;
- exponent =
- (CK_BYTE_PTR) PyMem_Malloc(obj_template[1].ulValueLen *
- sizeof(CK_BYTE));
- if (exponent == NULL) {
- PyErr_NoMemory();
- GOTO_FAIL;
- }
- obj_template[1].pValue = exponent;
-
- rv = self->p11->C_GetAttributeValue(self->session, object, obj_template,
- sizeof(obj_template) / sizeof(CK_ATTRIBUTE));
- if (!check_return_value(rv, "get RSA public key values")) {
- GOTO_FAIL;
- }
-
- /* Check if the key is RSA public key */
- if (class != CKO_PUBLIC_KEY) {
- PyErr_SetString(ipap11helperError,
- "export_RSA_public_key: required public key class");
- GOTO_FAIL;
- }
-
- if (key_type != CKK_RSA) {
- PyErr_SetString(ipap11helperError,
- "export_RSA_public_key: required RSA key type");
- GOTO_FAIL;
- }
-
- rsa = RSA_new();
- pkey = EVP_PKEY_new();
- n = BN_bin2bn((const unsigned char *) modulus,
- obj_template[0].ulValueLen * sizeof(CK_BYTE), NULL);
- if (n == NULL) {
- PyErr_SetString(ipap11helperError,
- "export_RSA_public_key: internal error: unable to convert modulus");
- GOTO_FAIL;
- }
-
- e = BN_bin2bn((const unsigned char *) exponent,
- obj_template[1].ulValueLen * sizeof(CK_BYTE), NULL);
- if (e == NULL) {
- PyErr_SetString(ipap11helperError,
- "export_RSA_public_key: internal error: unable to convert exponent");
- GOTO_FAIL;
- }
-
- /* set modulus and exponent */
- rsa->n = n;
- rsa->e = e;
-
- if (EVP_PKEY_set1_RSA(pkey, rsa) == 0) {
- PyErr_SetString(ipap11helperError,
- "export_RSA_public_key: internal error: EVP_PKEY_set1_RSA failed");
- GOTO_FAIL;
- }
-
- pp_len = i2d_PUBKEY(pkey, &pp);
- ret = string_to_pybytes_or_none(pp, pp_len);
-
-final:
- if (rsa != NULL) {
- RSA_free(rsa); // this frees also 'n' and 'e'
- } else {
- if (n != NULL)
- BN_free(n);
- if (e != NULL)
- BN_free(e);
- }
-
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
- if (pp != NULL)
- free(pp);
- if (modulus != NULL)
- PyMem_Free(modulus);
- if (exponent != NULL)
- PyMem_Free(exponent);
-
- if (error)
- return NULL;
- return ret;
-}
-
-/**
- * Export public key
- *
- * Export public key in SubjectPublicKeyInfo (RFC5280) DER encoded format
- */
-static PyObject *P11_Helper_export_public_key(P11_Helper *self,
- PyObject *args, PyObject *kwds) {
- CK_RV rv;
- CK_OBJECT_HANDLE object = 0;
- CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
- CK_KEY_TYPE key_type = CKK_RSA;
- static char *kwlist[] = { "key_handle", NULL };
- //TODO check long overflow
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "k|", kwlist, &object)) {
- return NULL;
- }
-
- CK_ATTRIBUTE obj_template[] = {
- { CKA_CLASS, &class, sizeof(class) },
- { CKA_KEY_TYPE, &key_type, sizeof(key_type) }
- };
-
- rv = self->p11->C_GetAttributeValue(self->session, object, obj_template,
- sizeof(obj_template) / sizeof(CK_ATTRIBUTE));
- if (!check_return_value
- (rv, "export_public_key: get RSA public key values"))
- return NULL;
-
- if (class != CKO_PUBLIC_KEY) {
- PyErr_SetString(ipap11helperError,
- "export_public_key: required public key class");
- return NULL;
- }
-
- switch (key_type) {
- case CKK_RSA:
- return P11_Helper_export_RSA_public_key(self, object);
- break;
- default:
- PyErr_SetString(ipap11helperError,
- "export_public_key: unsupported key type");
- }
-
- return NULL;
-}
-
-/**
- * Import RSA public key
- *
- */
-static PyObject *P11_Helper_import_RSA_public_key(P11_Helper *self,
- CK_UTF8CHAR * label,
- Py_ssize_t label_length,
- CK_BYTE * id,
- Py_ssize_t id_length,
- EVP_PKEY * pkey,
- CK_BBOOL *cka_copyable,
- CK_BBOOL *cka_derive,
- CK_BBOOL *cka_encrypt,
- CK_BBOOL *cka_modifiable,
- CK_BBOOL *cka_private,
- CK_BBOOL *cka_trusted,
- CK_BBOOL *cka_verify,
- CK_BBOOL *cka_verify_recover,
- CK_BBOOL *cka_wrap) {
- CK_RV rv;
- CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
- CK_KEY_TYPE keyType = CKK_RSA;
- CK_BBOOL *cka_token = &true;
- RSA *rsa = NULL;
- CK_BYTE_PTR modulus = NULL;
- int modulus_len = 0;
- CK_BYTE_PTR exponent = NULL;
- int exponent_len = 0;
- int error = 0;
-
- if (pkey->type != EVP_PKEY_RSA) {
- PyErr_SetString(ipap11helperError, "Required RSA public key");
- GOTO_FAIL;
- }
-
- rsa = EVP_PKEY_get1_RSA(pkey);
- if (rsa == NULL) {
- PyErr_SetString(ipap11helperError,
- "import_RSA_public_key: EVP_PKEY_get1_RSA error");
- GOTO_FAIL;
- }
-
- /* convert BIGNUM to binary array */
- modulus = (CK_BYTE_PTR) PyMem_Malloc(BN_num_bytes(rsa->n));
- if (modulus == NULL) {
- PyErr_NoMemory();
- GOTO_FAIL;
- }
- modulus_len = BN_bn2bin(rsa->n, (unsigned char *) modulus);
- if (modulus_len == 0) {
- PyErr_SetString(ipap11helperError,
- "import_RSA_public_key: BN_bn2bin modulus error");
- GOTO_FAIL;
- }
-
- exponent = (CK_BYTE_PTR) PyMem_Malloc(BN_num_bytes(rsa->e));
- if (exponent == NULL) {
- PyErr_NoMemory();
- GOTO_FAIL;
- }
- exponent_len = BN_bn2bin(rsa->e, (unsigned char *) exponent);
- if (exponent_len == 0) {
- PyErr_SetString(ipap11helperError,
- "import_RSA_public_key: BN_bn2bin exponent error");
- GOTO_FAIL;
- }
-
- CK_ATTRIBUTE template[] = {
- { CKA_ID, id, id_length },
- { CKA_CLASS, &class, sizeof(class) },
- { CKA_KEY_TYPE, &keyType, sizeof(keyType) },
- { CKA_TOKEN, cka_token, sizeof(CK_BBOOL) },
- { CKA_LABEL, label, label_length },
- { CKA_MODULUS, modulus, modulus_len },
- { CKA_PUBLIC_EXPONENT, exponent, exponent_len },
- //{ CKA_COPYABLE, cka_copyable, sizeof(CK_BBOOL) }, //TODO Softhsm doesn't support it
- { CKA_DERIVE, cka_derive, sizeof(CK_BBOOL) },
- { CKA_ENCRYPT, cka_encrypt, sizeof(CK_BBOOL) },
- { CKA_MODIFIABLE, cka_modifiable, sizeof(CK_BBOOL) },
- { CKA_PRIVATE, cka_private, sizeof(CK_BBOOL) },
- { CKA_TRUSTED, cka_trusted, sizeof(CK_BBOOL) },
- { CKA_VERIFY, cka_verify, sizeof(CK_BBOOL) },
- { CKA_VERIFY_RECOVER, cka_verify_recover, sizeof(CK_BBOOL) },
- { CKA_WRAP, cka_wrap, sizeof(CK_BBOOL) }
- };
- CK_OBJECT_HANDLE object;
-
- rv = self->p11->C_CreateObject(self->session, template,
- sizeof(template) / sizeof(CK_ATTRIBUTE),
- &object);
- if (!check_return_value(rv, "create public key object"))
- GOTO_FAIL;
-
-final:
- if (rsa != NULL)
- RSA_free(rsa);
- if (modulus != NULL)
- PyMem_Free(modulus);
- if (exponent != NULL)
- PyMem_Free(exponent);
-
- if (error)
- return NULL;
- return Py_BuildValue("k", object);
-}
-
-/**
- * Import RSA public key
- *
- */
-static PyObject *P11_Helper_import_public_key(P11_Helper *self,
- PyObject *args, PyObject *kwds) {
- int r;
- PyObject *ret = NULL;
- PyObject *label_unicode = NULL;
- CK_BYTE *id = NULL;
- CK_BYTE *data = NULL;
- CK_UTF8CHAR *label = NULL;
- Py_ssize_t id_length = 0;
- Py_ssize_t data_length = 0;
- Py_ssize_t label_length = 0;
- EVP_PKEY *pkey = NULL;
- int error = 0;
-
- PyObj2Bool_mapping_t attrs_pub[] = {
- { NULL, &true }, // pub_en_cka_copyable
- { NULL, &false }, // pub_en_cka_derive
- { NULL, &false }, // pub_en_cka_encrypt
- { NULL, &true }, // pub_en_cka_modifiable
- { NULL, &true }, // pub_en_cka_private
- { NULL, &false }, // pub_en_cka_trusted
- { NULL, &true }, // pub_en_cka_verify
- { NULL, &true }, // pub_en_cka_verify_recover
- { NULL, &false }, // pub_en_cka_wrap
- };
-
- static char *kwlist[] = { "label", "id", "data",
- /* public key attributes */
- "cka_copyable", "cka_derive", "cka_encrypt", "cka_modifiable",
- "cka_private", "cka_trusted", "cka_verify", "cka_verify_recover",
- "cka_wrap", NULL
- };
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "Us#s#|OOOOOOOOO", kwlist,
- &label_unicode, &id, &id_length, &data,
- &data_length,
- /* public key attributes */
- &attrs_pub[pub_en_cka_copyable].py_obj,
- &attrs_pub[pub_en_cka_derive].py_obj,
- &attrs_pub[pub_en_cka_encrypt].py_obj,
- &attrs_pub[pub_en_cka_modifiable].py_obj,
- &attrs_pub[pub_en_cka_private].py_obj,
- &attrs_pub[pub_en_cka_trusted].py_obj,
- &attrs_pub[pub_en_cka_verify].py_obj,
- &attrs_pub[pub_en_cka_verify_recover].py_obj,
- &attrs_pub[pub_en_cka_wrap].py_obj)) {
- return NULL;
- }
-
- label = (unsigned char *) unicode_to_char_array(label_unicode,
- &label_length);
- if (label == NULL)
- GOTO_FAIL;
-
- r = _id_exists(self, id, id_length, CKO_PUBLIC_KEY);
- if (r == 1) {
- PyErr_SetString(ipap11helperDuplicationError,
- "Public key with same ID already exists");
- GOTO_FAIL;
- } else if (r == -1) {
- GOTO_FAIL;
- }
-
- /* Process keyword boolean arguments */
- convert_py2bool(attrs_pub,
- sizeof(attrs_pub) / sizeof(PyObj2Bool_mapping_t));
-
- /* decode from ASN1 DER */
- pkey = d2i_PUBKEY(NULL, (const unsigned char **) &data, data_length);
- if (pkey == NULL) {
- PyErr_SetString(ipap11helperError,
- "import_public_key: d2i_PUBKEY error");
- GOTO_FAIL;
- }
- switch (pkey->type) {
- case EVP_PKEY_RSA:
- ret = P11_Helper_import_RSA_public_key(self, label, label_length,
- id, id_length, pkey,
- attrs_pub[pub_en_cka_copyable].bool,
- attrs_pub[pub_en_cka_derive].bool,
- attrs_pub[pub_en_cka_encrypt].bool,
- attrs_pub[pub_en_cka_modifiable].bool,
- attrs_pub[pub_en_cka_private].bool,
- attrs_pub[pub_en_cka_trusted].bool,
- attrs_pub[pub_en_cka_verify].bool,
- attrs_pub[pub_en_cka_verify_recover].bool,
- attrs_pub[pub_en_cka_wrap].bool);
- break;
- case EVP_PKEY_DSA:
- error = 1;
- PyErr_SetString(ipap11helperError, "DSA is not supported");
- break;
- case EVP_PKEY_EC:
- error = 1;
- PyErr_SetString(ipap11helperError, "EC is not supported");
- break;
- default:
- error = 1;
- PyErr_SetString(ipap11helperError, "Unsupported key type");
- }
-final:
- if (pkey != NULL)
- EVP_PKEY_free(pkey);
- if (label != NULL)
- PyMem_Free(label);
-
- if (error)
- return NULL;
- return ret;
-}
-
-/**
- * Export wrapped key
- *
- */
-static PyObject *P11_Helper_export_wrapped_key(P11_Helper *self,
- PyObject *args,
- PyObject *kwds) {
- CK_RV rv;
- CK_OBJECT_HANDLE object_key = 0;
- CK_OBJECT_HANDLE object_wrapping_key = 0;
- CK_BYTE_PTR wrapped_key = NULL;
- CK_ULONG wrapped_key_len = 0;
- CK_MECHANISM wrapping_mech = { CKM_RSA_PKCS, NULL, 0 };
- /* currently we don't support parameter in mechanism */
- PyObject *result = NULL;
- int error = 0;
-
- static char *kwlist[] = { "key", "wrapping_key", "wrapping_mech", NULL };
- //TODO check long overflow
- //TODO export method
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "kkk|", kwlist, &object_key,
- &object_wrapping_key,
- &wrapping_mech.mechanism))
- GOTO_FAIL;
-
- // fill mech parameters
- if (!_set_wrapping_mech_parameters(wrapping_mech.mechanism, &wrapping_mech))
- GOTO_FAIL;
-
- rv = self->p11->C_WrapKey(self->session, &wrapping_mech,
- object_wrapping_key, object_key, NULL,
- &wrapped_key_len);
- if (!check_return_value(rv, "key wrapping: get buffer length"))
- GOTO_FAIL;
-
- wrapped_key = PyMem_Malloc(wrapped_key_len);
- if (wrapped_key == NULL) {
- PyErr_NoMemory();
- GOTO_FAIL;
- }
-
- rv = self->p11->C_WrapKey(self->session, &wrapping_mech,
- object_wrapping_key, object_key, wrapped_key,
- &wrapped_key_len);
- if (!check_return_value(rv, "key wrapping: wrapping"))
- GOTO_FAIL;
-
- result = string_to_pybytes_or_none(wrapped_key, wrapped_key_len);
-
-final:
- if (wrapped_key != NULL)
- PyMem_Free(wrapped_key);
-
- if (error)
- return NULL;
- return result;
-
-}
-
-/**
- * Import wrapped secret key
- *
- */
-static PyObject *P11_Helper_import_wrapped_secret_key(P11_Helper *self,
- PyObject *args,
- PyObject *kwds) {
- CK_RV rv;
- int r;
- CK_BYTE_PTR wrapped_key = NULL;
- CK_ULONG wrapped_key_len = 0;
- CK_ULONG unwrapping_key_object = 0;
- CK_OBJECT_HANDLE unwrapped_key_object = 0;
- PyObject *label_unicode = NULL;
- CK_BYTE *id = NULL;
- CK_UTF8CHAR *label = NULL;
- Py_ssize_t id_length = 0;
- Py_ssize_t label_length = 0;
- CK_MECHANISM wrapping_mech = { CKM_RSA_PKCS, NULL, 0 };
- CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
- CK_KEY_TYPE key_type = CKK_RSA;
- int error = 0;
-
- PyObj2Bool_mapping_t attrs[] = {
- { NULL, &true }, // sec_en_cka_copyable
- { NULL, &false }, // sec_en_cka_decrypt
- { NULL, &false }, // sec_en_cka_derive
- { NULL, &false }, // sec_en_cka_encrypt
- { NULL, &true }, // sec_en_cka_extractable
- { NULL, &true }, // sec_en_cka_modifiable
- { NULL, &true }, // sec_en_cka_private
- { NULL, &true }, // sec_en_cka_sensitive
- { NULL, &false }, // sec_en_cka_sign
- { NULL, &true }, // sec_en_cka_unwrap
- { NULL, &false }, // sec_en_cka_verify
- { NULL, &true }, // sec_en_cka_wrap
- { NULL, &false } // sec_en_cka_wrap_with_trusted
- };
-
- static char *kwlist[] = { "label", "id", "data", "unwrapping_key",
- "wrapping_mech", "key_type",
- // secret key attrs
- "cka_copyable", "cka_decrypt", "cka_derive", "cka_encrypt",
- "cka_extractable", "cka_modifiable", "cka_private", "cka_sensitive",
- "cka_sign", "cka_unwrap", "cka_verify", "cka_wrap",
- "cka_wrap_with_trusted", NULL
- };
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "Us#s#kkk|OOOOOOOOOOOOO",
- kwlist, &label_unicode, &id, &id_length,
- &wrapped_key, &wrapped_key_len,
- &unwrapping_key_object,
- &wrapping_mech.mechanism, &key_type,
- // secret key attrs
- &attrs[sec_en_cka_copyable].py_obj,
- &attrs[sec_en_cka_decrypt].py_obj,
- &attrs[sec_en_cka_derive].py_obj,
- &attrs[sec_en_cka_encrypt].py_obj,
- &attrs[sec_en_cka_extractable].py_obj,
- &attrs[sec_en_cka_modifiable].py_obj,
- &attrs[sec_en_cka_private].py_obj,
- &attrs[sec_en_cka_sensitive].py_obj,
- &attrs[sec_en_cka_sign].py_obj,
- &attrs[sec_en_cka_unwrap].py_obj,
- &attrs[sec_en_cka_verify].py_obj,
- &attrs[sec_en_cka_wrap].py_obj,
- &attrs[sec_en_cka_wrap_with_trusted].py_obj)) {
- return NULL;
- }
-
- if (!_set_wrapping_mech_parameters(wrapping_mech.mechanism, &wrapping_mech))
- return NULL;
-
- label = (unsigned char *) unicode_to_char_array(label_unicode,
- &label_length);
- if (label == NULL)
- GOTO_FAIL;
-
- r = _id_exists(self, id, id_length, key_class);
- if (r == 1) {
- PyErr_SetString(ipap11helperDuplicationError,
- "Secret key with same ID already exists");
- GOTO_FAIL;
-
- } else if (r == -1)
- GOTO_FAIL;
-
-
- /* Process keyword boolean arguments */
- convert_py2bool(attrs, sizeof(attrs) / sizeof(PyObj2Bool_mapping_t));
-
- CK_ATTRIBUTE template[] = {
- { CKA_CLASS, &key_class, sizeof(key_class) },
- { CKA_KEY_TYPE, &key_type, sizeof(key_type) },
- { CKA_ID, id, id_length },
- { CKA_LABEL, label, label_length },
- { CKA_TOKEN, &true, sizeof(CK_BBOOL) },
- //{ CKA_COPYABLE, attrs[sec_en_cka_copyable].bool, sizeof(CK_BBOOL) }, //TODO Softhsm doesn't support it
- { CKA_DECRYPT, attrs[sec_en_cka_decrypt].bool, sizeof(CK_BBOOL) },
- { CKA_DERIVE, attrs[sec_en_cka_derive].bool, sizeof(CK_BBOOL) },
- { CKA_ENCRYPT, attrs[sec_en_cka_encrypt].bool, sizeof(CK_BBOOL) },
- { CKA_EXTRACTABLE, attrs[sec_en_cka_extractable].bool, sizeof(CK_BBOOL) },
- { CKA_MODIFIABLE, attrs[sec_en_cka_modifiable].bool, sizeof(CK_BBOOL) },
- { CKA_PRIVATE, attrs[sec_en_cka_private].bool, sizeof(CK_BBOOL) },
- { CKA_SENSITIVE, attrs[sec_en_cka_sensitive].bool, sizeof(CK_BBOOL) },
- { CKA_SIGN, attrs[sec_en_cka_sign].bool, sizeof(CK_BBOOL) },
- { CKA_UNWRAP, attrs[sec_en_cka_unwrap].bool, sizeof(CK_BBOOL) },
- { CKA_VERIFY, attrs[sec_en_cka_verify].bool, sizeof(CK_BBOOL) },
- { CKA_WRAP, attrs[sec_en_cka_wrap].bool, sizeof(CK_BBOOL) },
- { CKA_WRAP_WITH_TRUSTED, attrs[sec_en_cka_wrap_with_trusted].bool, sizeof(CK_BBOOL) }
- };
-
- rv = self->p11->C_UnwrapKey(self->session, &wrapping_mech,
- unwrapping_key_object, wrapped_key,
- wrapped_key_len, template,
- sizeof(template) / sizeof(CK_ATTRIBUTE),
- &unwrapped_key_object);
- if (!check_return_value(rv, "import_wrapped_key: key unwrapping"))
- GOTO_FAIL;
-
-final:
- if (label != NULL)
- PyMem_Free(label);
-
- if (error)
- return NULL;
-
- return Py_BuildValue("k", unwrapped_key_object);
-}
-
-/**
- * Import wrapped private key
- *
- */
-static PyObject *P11_Helper_import_wrapped_private_key(P11_Helper *self,
- PyObject *args,
- PyObject *kwds) {
- CK_RV rv;
- int r;
- CK_BYTE_PTR wrapped_key = NULL;
- CK_ULONG wrapped_key_len = 0;
- CK_ULONG unwrapping_key_object = 0;
- CK_OBJECT_HANDLE unwrapped_key_object = 0;
- PyObject *label_unicode = NULL;
- CK_BYTE *id = NULL;
- CK_UTF8CHAR *label = NULL;
- Py_ssize_t id_length = 0;
- Py_ssize_t label_length = 0;
- CK_MECHANISM wrapping_mech = { CKM_RSA_PKCS, NULL, 0 };
- CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
- CK_KEY_TYPE key_type = CKK_RSA;
- int error = 0;
-
- PyObj2Bool_mapping_t attrs_priv[] = {
- { NULL, &false }, // priv_en_cka_always_authenticate
- { NULL, &true }, // priv_en_cka_copyable
- { NULL, &false }, // priv_en_cka_decrypt
- { NULL, &false }, // priv_en_cka_derive
- { NULL, &true }, // priv_en_cka_extractable
- { NULL, &true }, // priv_en_cka_modifiable
- { NULL, &true }, // priv_en_cka_private
- { NULL, &true }, // priv_en_cka_sensitive
- { NULL, &true }, // priv_en_cka_sign
- { NULL, &true }, // priv_en_cka_sign_recover
- { NULL, &false }, // priv_en_cka_unwrap
- { NULL, &false } // priv_en_cka_wrap_with_trusted
- };
-
- static char *kwlist[] = { "label", "id", "data", "unwrapping_key",
- "wrapping_mech", "key_type",
- // private key attrs
- "cka_always_authenticate", "cka_copyable", "cka_decrypt",
- "cka_derive", "cka_extractable", "cka_modifiable", "cka_private",
- "cka_sensitive", "cka_sign", "cka_sign_recover", "cka_unwrap",
- "cka_wrap_with_trusted", NULL
- };
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "Us#s#kkk|OOOOOOOOOOOO",
- kwlist, &label_unicode, &id, &id_length,
- &wrapped_key, &wrapped_key_len,
- &unwrapping_key_object,
- &wrapping_mech.mechanism, &key_type,
- // private key attrs
- &attrs_priv[priv_en_cka_always_authenticate].py_obj,
- &attrs_priv[priv_en_cka_copyable].py_obj,
- &attrs_priv[priv_en_cka_decrypt].py_obj,
- &attrs_priv[priv_en_cka_derive].py_obj,
- &attrs_priv[priv_en_cka_extractable].py_obj,
- &attrs_priv[priv_en_cka_modifiable].py_obj,
- &attrs_priv[priv_en_cka_private].py_obj,
- &attrs_priv[priv_en_cka_sensitive].py_obj,
- &attrs_priv[priv_en_cka_sign].py_obj,
- &attrs_priv[priv_en_cka_sign_recover].py_obj,
- &attrs_priv[priv_en_cka_unwrap].py_obj,
- &attrs_priv[priv_en_cka_wrap_with_trusted].py_obj)) {
- return NULL;
- }
-
- label = (unsigned char *) unicode_to_char_array(label_unicode,
- &label_length);
- if (label == NULL)
- GOTO_FAIL;
-
- r = _id_exists(self, id, id_length, CKO_SECRET_KEY);
- if (r == 1) {
- PyErr_SetString(ipap11helperDuplicationError,
- "Secret key with same ID already exists");
- GOTO_FAIL;
- } else if (r == -1) {
- GOTO_FAIL;
- }
-
- /* Process keyword boolean arguments */
- convert_py2bool(attrs_priv,
- sizeof(attrs_priv) / sizeof(PyObj2Bool_mapping_t));
-
- CK_ATTRIBUTE template[] = {
- { CKA_CLASS, &key_class, sizeof(key_class) },
- { CKA_KEY_TYPE, &key_type, sizeof(key_type) },
- { CKA_ID, id, id_length },
- { CKA_LABEL, label, label_length },
- { CKA_TOKEN, &true, sizeof(CK_BBOOL) },
- { CKA_ALWAYS_AUTHENTICATE, attrs_priv[priv_en_cka_always_authenticate].bool, sizeof(CK_BBOOL) },
- //{ CKA_COPYABLE, attrs_priv[priv_en_cka_copyable].bool, sizeof(CK_BBOOL) }, //TODO Softhsm doesn't support it
- { CKA_DECRYPT, attrs_priv[priv_en_cka_decrypt].bool, sizeof(CK_BBOOL) },
- { CKA_DERIVE, attrs_priv[priv_en_cka_derive].bool, sizeof(CK_BBOOL) },
- { CKA_EXTRACTABLE, attrs_priv[priv_en_cka_extractable].bool, sizeof(CK_BBOOL) },
- { CKA_MODIFIABLE, attrs_priv[priv_en_cka_modifiable].bool, sizeof(CK_BBOOL) },
- { CKA_PRIVATE, attrs_priv[priv_en_cka_private].bool, sizeof(CK_BBOOL) },
- { CKA_SENSITIVE, attrs_priv[priv_en_cka_sensitive].bool, sizeof(CK_BBOOL) },
- { CKA_SIGN, attrs_priv[priv_en_cka_sign].bool, sizeof(CK_BBOOL) },
- { CKA_SIGN_RECOVER, attrs_priv[priv_en_cka_sign].bool, sizeof(CK_BBOOL) },
- { CKA_UNWRAP, attrs_priv[priv_en_cka_unwrap].bool, sizeof(CK_BBOOL) },
- { CKA_WRAP_WITH_TRUSTED, attrs_priv[priv_en_cka_wrap_with_trusted].bool, sizeof(CK_BBOOL) }
- };
-
- rv = self->p11->C_UnwrapKey(self->session, &wrapping_mech,
- unwrapping_key_object, wrapped_key,
- wrapped_key_len, template,
- sizeof(template) / sizeof(CK_ATTRIBUTE),
- &unwrapped_key_object);
- if (!check_return_value(rv, "import_wrapped_key: key unwrapping")) {
- GOTO_FAIL;
- }
-final:
- if (label != NULL)
- PyMem_Free(label);
-
- if (error)
- return NULL;
- return PyLong_FromUnsignedLong(unwrapped_key_object);
-
-}
-
-/*
- * Set object attributes
- */
-static PyObject *P11_Helper_set_attribute(P11_Helper *self, PyObject *args,
- PyObject *kwds) {
- PyObject *ret = Py_None;
- PyObject *value = NULL;
- CK_ULONG object = 0;
- unsigned long attr = 0;
- CK_ATTRIBUTE attribute;
- CK_RV rv;
- Py_ssize_t len = 0;
- CK_UTF8CHAR *label = NULL;
- int error = 0;
-
- static char *kwlist[] = { "key_object", "attr", "value", NULL };
- if (!PyArg_ParseTupleAndKeywords
- (args, kwds, "kkO|", kwlist, &object, &attr, &value)) {
- return NULL;
- }
-
- attribute.type = attr;
- switch (attr) {
- case CKA_ALWAYS_AUTHENTICATE:
- case CKA_ALWAYS_SENSITIVE:
- case CKA_COPYABLE:
- case CKA_ENCRYPT:
- case CKA_EXTRACTABLE:
- case CKA_DECRYPT:
- case CKA_DERIVE:
- case CKA_LOCAL:
- case CKA_MODIFIABLE:
- case CKA_NEVER_EXTRACTABLE:
- case CKA_PRIVATE:
- case CKA_SENSITIVE:
- case CKA_SIGN:
- case CKA_SIGN_RECOVER:
- case CKA_TOKEN:
- case CKA_TRUSTED:
- case CKA_UNWRAP:
- case CKA_VERIFY:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- case CKA_WRAP_WITH_TRUSTED:
- attribute.pValue = PyObject_IsTrue(value) ? &true : &false;
- attribute.ulValueLen = sizeof(CK_BBOOL);
- break;
- case CKA_ID:
- if (!PyBytes_Check(value)) {
- PyErr_SetString(ipap11helperError, "Bytestring value expected");
- GOTO_FAIL;
- }
- if (PyBytes_AsStringAndSize(value, (char **) &attribute.pValue,
- &len) == -1) {
- GOTO_FAIL;
- }
- attribute.ulValueLen = len;
- break;
- case CKA_LABEL:
- if (!PyUnicode_Check(value)) {
- PyErr_SetString(ipap11helperError, "Unicode value expected");
- GOTO_FAIL;
- }
- label = unicode_to_char_array(value, &len);
- /* check for conversion error */
- if (label == NULL)
- GOTO_FAIL;
- attribute.pValue = label;
- attribute.ulValueLen = len;
- break;
- case CKA_KEY_TYPE:
- if (!PyInt_Check(value)) {
- PyErr_SetString(ipap11helperError, "Integer value expected");
- GOTO_FAIL;
- }
- unsigned long lv = PyInt_AsUnsignedLongMask(value);
- attribute.pValue = &lv;
- attribute.ulValueLen = sizeof(unsigned long);
- break;
- default:
- PyErr_SetString(ipap11helperError, "Unknown attribute");
- GOTO_FAIL;
- }
-
- CK_ATTRIBUTE template[] = { attribute };
-
- rv = self->p11->C_SetAttributeValue(self->session, object, template,
- sizeof(template) / sizeof(CK_ATTRIBUTE));
- if (!check_return_value(rv, "set_attribute"))
- GOTO_FAIL;
-
-final:
- if (label != NULL)
- PyMem_Free(label);
- Py_XINCREF(ret);
-
- if (error)
- return NULL;
- return ret;
-}
-
-/*
- * Get object attributes
- */
-static PyObject *P11_Helper_get_attribute(P11_Helper *self, PyObject *args,
- PyObject *kwds) {
- PyObject *ret = NULL;
- void *value = NULL;
- CK_ULONG object = 0;
- unsigned long attr = 0;
- CK_ATTRIBUTE attribute;
- CK_RV rv;
- int error = 0;
-
- static char *kwlist[] = { "key_object", "attr", NULL };
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "kk|", kwlist, &object,
- &attr)) {
- return NULL;
- }
-
- attribute.type = attr;
- attribute.pValue = NULL_PTR;
- attribute.ulValueLen = 0;
- CK_ATTRIBUTE template[] = { attribute };
-
- rv = self->p11->C_GetAttributeValue(self->session, object, template,
- sizeof(template) / sizeof(CK_ATTRIBUTE));
- // attribute doesn't exists
- if (rv == CKR_ATTRIBUTE_TYPE_INVALID
- || template[0].ulValueLen == (unsigned long) -1) {
- PyErr_SetString(ipap11helperNotFound, "attribute does not exist");
- GOTO_FAIL;
- }
- if (!check_return_value(rv, "get_attribute init")) {
- GOTO_FAIL;
- }
- value = PyMem_Malloc(template[0].ulValueLen);
- if (value == NULL) {
- PyErr_NoMemory();
- GOTO_FAIL;
- }
- template[0].pValue = value;
-
- rv = self->p11->C_GetAttributeValue(self->session, object, template,
- sizeof(template) / sizeof(CK_ATTRIBUTE));
- if (!check_return_value(rv, "get_attribute")) {
- GOTO_FAIL;
- }
-
- switch (attr) {
- case CKA_ALWAYS_AUTHENTICATE:
- case CKA_ALWAYS_SENSITIVE:
- case CKA_COPYABLE:
- case CKA_ENCRYPT:
- case CKA_EXTRACTABLE:
- case CKA_DECRYPT:
- case CKA_DERIVE:
- case CKA_LOCAL:
- case CKA_MODIFIABLE:
- case CKA_NEVER_EXTRACTABLE:
- case CKA_PRIVATE:
- case CKA_SENSITIVE:
- case CKA_SIGN:
- case CKA_SIGN_RECOVER:
- case CKA_TOKEN:
- case CKA_TRUSTED:
- case CKA_UNWRAP:
- case CKA_VERIFY:
- case CKA_VERIFY_RECOVER:
- case CKA_WRAP:
- case CKA_WRAP_WITH_TRUSTED:
- /* booleans */
- ret = PyBool_FromLong(*(CK_BBOOL *) value);
- break;
- case CKA_LABEL:
- /* unicode string */
- ret = char_array_to_unicode(value, template[0].ulValueLen);
- break;
- case CKA_MODULUS:
- case CKA_PUBLIC_EXPONENT:
- case CKA_ID:
- /* byte arrays */
- ret = string_to_pybytes_or_none(value, template[0].ulValueLen);
- break;
- case CKA_KEY_TYPE:
- /* unsigned long */
- ret = Py_BuildValue("k", *(unsigned long *) value);
- break;
- default:
- PyErr_SetString(ipap11helperError, "Unknown attribute");
- GOTO_FAIL;
- }
-
-final:
- if (value != NULL)
- PyMem_Free(value);
-
- if (error)
- return NULL;
- return ret;
-}
-
-static PyMethodDef P11_Helper_methods[] = {
- {
- "finalize",
- (PyCFunction) P11_Helper_finalize,
- METH_NOARGS,
- "Finalize operations with pkcs11 library"
- },
- {
- "generate_master_key",
- (PyCFunction) P11_Helper_generate_master_key,
- METH_VARARGS | METH_KEYWORDS,
- "Generate master key"
- },
- {
- "generate_replica_key_pair",
- (PyCFunction) P11_Helper_generate_replica_key_pair,
- METH_VARARGS | METH_KEYWORDS,
- "Generate replica key pair"
- },
- {
- "find_keys",
- (PyCFunction) P11_Helper_find_keys,
- METH_VARARGS | METH_KEYWORDS,
- "Find keys"
- },
- {
- "delete_key",
- (PyCFunction) P11_Helper_delete_key,
- METH_VARARGS | METH_KEYWORDS,
- "Delete key"
- },
- {
- "export_public_key",
- (PyCFunction) P11_Helper_export_public_key,
- METH_VARARGS | METH_KEYWORDS,
- "Export public key"
- },
- {
- "import_public_key",
- (PyCFunction) P11_Helper_import_public_key,
- METH_VARARGS | METH_KEYWORDS,
- "Import public key"
- },
- {
- "export_wrapped_key",
- (PyCFunction) P11_Helper_export_wrapped_key,
- METH_VARARGS | METH_KEYWORDS,
- "Export wrapped private key"
- },
- {
- "import_wrapped_secret_key",
- (PyCFunction) P11_Helper_import_wrapped_secret_key,
- METH_VARARGS | METH_KEYWORDS,
- "Import wrapped secret key"
- },
- {
- "import_wrapped_private_key",
- (PyCFunction) P11_Helper_import_wrapped_private_key,
- METH_VARARGS | METH_KEYWORDS,
- "Import wrapped private key"
- },
- {
- "set_attribute",
- (PyCFunction) P11_Helper_set_attribute,
- METH_VARARGS | METH_KEYWORDS,
- "Set attribute"
- },
- {
- "get_attribute",
- (PyCFunction) P11_Helper_get_attribute,
- METH_VARARGS | METH_KEYWORDS,
- "Get attribute"
- },
- {
- /* Sentinel */
- NULL
- }
-};
-
-static PyTypeObject P11_HelperType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_ipap11helper.P11_Helper", /* tp_name */
- sizeof(P11_Helper), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor) P11_Helper_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- "P11_Helper objects", /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- P11_Helper_methods, /* tp_methods */
- P11_Helper_members, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc) P11_Helper_init, /* tp_init */
- 0, /* tp_alloc */
- P11_Helper_new, /* tp_new */
-};
-
-static PyMethodDef module_methods[] = {
- { NULL } /* Sentinel */
-};
-
-#define MODULE_DOC PyDoc_STR("Example module that creates an extension type.")
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- .m_name = "_ipap11helper",
- .m_doc = MODULE_DOC,
- .m_size = -1,
- .m_methods = module_methods,
-};
-#endif
-
-PyObject * module_init(void);
-PyObject * module_init(void) {
- PyObject *m;
-
- if (PyType_Ready(&P11_HelperType) < 0)
- return NULL;
-
- /*
- * Setting up P11_Helper module
- */
-#if PY_MAJOR_VERSION >= 3
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_ipap11helper", module_methods, MODULE_DOC);
-#endif
-
- if (m == NULL)
- return NULL;
-
- /*
- * Setting up P11_Helper
- */
- Py_INCREF(&P11_HelperType);
- PyModule_AddObject(m, "P11_Helper", (PyObject *) &P11_HelperType);
-
- /*
- * Setting up P11_Helper Exceptions
- */
- ipap11helperException = PyErr_NewException("_ipap11helper.Exception", NULL,
- NULL);
- Py_INCREF(ipap11helperException);
- PyModule_AddObject(m, "Exception", ipap11helperException);
-
- ipap11helperError = PyErr_NewException("_ipap11helper.Error",
- ipap11helperException, NULL);
- Py_INCREF(ipap11helperError);
- PyModule_AddObject(m, "Error", ipap11helperError);
-
- ipap11helperNotFound = PyErr_NewException("_ipap11helper.NotFound",
- ipap11helperException, NULL);
- Py_INCREF(ipap11helperNotFound);
- PyModule_AddObject(m, "NotFound", ipap11helperNotFound);
-
- ipap11helperDuplicationError =
- PyErr_NewException("_ipap11helper.DuplicationError",
- ipap11helperException, NULL);
- Py_INCREF(ipap11helperDuplicationError);
- PyModule_AddObject(m, "DuplicationError", ipap11helperDuplicationError);
-
- /**
- * Setting up module attributes
- */
-
- /* Key Classes */
- PyModule_AddIntConstant(m, "KEY_CLASS_PUBLIC_KEY", CKO_PUBLIC_KEY);
- PyModule_AddIntConstant(m, "KEY_CLASS_PRIVATE_KEY", CKO_PRIVATE_KEY);
- PyModule_AddIntConstant(m, "KEY_CLASS_SECRET_KEY", CKO_SECRET_KEY);
-
- /* Key types */
- PyModule_AddIntConstant(m, "KEY_TYPE_RSA", CKK_RSA);
- PyModule_AddIntConstant(m, "KEY_TYPE_AES", CKK_AES);
-
- /* Wrapping mech type */
- PyModule_AddIntConstant(m, "MECH_RSA_PKCS", CKM_RSA_PKCS);
- PyModule_AddIntConstant(m, "MECH_RSA_PKCS_OAEP", CKM_RSA_PKCS_OAEP);
- PyModule_AddIntConstant(m, "MECH_AES_KEY_WRAP", CKM_AES_KEY_WRAP);
- PyModule_AddIntConstant(m, "MECH_AES_KEY_WRAP_PAD", CKM_AES_KEY_WRAP_PAD);
-
- /* Key attributes */
- PyModule_AddIntMacro(m, CKA_ALWAYS_AUTHENTICATE);
- PyModule_AddIntMacro(m, CKA_ALWAYS_SENSITIVE);
- PyModule_AddIntMacro(m, CKA_COPYABLE);
- PyModule_AddIntMacro(m, CKA_DECRYPT);
- PyModule_AddIntMacro(m, CKA_DERIVE);
- PyModule_AddIntMacro(m, CKA_ENCRYPT);
- PyModule_AddIntMacro(m, CKA_EXTRACTABLE);
- PyModule_AddIntMacro(m, CKA_ID);
- PyModule_AddIntMacro(m, CKA_KEY_TYPE);
- PyModule_AddIntMacro(m, CKA_LOCAL);
- PyModule_AddIntMacro(m, CKA_MODIFIABLE);
- PyModule_AddIntMacro(m, CKA_MODULUS);
- PyModule_AddIntMacro(m, CKA_NEVER_EXTRACTABLE);
- PyModule_AddIntMacro(m, CKA_PRIVATE);
- PyModule_AddIntMacro(m, CKA_PUBLIC_EXPONENT);
- PyModule_AddIntMacro(m, CKA_SENSITIVE);
- PyModule_AddIntMacro(m, CKA_SIGN);
- PyModule_AddIntMacro(m, CKA_SIGN_RECOVER);
- PyModule_AddIntMacro(m, CKA_TRUSTED);
- PyModule_AddIntMacro(m, CKA_VERIFY);
- PyModule_AddIntMacro(m, CKA_VERIFY_RECOVER);
- PyModule_AddIntMacro(m, CKA_UNWRAP);
- PyModule_AddIntMacro(m, CKA_WRAP);
- PyModule_AddIntMacro(m, CKA_WRAP_WITH_TRUSTED);
- PyModule_AddIntMacro(m, CKA_TOKEN);
- PyModule_AddIntMacro(m, CKA_LABEL);
-
- return m;
-}
-
-
-#if PY_MAJOR_VERSION >= 3
-PyMODINIT_FUNC PyInit__ipap11helper(void);
-PyMODINIT_FUNC PyInit__ipap11helper(void)
-{
- return module_init();
-}
-#else
-void init_ipap11helper(void);
-void init_ipap11helper(void)
-{
- module_init();
-}
-#endif
diff --git a/ipapython/ipap11helper/setup.py b/ipapython/ipap11helper/setup.py
deleted file mode 100644
index 9743ac229..000000000
--- a/ipapython/ipap11helper/setup.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/python2
-#
-# Copyright (C) 2014 FreeIPA Contributors see COPYING for license
-#
-
-from distutils.core import setup, Extension
-from distutils.sysconfig import get_python_inc
-import sys
-import os
-
-python_header = os.path.join(get_python_inc(plat_specific=0), 'Python.h')
-if not os.path.exists(python_header):
- sys.exit("Cannot find Python development packages that provide Python.h")
-
-module = Extension('_ipap11helper',
- define_macros = [],
- include_dirs = [],
- libraries = ['dl', 'crypto', 'p11-kit'],
- library_dirs = [],
- extra_compile_args = [
- '-std=c99',
- '-I/usr/include/p11-kit-1',
- '-ggdb3',
- '-O2',
- '-W',
- '-Wall',
- '-Wno-unused-parameter',
- '-Wbad-function-cast',
- '-Wextra',
- ],
- sources = ['p11helper.c', 'library.c'])
-
-setup(name='_ipap11helper',
- version='0.1',
- description='FreeIPA pkcs11 helper',
- author='Martin Basti, Petr Spacek',
- author_email='mbasti@redhat.com, pspacek@redhat.com',
- license='GPLv2+',
- url='http://www.freeipa.org',
- long_description="""
- FreeIPA pkcs11 key manipulation utils.
-""",
- ext_modules = [module])