blob: a0796cb8de12eadb6aedc3820ecef83663afef3d [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\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040055@param pkey: The key to sign with\n\
56@param digest: The message digest to use\n\
57@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050058";
59
60static PyObject *
61crypto_NetscapeSPKI_sign(crypto_NetscapeSPKIObj *self, PyObject *args)
62{
63 crypto_PKeyObj *pkey;
64 char *digest_name;
65 const EVP_MD *digest;
66
67 if (!PyArg_ParseTuple(args, "O!s:sign", &crypto_PKey_Type, &pkey,
68 &digest_name))
69 return NULL;
70
71 if ((digest = EVP_get_digestbyname(digest_name)) == NULL)
72 {
73 PyErr_SetString(PyExc_ValueError, "No such digest method");
74 return NULL;
75 }
76
77 if (!NETSCAPE_SPKI_sign(self->netscape_spki, pkey->pkey, digest))
78 {
79 exception_from_error_queue();
80 return NULL;
81 }
82
83 Py_INCREF(Py_None);
84 return Py_None;
85}
86
87static char crypto_NetscapeSPKI_verify_doc[] = "\n\
88Verifies a certificate request using the supplied public key\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040089\n\
90@param key: a public key\n\
91@return: True if the signature is correct, False otherwise.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050092";
93
94PyObject *
95crypto_NetscapeSPKI_verify(crypto_NetscapeSPKIObj *self, PyObject *args)
96{
97 crypto_PKeyObj *pkey;
98 int answer;
99
100 if (!PyArg_ParseTuple(args, "O!:verify", &crypto_PKey_Type, &pkey))
101 return NULL;
102
103 if ((answer = NETSCAPE_SPKI_verify(self->netscape_spki, pkey->pkey)) < 0)
104 {
105 exception_from_error_queue();
106 return NULL;
107 }
108
109 return PyInt_FromLong((long)answer);
110}
111
112static char crypto_NetscapeSPKI_b64_encode_doc[] = "\n\
113Generate a base64 encoded string from an SPKI\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400114\n\
115@return: The base64 encoded string\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500116";
117
118PyObject *
119crypto_NetscapeSPKI_b64_encode(crypto_NetscapeSPKIObj *self, PyObject *args)
120{
121 char *str;
122
123 if (!PyArg_ParseTuple(args, ":b64_encode"))
124 return NULL;
125
126 str = NETSCAPE_SPKI_b64_encode(self->netscape_spki);
127 return PyString_FromString(str);
128}
129
130
131static char crypto_NetscapeSPKI_get_pubkey_doc[] = "\n\
132Get the public key of the certificate\n\
133\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400134@return: The public key\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500135";
136
137static PyObject *
138crypto_NetscapeSPKI_get_pubkey(crypto_NetscapeSPKIObj *self, PyObject *args)
139{
140 crypto_PKeyObj *crypto_PKey_New(EVP_PKEY *, int);
141 EVP_PKEY *pkey;
142
143 if (!PyArg_ParseTuple(args, ":get_pubkey"))
144 return NULL;
145
146 if ((pkey = NETSCAPE_SPKI_get_pubkey(self->netscape_spki)) == NULL)
147 {
148 exception_from_error_queue();
149 return NULL;
150 }
151
152 return (PyObject *)crypto_PKey_New(pkey, 0);
153}
154
155static char crypto_NetscapeSPKI_set_pubkey_doc[] = "\n\
156Set the public key of the certificate\n\
157\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400158@param pkey: The public key\n\
159@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500160";
161
162static PyObject *
163crypto_NetscapeSPKI_set_pubkey(crypto_NetscapeSPKIObj *self, PyObject *args)
164{
165 crypto_PKeyObj *pkey;
166
167 if (!PyArg_ParseTuple(args, "O!:set_pubkey", &crypto_PKey_Type, &pkey))
168 return NULL;
169
170 if (!NETSCAPE_SPKI_set_pubkey(self->netscape_spki, pkey->pkey))
171 {
172 exception_from_error_queue();
173 return NULL;
174 }
175
176 Py_INCREF(Py_None);
177 return Py_None;
178}
179
180/*
181 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
182 * { 'name', (PyCFunction)crypto_NetscapeSPKI_name, METH_VARARGS }
183 * for convenience
184 */
185#define ADD_METHOD(name) \
186 { #name, (PyCFunction)crypto_NetscapeSPKI_##name, METH_VARARGS, crypto_NetscapeSPKI_##name##_doc }
187static PyMethodDef crypto_NetscapeSPKI_methods[] =
188{
189 ADD_METHOD(get_pubkey),
190 ADD_METHOD(set_pubkey),
191 ADD_METHOD(b64_encode),
192 ADD_METHOD(sign),
193 ADD_METHOD(verify),
194 { NULL, NULL }
195};
196#undef ADD_METHOD
197
198/*
199 * Find attribute
200 *
201 * Arguments: self - The NetscapeSPKI object
202 * name - The attribute name
203 * Returns: A Python object for the attribute, or NULL if something went
204 * wrong
205 */
206static PyObject *
207crypto_NetscapeSPKI_getattr(crypto_NetscapeSPKIObj *self, char *name)
208{
209 return Py_FindMethod(crypto_NetscapeSPKI_methods, (PyObject *)self, name);
210}
211
212PyTypeObject crypto_NetscapeSPKI_Type = {
213 PyObject_HEAD_INIT(NULL)
214 0,
215 "NetscapeSPKI",
216 sizeof(crypto_NetscapeSPKIObj),
217 0,
218 (destructor)crypto_NetscapeSPKI_dealloc,
219 NULL, /* print */
220 (getattrfunc)crypto_NetscapeSPKI_getattr,
221 NULL, /* setattr */
222 NULL, /* compare */
223 NULL, /* repr */
224 NULL, /* as_number */
225 NULL, /* as_sequence */
226 NULL, /* as_mapping */
227 NULL /* hash */
228};
229
230
231/*
232 * Initialize the X509Name part of the crypto module
233 *
234 * Arguments: dict - The crypto module dictionary
235 * Returns: None
236 */
237int
238init_crypto_netscape_spki(PyObject *dict)
239{
240 crypto_NetscapeSPKI_Type.ob_type = &PyType_Type;
241 Py_INCREF(&crypto_NetscapeSPKI_Type);
242 PyDict_SetItemString(dict, "NetscapeSPKIType", (PyObject *)&crypto_NetscapeSPKI_Type);
243 return 1;
244}