Initial import to Tizen
[profile/ivi/python-pyOpenSSL.git] / OpenSSL / crypto / netscape_spki.c
1 /*
2  * netscape_spki.c
3  *
4  * Copyright (C) Tollef Fog Heen
5  * See LICENSE for details.
6  *
7  * Netscape SPKI handling, thin wrapper
8  */
9 #include <Python.h>
10 #define crypto_MODULE
11 #include "crypto.h"
12
13 /*
14  * Constructor for Nestcape_SPKI, never called by Python code directly
15  *
16  * Arguments: name    - A "real" NetscapeSPKI object
17  *            dealloc - Boolean value to specify whether the destructor should
18  *                      free the "real" NetscapeSPKI object
19  * Returns:   The newly created NetscapeSPKI object
20  */
21 crypto_NetscapeSPKIObj *
22 crypto_NetscapeSPKI_New(NETSCAPE_SPKI *name, int dealloc)
23 {
24     crypto_NetscapeSPKIObj *self;
25
26     self = PyObject_New(crypto_NetscapeSPKIObj, &crypto_NetscapeSPKI_Type);
27
28     if (self == NULL)
29         return NULL;
30
31     self->netscape_spki = name;
32     self->dealloc = dealloc;
33
34     return self;
35 }
36
37
38 static char crypto_NetscapeSPKI_doc[] = "\n\
39 NetscapeSPKI([enc]) -> NetscapeSPKI instance\n\
40 \n\
41 @param enc: Base64 encoded NetscapeSPKI object.\n\
42 @type enc: C{str}\n\
43 @return: The NetscapeSPKI object\n\
44 ";
45
46 static PyObject *
47 crypto_NetscapeSPKI_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
48     char *enc = NULL;
49     int enc_len = -1;
50     NETSCAPE_SPKI *spki;
51
52     if (!PyArg_ParseTuple(args, "|s#:NetscapeSPKI", &enc, &enc_len))
53         return NULL;
54
55     if (enc_len >= 0)
56         spki = NETSCAPE_SPKI_b64_decode(enc, enc_len);
57     else
58         spki = NETSCAPE_SPKI_new();
59     if (spki == NULL)
60     {
61         exception_from_error_queue(crypto_Error);
62         return NULL;
63     }
64     return (PyObject *)crypto_NetscapeSPKI_New(spki, 1);
65 }
66
67
68 /*
69  * Deallocate the memory used by the NetscapeSPKI object
70  *
71  * Arguments: self - The NetscapeSPKI object
72  * Returns:   None
73  */
74 static void
75 crypto_NetscapeSPKI_dealloc(crypto_NetscapeSPKIObj *self)
76 {
77     /* Sometimes we don't have to dealloc this */
78     if (self->dealloc)
79         NETSCAPE_SPKI_free(self->netscape_spki);
80
81     PyObject_Del(self);
82 }
83
84 static char crypto_NetscapeSPKI_sign_doc[] = "\n\
85 Sign the certificate request using the supplied key and digest\n\
86 \n\
87 @param pkey: The key to sign with\n\
88 @param digest: The message digest to use\n\
89 @return: None\n\
90 ";
91
92 static PyObject *
93 crypto_NetscapeSPKI_sign(crypto_NetscapeSPKIObj *self, PyObject *args)
94 {
95     crypto_PKeyObj *pkey;
96     char *digest_name;
97     const EVP_MD *digest;
98
99     if (!PyArg_ParseTuple(args, "O!s:sign", &crypto_PKey_Type, &pkey,
100                           &digest_name))
101         return NULL;
102
103     if (pkey->only_public) {
104         PyErr_SetString(PyExc_ValueError, "Key has only public part");
105         return NULL;
106     }
107
108     if (!pkey->initialized) {
109         PyErr_SetString(PyExc_ValueError, "Key is uninitialized");
110         return NULL;
111     }
112
113     if ((digest = EVP_get_digestbyname(digest_name)) == NULL)
114     {
115         PyErr_SetString(PyExc_ValueError, "No such digest method");
116         return NULL;
117     }
118
119     if (!NETSCAPE_SPKI_sign(self->netscape_spki, pkey->pkey, digest))
120     {
121         exception_from_error_queue(crypto_Error);
122         return NULL;
123     }
124
125     Py_INCREF(Py_None);
126     return Py_None;
127 }
128
129 static char crypto_NetscapeSPKI_verify_doc[] = "\n\
130 Verifies a certificate request using the supplied public key\n\
131 \n\
132 @param key: a public key\n\
133 @return: True if the signature is correct.\n\
134 @raise OpenSSL.crypto.Error: If the signature is invalid or there is a\n\
135     problem verifying the signature.\n\
136 ";
137
138 PyObject *
139 crypto_NetscapeSPKI_verify(crypto_NetscapeSPKIObj *self, PyObject *args)
140 {
141     crypto_PKeyObj *pkey;
142     int answer;
143
144     if (!PyArg_ParseTuple(args, "O!:verify", &crypto_PKey_Type, &pkey)) {
145         return NULL;
146     }
147
148     if ((answer = NETSCAPE_SPKI_verify(self->netscape_spki, pkey->pkey)) <= 0) {
149         exception_from_error_queue(crypto_Error);
150         return NULL;
151     }
152
153     return PyLong_FromLong((long)answer);
154 }
155
156 static char crypto_NetscapeSPKI_b64_encode_doc[] = "\n\
157 Generate a base64 encoded string from an SPKI\n\
158 \n\
159 @return: The base64 encoded string\n\
160 ";
161
162 PyObject *
163 crypto_NetscapeSPKI_b64_encode(crypto_NetscapeSPKIObj *self, PyObject *args)
164 {
165     char *str;
166
167     if (!PyArg_ParseTuple(args, ":b64_encode"))
168         return NULL;
169
170     str = NETSCAPE_SPKI_b64_encode(self->netscape_spki);
171     return PyBytes_FromString(str);
172 }
173
174
175 static char crypto_NetscapeSPKI_get_pubkey_doc[] = "\n\
176 Get the public key of the certificate\n\
177 \n\
178 @return: The public key\n\
179 ";
180
181 static PyObject *
182 crypto_NetscapeSPKI_get_pubkey(crypto_NetscapeSPKIObj *self, PyObject *args)
183 {
184     crypto_PKeyObj *crypto_PKey_New(EVP_PKEY *, int);
185     EVP_PKEY *pkey;
186     crypto_PKeyObj *py_pkey;
187
188     if (!PyArg_ParseTuple(args, ":get_pubkey"))
189         return NULL;
190
191     if ((pkey = NETSCAPE_SPKI_get_pubkey(self->netscape_spki)) == NULL)
192     {
193         exception_from_error_queue(crypto_Error);
194         return NULL;
195     }
196
197     py_pkey = crypto_PKey_New(pkey, 1);
198     if (py_pkey != NULL) {
199         py_pkey->only_public = 1;
200     }
201     return (PyObject *)py_pkey;
202 }
203
204 static char crypto_NetscapeSPKI_set_pubkey_doc[] = "\n\
205 Set the public key of the certificate\n\
206 \n\
207 @param pkey: The public key\n\
208 @return: None\n\
209 ";
210
211 static PyObject *
212 crypto_NetscapeSPKI_set_pubkey(crypto_NetscapeSPKIObj *self, PyObject *args)
213 {
214     crypto_PKeyObj *pkey;
215
216     if (!PyArg_ParseTuple(args, "O!:set_pubkey", &crypto_PKey_Type, &pkey))
217         return NULL;
218
219     if (!NETSCAPE_SPKI_set_pubkey(self->netscape_spki, pkey->pkey))
220     {
221         exception_from_error_queue(crypto_Error);
222         return NULL;
223     }
224
225     Py_INCREF(Py_None);
226     return Py_None;
227 }
228
229 /*
230  * ADD_METHOD(name) expands to a correct PyMethodDef declaration
231  *   {  'name', (PyCFunction)crypto_NetscapeSPKI_name, METH_VARARGS }
232  * for convenience
233  */
234 #define ADD_METHOD(name)        \
235     { #name, (PyCFunction)crypto_NetscapeSPKI_##name, METH_VARARGS, crypto_NetscapeSPKI_##name##_doc }
236 static PyMethodDef crypto_NetscapeSPKI_methods[] =
237 {
238     ADD_METHOD(get_pubkey),
239     ADD_METHOD(set_pubkey),
240     ADD_METHOD(b64_encode),
241     ADD_METHOD(sign),
242     ADD_METHOD(verify),
243     { NULL, NULL }
244 };
245 #undef ADD_METHOD
246
247 PyTypeObject crypto_NetscapeSPKI_Type = {
248     PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
249     "NetscapeSPKI",
250     sizeof(crypto_NetscapeSPKIObj),
251     0,
252     (destructor)crypto_NetscapeSPKI_dealloc,
253     NULL, /* print */
254     NULL, /* getattr */
255     NULL, /* setattr */
256     NULL, /* compare */
257     NULL, /* repr */
258     NULL, /* as_number */
259     NULL, /* as_sequence */
260     NULL, /* as_mapping */
261     NULL,  /* hash */
262     NULL, /* call */
263     NULL, /* str */
264     NULL, /* getattro */
265     NULL, /* setattro */
266     NULL, /* as_buffer */
267     Py_TPFLAGS_DEFAULT,
268     crypto_NetscapeSPKI_doc, /* doc */
269     NULL, /* traverse */
270     NULL, /* clear */
271     NULL, /* tp_richcompare */
272     0, /* tp_weaklistoffset */
273     NULL, /* tp_iter */
274     NULL, /* tp_iternext */
275     crypto_NetscapeSPKI_methods, /* tp_methods */
276     NULL, /* tp_members */
277     NULL, /* tp_getset */
278     NULL, /* tp_base */
279     NULL, /* tp_dict */
280     NULL, /* tp_descr_get */
281     NULL, /* tp_descr_set */
282     0, /* tp_dictoffset */
283     NULL, /* tp_init */
284     NULL, /* tp_alloc */
285     crypto_NetscapeSPKI_new, /* tp_new */
286 };
287
288
289 /*
290  * Initialize the X509Name part of the crypto module
291  *
292  * Arguments: module - The crypto module
293  * Returns:   None
294  */
295 int
296 init_crypto_netscape_spki(PyObject *module) {
297     if (PyType_Ready(&crypto_NetscapeSPKI_Type) < 0) {
298         return 0;
299     }
300
301     if (PyModule_AddObject(module, "NetscapeSPKI", (PyObject *)&crypto_NetscapeSPKI_Type) != 0) {
302         return 0;
303     }
304
305     if (PyModule_AddObject(module, "NetscapeSPKIType", (PyObject *)&crypto_NetscapeSPKI_Type) != 0) {
306         return 0;
307     }
308
309     return 1;
310 }