4 * Copyright (C) AB Strakt
5 * Copyright (C) Jean-Paul Calderone
6 * See LICENSE for details.
8 * Public/rivate key handling code, mostly thin wrappers around OpenSSL.
9 * See the file RATIONALE for a short explanation of why this module was written.
17 * This is done every time something fails, so turning it into a macro is
21 * Returns: Doesn't return
25 exception_from_error_queue(crypto_Error); \
30 static char crypto_PKey_generate_key_doc[] = "\n\
31 Generate a key of a given type, with a given number of a bits\n\
33 @param type: The key type (TYPE_RSA or TYPE_DSA)\n\
34 @param bits: The number of bits\n\
39 crypto_PKey_generate_key(crypto_PKeyObj *self, PyObject *args)
45 if (!PyArg_ParseTuple(args, "ii:generate_key", &type, &bits))
52 PyErr_SetString(PyExc_ValueError, "Invalid number of bits");
55 if ((rsa = RSA_generate_key(bits, 0x10001, NULL, NULL)) == NULL)
57 if (!EVP_PKEY_assign_RSA(self->pkey, rsa))
62 if ((dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL)) == NULL)
64 if (!DSA_generate_key(dsa))
66 if (!EVP_PKEY_assign_DSA(self->pkey, dsa))
71 PyErr_SetString(crypto_Error, "No such key type");
75 self->initialized = 1;
80 static char crypto_PKey_bits_doc[] = "\n\
81 Returns the number of bits of the key\n\
83 @return: The number of bits of the key.\n\
87 crypto_PKey_bits(crypto_PKeyObj *self, PyObject *args)
89 if (!PyArg_ParseTuple(args, ":bits"))
92 return PyLong_FromLong(EVP_PKEY_bits(self->pkey));
95 static char crypto_PKey_type_doc[] = "\n\
96 Returns the type of the key\n\
98 @return: The type of the key.\n\
102 crypto_PKey_type(crypto_PKeyObj *self, PyObject *args)
104 if (!PyArg_ParseTuple(args, ":type"))
107 return PyLong_FromLong(self->pkey->type);
112 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
113 * { 'name', (PyCFunction)crypto_PKey_name, METH_VARARGS }
116 #define ADD_METHOD(name) \
117 { #name, (PyCFunction)crypto_PKey_##name, METH_VARARGS, crypto_PKey_##name##_doc }
118 static PyMethodDef crypto_PKey_methods[] =
120 ADD_METHOD(generate_key),
129 * Constructor for PKey objects, never called by Python code directly
131 * Arguments: pkey - A "real" EVP_PKEY object
132 * dealloc - Boolean value to specify whether the destructor should
133 * free the "real" EVP_PKEY object
134 * Returns: The newly created PKey object
137 crypto_PKey_New(EVP_PKEY *pkey, int dealloc)
139 crypto_PKeyObj *self;
141 self = PyObject_New(crypto_PKeyObj, &crypto_PKey_Type);
147 self->dealloc = dealloc;
148 self->only_public = 0;
151 * Heuristic. Most call-sites pass an initialized EVP_PKEY. Not
152 * necessarily the case that they will, though. That's part of why this is
155 self->initialized = 1;
160 static char crypto_PKey_doc[] = "\n\
161 PKey() -> PKey instance\n\
163 Create a new PKey object.\n\
165 @return: The PKey object\n\
168 crypto_PKey_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
169 crypto_PKeyObj *self;
171 if (!PyArg_ParseTuple(args, ":PKey")) {
175 self = crypto_PKey_New(EVP_PKEY_new(), 1);
177 self->initialized = 0;
180 return (PyObject *)self;
185 * Deallocate the memory used by the PKey object
187 * Arguments: self - The PKey object
191 crypto_PKey_dealloc(crypto_PKeyObj *self)
193 /* Sometimes we don't have to dealloc the "real" EVP_PKEY pointer ourselves */
195 EVP_PKEY_free(self->pkey);
200 PyTypeObject crypto_PKey_Type = {
201 PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
202 "OpenSSL.crypto.PKey",
203 sizeof(crypto_PKeyObj),
205 (destructor)crypto_PKey_dealloc,
211 NULL, /* as_number */
212 NULL, /* as_sequence */
213 NULL, /* as_mapping */
219 NULL, /* as_buffer */
221 crypto_PKey_doc, /* doc */
224 NULL, /* tp_richcompare */
225 0, /* tp_weaklistoffset */
227 NULL, /* tp_iternext */
228 crypto_PKey_methods, /* tp_methods */
229 NULL, /* tp_members */
230 NULL, /* tp_getset */
233 NULL, /* tp_descr_get */
234 NULL, /* tp_descr_set */
235 0, /* tp_dictoffset */
238 crypto_PKey_new, /* tp_new */
243 * Initialize the PKey part of the crypto sub module
245 * Arguments: module - The crypto module
249 init_crypto_pkey(PyObject *module)
251 if (PyType_Ready(&crypto_PKey_Type) < 0) {
255 if (PyModule_AddObject(module, "PKey", (PyObject *)&crypto_PKey_Type) != 0) {
259 if (PyModule_AddObject(module, "PKeyType", (PyObject *)&crypto_PKey_Type) != 0) {