Skip to content

Commit 1cf6785

Browse files
committed
Fix #164 - Add support for loading keys from engine (e.g. pkcs11).
1 parent 2c58d43 commit 1cf6785

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

Diff for: README.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ Check the `examples <https://xmlsec.readthedocs.io/en/latest/examples.html>`_ se
3737
Requirements
3838
************
3939
- ``libxml2 >= 2.9.1``
40-
- ``libxmlsec1 >= 1.2.18``
40+
- ``libxmlsec1 >= 1.2.33``
4141

4242
Install
4343
*******

Diff for: src/keys.c

+47
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,47 @@ static PyObject* PyXmlSec_KeyFromFile(PyObject* self, PyObject* args, PyObject*
185185
return NULL;
186186
}
187187

188+
static const char PyXmlSec_KeyFromEngine__doc__[] = \
189+
"from_engine(engine_and_key_id) -> xmlsec.Key\n"
190+
"Loads PKI key from an engine.\n\n"
191+
":param engine_and_key_id: engine and key id, i.e. 'pkcs11;pkcs11:token=XmlsecToken;object=XmlsecKey;pin-value=password'\n"
192+
":type engine_and_key_id: :class:`str`, "
193+
":return: pointer to newly created key\n"
194+
":rtype: :class:`~xmlsec.Key`";
195+
static PyObject* PyXmlSec_KeyFromEngine(PyObject* self, PyObject* args, PyObject* kwargs) {
196+
static char *kwlist[] = {"engine_and_key_id", NULL};
197+
198+
const char* engine_and_key_id = NULL;
199+
PyXmlSec_Key* key = NULL;
200+
201+
PYXMLSEC_DEBUG("load key from engine - start");
202+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:from_engine", kwlist, &engine_and_key_id)) {
203+
goto ON_FAIL;
204+
}
205+
206+
if ((key = PyXmlSec_NewKey1((PyTypeObject*)self)) == NULL) goto ON_FAIL;
207+
208+
Py_BEGIN_ALLOW_THREADS;
209+
key->handle = xmlSecCryptoAppKeyLoad(engine_and_key_id, xmlSecKeyDataFormatEngine, NULL, xmlSecCryptoAppGetDefaultPwdCallback(),
210+
(void*)engine_and_key_id);
211+
Py_END_ALLOW_THREADS;
212+
213+
if (key->handle == NULL) {
214+
PyXmlSec_SetLastError("cannot read key");
215+
goto ON_FAIL;
216+
}
217+
218+
key->is_own = 1;
219+
220+
PYXMLSEC_DEBUG("load key from engine - ok");
221+
return (PyObject*)key;
222+
223+
ON_FAIL:
224+
PYXMLSEC_DEBUG("load key from engine - fail");
225+
Py_XDECREF(key);
226+
return NULL;
227+
}
228+
188229
static const char PyXmlSec_KeyGenerate__doc__[] = \
189230
"generate(klass, size, type) -> xmlsec.Key\n"
190231
"Generates key of kind ``klass`` with ``size`` and ``type``.\n\n"
@@ -494,6 +535,12 @@ static PyMethodDef PyXmlSec_KeyMethods[] = {
494535
METH_CLASS|METH_VARARGS|METH_KEYWORDS,
495536
PyXmlSec_KeyFromFile__doc__
496537
},
538+
{
539+
"from_engine",
540+
(PyCFunction)PyXmlSec_KeyFromEngine,
541+
METH_CLASS|METH_VARARGS|METH_KEYWORDS,
542+
PyXmlSec_KeyFromEngine__doc__
543+
},
497544
{
498545
"generate",
499546
(PyCFunction)PyXmlSec_KeyGenerate,

Diff for: src/xmlsec/__init__.pyi

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class Key:
4949
@classmethod
5050
def from_file(cls: type[Self], file: GenericPath[AnyStr] | IO[AnyStr], format: int, password: str | None = ...) -> Self: ...
5151
@classmethod
52+
def from_engine(cls: type[Self], engine_and_key_id: AnyStr) -> Self: ...
53+
@classmethod
5254
def from_memory(cls: type[Self], data: AnyStr, format: int, password: str | None = ...) -> Self: ...
5355
@classmethod
5456
def generate(cls: type[Self], klass: KeyData, size: int, type: int) -> Self: ...

0 commit comments

Comments
 (0)