blob: e9f2553f1ca6e9e27169c75f930a4d43a90b96fe [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001/*
2 * netscape_spki.c
3 *
4 * Copyright (C) Tollef Fog Heen 2003
5 *
6 * Netscape SPKI handling, thin wrapper
7 */
8#include <Python.h>
9#define crypto_MODULE
10#include "crypto.h"
11
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050012/*
13 * Constructor for Nestcape_SPKI, never called by Python code directly
14 *
15 * Arguments: name - A "real" NetscapeSPKI object
16 * dealloc - Boolean value to specify whether the destructor should
17 * free the "real" NetscapeSPKI object
18 * Returns: The newly created NetscapeSPKI object
19 */
20crypto_NetscapeSPKIObj *
21crypto_NetscapeSPKI_New(NETSCAPE_SPKI *name, int dealloc)
22{
23 crypto_NetscapeSPKIObj *self;
24
25 self = PyObject_New(crypto_NetscapeSPKIObj, &crypto_NetscapeSPKI_Type);
26
27 if (self == NULL)
28 return NULL;
29
30 self->netscape_spki = name;
31 self->dealloc = dealloc;
32
33 return self;
34}
35
36/*
37 * Deallocate the memory used by the NetscapeSPKI object
38 *
39 * Arguments: self - The NetscapeSPKI object
40 * Returns: None
41 */
42static void
43crypto_NetscapeSPKI_dealloc(crypto_NetscapeSPKIObj *self)
44{
45 /* Sometimes we don't have to dealloc this */
46 if (self->dealloc)
47 NETSCAPE_SPKI_free(self->netscape_spki);
48
49 PyObject_Del(self);
50}
51
52static char crypto_NetscapeSPKI_sign_doc[] = "\n\
53Sign the certificate request using the supplied key and digest\n\
54\n\
55Arguments: self - The NetscapeSPKI object\n\
56 args - The Python argument tuple, should be:\n\
57 pkey - The key to sign with\n\
58 digest - The message digest to use\n\
59Returns: None\n\
60";
61
62static PyObject *
63crypto_NetscapeSPKI_sign(crypto_NetscapeSPKIObj *self, PyObject *args)
64{
65 crypto_PKeyObj *pkey;
66 char *digest_name;
67 const EVP_MD *digest;
68
69 if (!PyArg_ParseTuple(args, "O!s:sign", &crypto_PKey_Type, &pkey,
70 &digest_name))
71 return NULL;
72
73 if ((digest = EVP_get_digestbyname(digest_name)) == NULL)
74 {
75 PyErr_SetString(PyExc_ValueError, "No such digest method");
76 return NULL;
77 }
78
79 if (!NETSCAPE_SPKI_sign(self->netscape_spki, pkey->pkey, digest))
80 {
81 exception_from_error_queue();
82 return NULL;
83 }
84
85 Py_INCREF(Py_None);
86 return Py_None;
87}
88
89static char crypto_NetscapeSPKI_verify_doc[] = "\n\
90Verifies a certificate request using the supplied public key\n\
91 \n\
92Arguments: self - NetscapeSPKI object\n\
93 args - The Python argument tuple, should be:\n\
94 key - a public key\n\
95Returns: True, if the signature is correct, 0 otherwise.\n\
96";
97
98PyObject *
99crypto_NetscapeSPKI_verify(crypto_NetscapeSPKIObj *self, PyObject *args)
100{
101 crypto_PKeyObj *pkey;
102 int answer;
103
104 if (!PyArg_ParseTuple(args, "O!:verify", &crypto_PKey_Type, &pkey))
105 return NULL;
106
107 if ((answer = NETSCAPE_SPKI_verify(self->netscape_spki, pkey->pkey)) < 0)
108 {
109 exception_from_error_queue();
110 return NULL;
111 }
112
113 return PyInt_FromLong((long)answer);
114}
115
116static char crypto_NetscapeSPKI_b64_encode_doc[] = "\n\
117Generate a base64 encoded string from an SPKI\n\
118 \n\
119Arguments: self - NetscapeSPKI object\n\
120 args - The Python argument tuple, should be empty\n\
121Returns: The base64 encoded string\n\
122";
123
124PyObject *
125crypto_NetscapeSPKI_b64_encode(crypto_NetscapeSPKIObj *self, PyObject *args)
126{
127 char *str;
128
129 if (!PyArg_ParseTuple(args, ":b64_encode"))
130 return NULL;
131
132 str = NETSCAPE_SPKI_b64_encode(self->netscape_spki);
133 return PyString_FromString(str);
134}
135
136
137static char crypto_NetscapeSPKI_get_pubkey_doc[] = "\n\
138Get the public key of the certificate\n\
139\n\
140Arguments: self - The NETSCAPE_SPKI object\n\
141 args - The Python argument tuple, should be empty\n\
142Returns: The public key\n\
143";
144
145static PyObject *
146crypto_NetscapeSPKI_get_pubkey(crypto_NetscapeSPKIObj *self, PyObject *args)
147{
148 crypto_PKeyObj *crypto_PKey_New(EVP_PKEY *, int);
149 EVP_PKEY *pkey;
150
151 if (!PyArg_ParseTuple(args, ":get_pubkey"))
152 return NULL;
153
154 if ((pkey = NETSCAPE_SPKI_get_pubkey(self->netscape_spki)) == NULL)
155 {
156 exception_from_error_queue();
157 return NULL;
158 }
159
160 return (PyObject *)crypto_PKey_New(pkey, 0);
161}
162
163static char crypto_NetscapeSPKI_set_pubkey_doc[] = "\n\
164Set the public key of the certificate\n\
165\n\
166Arguments: self - The Netscape SPKI object\n\
167 args - The Python argument tuple, should be:\n\
168 pkey - The public key\n\
169Returns: None\n\
170";
171
172static PyObject *
173crypto_NetscapeSPKI_set_pubkey(crypto_NetscapeSPKIObj *self, PyObject *args)
174{
175 crypto_PKeyObj *pkey;
176
177 if (!PyArg_ParseTuple(args, "O!:set_pubkey", &crypto_PKey_Type, &pkey))
178 return NULL;
179
180 if (!NETSCAPE_SPKI_set_pubkey(self->netscape_spki, pkey->pkey))
181 {
182 exception_from_error_queue();
183 return NULL;
184 }
185
186 Py_INCREF(Py_None);
187 return Py_None;
188}
189
190/*
191 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
192 * { 'name', (PyCFunction)crypto_NetscapeSPKI_name, METH_VARARGS }
193 * for convenience
194 */
195#define ADD_METHOD(name) \
196 { #name, (PyCFunction)crypto_NetscapeSPKI_##name, METH_VARARGS, crypto_NetscapeSPKI_##name##_doc }
197static PyMethodDef crypto_NetscapeSPKI_methods[] =
198{
199 ADD_METHOD(get_pubkey),
200 ADD_METHOD(set_pubkey),
201 ADD_METHOD(b64_encode),
202 ADD_METHOD(sign),
203 ADD_METHOD(verify),
204 { NULL, NULL }
205};
206#undef ADD_METHOD
207
208/*
209 * Find attribute
210 *
211 * Arguments: self - The NetscapeSPKI object
212 * name - The attribute name
213 * Returns: A Python object for the attribute, or NULL if something went
214 * wrong
215 */
216static PyObject *
217crypto_NetscapeSPKI_getattr(crypto_NetscapeSPKIObj *self, char *name)
218{
219 return Py_FindMethod(crypto_NetscapeSPKI_methods, (PyObject *)self, name);
220}
221
222PyTypeObject crypto_NetscapeSPKI_Type = {
223 PyObject_HEAD_INIT(NULL)
224 0,
225 "NetscapeSPKI",
226 sizeof(crypto_NetscapeSPKIObj),
227 0,
228 (destructor)crypto_NetscapeSPKI_dealloc,
229 NULL, /* print */
230 (getattrfunc)crypto_NetscapeSPKI_getattr,
231 NULL, /* setattr */
232 NULL, /* compare */
233 NULL, /* repr */
234 NULL, /* as_number */
235 NULL, /* as_sequence */
236 NULL, /* as_mapping */
237 NULL /* hash */
238};
239
240
241/*
242 * Initialize the X509Name part of the crypto module
243 *
244 * Arguments: dict - The crypto module dictionary
245 * Returns: None
246 */
247int
248init_crypto_netscape_spki(PyObject *dict)
249{
250 crypto_NetscapeSPKI_Type.ob_type = &PyType_Type;
251 Py_INCREF(&crypto_NetscapeSPKI_Type);
252 PyDict_SetItemString(dict, "NetscapeSPKIType", (PyObject *)&crypto_NetscapeSPKI_Type);
253 return 1;
254}