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