blob: c1e1934db9941341326b1dcc29cd340ad5d88786 [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001/*
2 * context.c
3 *
4 * Copyright (C) AB Strakt 2001, All rights reserved
Jean-Paul Calderone8b63d452008-03-21 18:31:12 -04005 * Copyright (C) Jean-Paul Calderone 2008, All rights reserved
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05006 *
7 * SSL Context objects and their methods.
8 * See the file RATIONALE for a short explanation of why this module was written.
9 *
10 * Reviewed 2001-07-23
11 */
12#include <Python.h>
Jean-Paul Calderone12ea9a02008-02-22 12:24:39 -050013
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -050014#if PY_VERSION_HEX >= 0x02050000
15# define PYARG_PARSETUPLE_FORMAT const char
16#else
17# define PYARG_PARSETUPLE_FORMAT char
18#endif
19
Jean-Paul Calderone12ea9a02008-02-22 12:24:39 -050020#ifndef MS_WINDOWS
21# include <sys/socket.h>
22# include <netinet/in.h>
23# if !(defined(__BEOS__) || defined(__CYGWIN__))
24# include <netinet/tcp.h>
25# endif
26#else
27# include <winsock.h>
28# include <wincrypt.h>
29#endif
30
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050031#define SSL_MODULE
32#include "ssl.h"
33
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050034/*
35 * CALLBACKS
36 *
37 * Callbacks work like this: We provide a "global" callback in C which
38 * transforms the arguments into a Python argument tuple and calls the
39 * corresponding Python callback, and then parsing the return value back into
40 * things the C function can return.
41 *
42 * Three caveats:
43 * + How do we find the Context object where the Python callbacks are stored?
44 * + What about multithreading and execution frames?
45 * + What about Python callbacks that raise exceptions?
46 *
47 * The solution to the first issue is trivial if the callback provides
48 * "userdata" functionality. Since the only callbacks that don't provide
49 * userdata do provide a pointer to an SSL structure, we can associate an SSL
50 * object and a Connection one-to-one via the SSL_set/get_app_data()
51 * functions.
52 *
53 * The solution to the other issue is to rewrite the Py_BEGIN_ALLOW_THREADS
54 * macro allowing it (or rather a new macro) to specify where to save the
55 * thread state (in our case, as a member of the Connection/Context object) so
56 * we can retrieve it again before calling the Python callback.
57 */
58
59/*
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040060 * Globally defined passphrase callback. This is called from OpenSSL
61 * internally. The GIL will not be held when this function is invoked. It
62 * must not be held when the function returns.
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050063 *
64 * Arguments: buf - Buffer to store the returned passphrase in
65 * maxlen - Maximum length of the passphrase
66 * verify - If true, the passphrase callback should ask for a
67 * password twice and verify they're equal. If false, only
68 * ask once.
69 * arg - User data, always a Context object
70 * Returns: The length of the password if successful, 0 otherwise
71 */
72static int
73global_passphrase_callback(char *buf, int maxlen, int verify, void *arg)
74{
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040075 /*
76 * Initialize len here because we're always going to return it, and we
77 * might jump to the return before it gets initialized in any other way.
78 */
79 int len = 0;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050080 char *str;
81 PyObject *argv, *ret = NULL;
82 ssl_ContextObj *ctx = (ssl_ContextObj *)arg;
83
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040084 /*
85 * GIL isn't held yet. First things first - acquire it, or any Python API
86 * we invoke might segfault or blow up the sun. The reverse will be done
87 * before returning.
88 */
89 MY_END_ALLOW_THREADS(ctx->tstate);
90
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -040091 /* The Python callback is called with a (maxlen,verify,userdata) tuple */
92 argv = Py_BuildValue("(iiO)", maxlen, verify, ctx->passphrase_userdata);
93
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040094 /*
95 * XXX Didn't check argv to see if it was NULL. -exarkun
96 */
97 ret = PyEval_CallObject(ctx->passphrase_callback, argv);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050098 Py_DECREF(argv);
99
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400100 if (ret == NULL) {
101 /*
102 * XXX The callback raised an exception. At the very least, it should
103 * be printed out here. An *actual* solution would be to raise it up
104 * through OpenSSL. That might be a bit tricky, but it's probably
105 * possible. -exarkun
106 */
107 goto out;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500108 }
109
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400110 if (!PyObject_IsTrue(ret)) {
111 /*
112 * Returned "", or None, or something. Treat it as no passphrase.
113 */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500114 Py_DECREF(ret);
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400115 goto out;
116 }
117
118 if (!PyString_Check(ret)) {
119 /*
120 * XXX Returned something that wasn't a string. This is bogus. We
121 * should report an error or raise an exception (again, through OpenSSL
122 * - tricky). -exarkun
123 */
124 Py_DECREF(ret);
125 goto out;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500126 }
127
128 len = PyString_Size(ret);
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400129 if (len > maxlen) {
130 /*
131 * XXX Returned more than we said they were allowed to return. Report
132 * an error or raise an exception (tricky blah blah). -exarkun
133 */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500134 len = maxlen;
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400135 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500136
137 str = PyString_AsString(ret);
138 strncpy(buf, str, len);
139 Py_XDECREF(ret);
140
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400141 out:
142 /*
143 * This function is returning into OpenSSL. Release the GIL again.
144 */
145 MY_BEGIN_ALLOW_THREADS(ctx->tstate);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500146 return len;
147}
148
149/*
150 * Globally defined verify callback
151 *
152 * Arguments: ok - True everything is OK "so far", false otherwise
153 * x509_ctx - Contains the certificate being checked, the current
154 * error number and depth, and the Connection we're
155 * dealing with
156 * Returns: True if everything is okay, false otherwise
157 */
158static int
159global_verify_callback(int ok, X509_STORE_CTX *x509_ctx)
160{
161 PyObject *argv, *ret;
162 SSL *ssl;
163 ssl_ConnectionObj *conn;
164 crypto_X509Obj *cert;
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -0500165 int errnum, errdepth, c_ret;
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400166
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400167 // Get Connection object to check thread state
168 ssl = (SSL *)X509_STORE_CTX_get_app_data(x509_ctx);
169 conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400170
Jean-Paul Calderone26aea022008-09-21 18:47:06 -0400171 MY_END_ALLOW_THREADS(conn->tstate);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400172
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500173 cert = crypto_X509_New(X509_STORE_CTX_get_current_cert(x509_ctx), 0);
174 errnum = X509_STORE_CTX_get_error(x509_ctx);
175 errdepth = X509_STORE_CTX_get_error_depth(x509_ctx);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400176
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500177 argv = Py_BuildValue("(OOiii)", (PyObject *)conn, (PyObject *)cert,
178 errnum, errdepth, ok);
179 Py_DECREF(cert);
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400180 ret = PyEval_CallObject(conn->context->verify_callback, argv);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500181 Py_DECREF(argv);
182
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400183 if (ret != NULL && PyObject_IsTrue(ret)) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500184 X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400185 Py_DECREF(ret);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500186 c_ret = 1;
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400187 } else {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500188 c_ret = 0;
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400189 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500190
Jean-Paul Calderone26aea022008-09-21 18:47:06 -0400191 MY_BEGIN_ALLOW_THREADS(conn->tstate);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500192 return c_ret;
193}
194
195/*
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400196 * Globally defined info callback. This is called from OpenSSL internally.
197 * The GIL will not be held when this function is invoked. It must not be held
198 * when the function returns.
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500199 *
200 * Arguments: ssl - The Connection
201 * where - The part of the SSL code that called us
202 * _ret - The return code of the SSL function that called us
203 * Returns: None
204 */
205static void
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -0500206global_info_callback(const SSL *ssl, int where, int _ret)
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500207{
208 ssl_ConnectionObj *conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl);
209 PyObject *argv, *ret;
210
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400211 /*
212 * GIL isn't held yet. First things first - acquire it, or any Python API
213 * we invoke might segfault or blow up the sun. The reverse will be done
214 * before returning.
215 */
216 MY_END_ALLOW_THREADS(conn->tstate);
217
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500218 argv = Py_BuildValue("(Oii)", (PyObject *)conn, where, _ret);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400219 ret = PyEval_CallObject(conn->context->info_callback, argv);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500220 Py_DECREF(argv);
221
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400222 if (ret == NULL) {
223 /*
224 * XXX - This should be reported somehow. -exarkun
225 */
226 PyErr_Clear();
227 } else {
228 Py_DECREF(ret);
229 }
230
231 /*
232 * This function is returning into OpenSSL. Release the GIL again.
233 */
234 MY_BEGIN_ALLOW_THREADS(conn->tstate);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500235 return;
236}
237
238
239
240
241static char ssl_Context_load_verify_locations_doc[] = "\n\
242Let SSL know where we can find trusted certificates for the certificate\n\
243chain\n\
244\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400245@param cafile: In which file we can find the certificates\n\
246@param capath: In which directory we can find the certificates\r\
247@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500248";
249static PyObject *
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400250ssl_Context_load_verify_locations(ssl_ContextObj *self, PyObject *args) {
251 char *cafile = NULL;
252 char *capath = NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500253
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400254 if (!PyArg_ParseTuple(args, "z|z:load_verify_locations", &cafile, &capath)) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500255 return NULL;
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400256 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500257
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400258 if (!SSL_CTX_load_verify_locations(self->ctx, cafile, capath))
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500259 {
260 exception_from_error_queue();
261 return NULL;
262 }
263 else
264 {
265 Py_INCREF(Py_None);
266 return Py_None;
267 }
268}
269
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400270static char ssl_Context_set_default_verify_paths_doc[] = "\n\
271Use the platform-specific CA certificate locations\n\
272\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400273@return: None\n\
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400274";
275static PyObject *
276ssl_Context_set_default_verify_paths(ssl_ContextObj *self, PyObject *args) {
Jean-Paul Calderone9eadb962008-09-07 21:20:44 -0400277 if (!PyArg_ParseTuple(args, ":set_default_verify_paths")) {
278 return NULL;
279 }
280
Jean-Paul Calderone286b1922008-09-07 21:35:38 -0400281 /*
282 * XXX Error handling for SSL_CTX_set_default_verify_paths is untested.
283 * -exarkun
284 */
285 if (!SSL_CTX_set_default_verify_paths(self->ctx)) {
286 exception_from_error_queue();
287 return NULL;
288 }
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400289 Py_INCREF(Py_None);
290 return Py_None;
291};
292
293
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500294static char ssl_Context_set_passwd_cb_doc[] = "\n\
295Set the passphrase callback\n\
296\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400297@param callback: The Python callback to use\n\
298@param userdata: (optional) A Python object which will be given as\n\
299 argument to the callback\n\
300@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500301";
302static PyObject *
303ssl_Context_set_passwd_cb(ssl_ContextObj *self, PyObject *args)
304{
305 PyObject *callback = NULL, *userdata = Py_None;
306
307 if (!PyArg_ParseTuple(args, "O|O:set_passwd_cb", &callback, &userdata))
308 return NULL;
309
310 if (!PyCallable_Check(callback))
311 {
312 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
313 return NULL;
314 }
315
316 Py_DECREF(self->passphrase_callback);
317 Py_INCREF(callback);
318 self->passphrase_callback = callback;
319 SSL_CTX_set_default_passwd_cb(self->ctx, global_passphrase_callback);
320
321 Py_DECREF(self->passphrase_userdata);
322 Py_INCREF(userdata);
323 self->passphrase_userdata = userdata;
324 SSL_CTX_set_default_passwd_cb_userdata(self->ctx, (void *)self);
325
326 Py_INCREF(Py_None);
327 return Py_None;
328}
329
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500330static crypto_X509Obj *
331parse_certificate_argument(const char* format1, const char* format2, PyObject* args)
332{
333 static PyTypeObject *crypto_X509_type = NULL;
334 crypto_X509Obj *cert;
335
336 /* We need to check that cert really is an X509 object before
337 we deal with it. The problem is we can't just quickly verify
338 the type (since that comes from another module). This should
339 do the trick (reasonably well at least): Once we have one
340 verified object, we use it's type object for future
341 comparisons. */
342
343 if (!crypto_X509_type)
344 {
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -0500345 if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format1, &cert))
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500346 return NULL;
347
348 if (strcmp(cert->ob_type->tp_name, "X509") != 0 ||
349 cert->ob_type->tp_basicsize != sizeof(crypto_X509Obj))
350 {
351 PyErr_SetString(PyExc_TypeError, "Expected an X509 object");
352 return NULL;
353 }
354
355 crypto_X509_type = cert->ob_type;
356 }
357 else
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -0500358 if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format2, crypto_X509_type,
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500359 &cert))
360 return NULL;
361 return cert;
362}
363
364static char ssl_Context_add_extra_chain_cert_doc[] = "\n\
365Add certificate to chain\n\
366\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400367@param certobj: The X509 certificate object to add to the chain\n\
368@return: None\n\
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500369";
370
371static PyObject *
372ssl_Context_add_extra_chain_cert(ssl_ContextObj *self, PyObject *args)
373{
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500374 X509* cert_original;
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500375 crypto_X509Obj *cert = parse_certificate_argument(
376 "O:add_extra_chain_cert", "O!:add_extra_chain_cert", args);
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500377 if (cert == NULL)
378 {
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500379 return NULL;
380 }
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500381 if (!(cert_original = X509_dup(cert->x509)))
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500382 {
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500383 /* exception_from_error_queue(); */
384 PyErr_SetString(PyExc_RuntimeError, "X509_dup failed");
385 return NULL;
386 }
387 if (!SSL_CTX_add_extra_chain_cert(self->ctx, cert_original))
388 {
389 X509_free(cert_original);
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500390 exception_from_error_queue();
391 return NULL;
392 }
393 else
394 {
395 Py_INCREF(Py_None);
396 return Py_None;
397 }
398}
399
400
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500401static char ssl_Context_use_certificate_chain_file_doc[] = "\n\
402Load a certificate chain from a file\n\
403\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400404@param certfile: The name of the certificate chain file\n\
405@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500406";
407static PyObject *
408ssl_Context_use_certificate_chain_file(ssl_ContextObj *self, PyObject *args)
409{
410 char *certfile;
411
412 if (!PyArg_ParseTuple(args, "s:use_certificate_chain_file", &certfile))
413 return NULL;
414
415 if (!SSL_CTX_use_certificate_chain_file(self->ctx, certfile))
416 {
417 exception_from_error_queue();
418 return NULL;
419 }
420 else
421 {
422 Py_INCREF(Py_None);
423 return Py_None;
424 }
425}
426
427
428static char ssl_Context_use_certificate_file_doc[] = "\n\
429Load a certificate from a file\n\
430\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400431@param certfile: The name of the certificate file\n\
432@param filetype: (optional) The encoding of the file, default is PEM\n\
433@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500434";
435static PyObject *
436ssl_Context_use_certificate_file(ssl_ContextObj *self, PyObject *args)
437{
438 char *certfile;
439 int filetype = SSL_FILETYPE_PEM;
440
441 if (!PyArg_ParseTuple(args, "s|i:use_certificate_file", &certfile, &filetype))
442 return NULL;
443
444 if (!SSL_CTX_use_certificate_file(self->ctx, certfile, filetype))
445 {
446 exception_from_error_queue();
447 return NULL;
448 }
449 else
450 {
451 Py_INCREF(Py_None);
452 return Py_None;
453 }
454}
455
456static char ssl_Context_use_certificate_doc[] = "\n\
457Load a certificate from a X509 object\n\
458\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400459@param cert: The X509 object\n\
460@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500461";
462static PyObject *
463ssl_Context_use_certificate(ssl_ContextObj *self, PyObject *args)
464{
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500465 crypto_X509Obj *cert = parse_certificate_argument(
466 "O:use_certificate", "O!:use_certificate", args);
467 if (cert == NULL) {
468 return NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500469 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500470
471 if (!SSL_CTX_use_certificate(self->ctx, cert->x509))
472 {
473 exception_from_error_queue();
474 return NULL;
475 }
476 else
477 {
478 Py_INCREF(Py_None);
479 return Py_None;
480 }
481}
482
483static char ssl_Context_use_privatekey_file_doc[] = "\n\
484Load a private key from a file\n\
485\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400486@param keyfile: The name of the key file\n\
487@param filetype: (optional) The encoding of the file, default is PEM\n\
488@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500489";
490static PyObject *
491ssl_Context_use_privatekey_file(ssl_ContextObj *self, PyObject *args)
492{
493 char *keyfile;
494 int filetype = SSL_FILETYPE_PEM, ret;
495
496 if (!PyArg_ParseTuple(args, "s|i:use_privatekey_file", &keyfile, &filetype))
497 return NULL;
498
499 MY_BEGIN_ALLOW_THREADS(self->tstate);
500 ret = SSL_CTX_use_PrivateKey_file(self->ctx, keyfile, filetype);
501 MY_END_ALLOW_THREADS(self->tstate);
502
503 if (PyErr_Occurred())
504 {
505 flush_error_queue();
506 return NULL;
507 }
508
509 if (!ret)
510 {
511 exception_from_error_queue();
512 return NULL;
513 }
514 else
515 {
516 Py_INCREF(Py_None);
517 return Py_None;
518 }
519}
520
521static char ssl_Context_use_privatekey_doc[] = "\n\
522Load a private key from a PKey object\n\
523\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400524@param pkey: The PKey object\n\
525@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500526";
527static PyObject *
528ssl_Context_use_privatekey(ssl_ContextObj *self, PyObject *args)
529{
530 static PyTypeObject *crypto_PKey_type = NULL;
531 crypto_PKeyObj *pkey;
532
533 /* We need to check that cert really is a PKey object before
534 we deal with it. The problem is we can't just quickly verify
535 the type (since that comes from another module). This should
536 do the trick (reasonably well at least): Once we have one
537 verified object, we use it's type object for future
538 comparisons. */
539
540 if (!crypto_PKey_type)
541 {
542 if (!PyArg_ParseTuple(args, "O:use_privatekey", &pkey))
543 return NULL;
544
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400545 if (strcmp(pkey->ob_type->tp_name, "PKey") != 0 ||
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500546 pkey->ob_type->tp_basicsize != sizeof(crypto_PKeyObj))
547 {
548 PyErr_SetString(PyExc_TypeError, "Expected a PKey object");
549 return NULL;
550 }
551
552 crypto_PKey_type = pkey->ob_type;
553 }
554 else
555 if (!PyArg_ParseTuple(args, "O!:use_privatekey", crypto_PKey_type, &pkey))
556 return NULL;
557
558 if (!SSL_CTX_use_PrivateKey(self->ctx, pkey->pkey))
559 {
560 exception_from_error_queue();
561 return NULL;
562 }
563 else
564 {
565 Py_INCREF(Py_None);
566 return Py_None;
567 }
568}
569
570static char ssl_Context_check_privatekey_doc[] = "\n\
571Check that the private key and certificate match up\n\
572\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400573@return: None (raises an exception if something's wrong)\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500574";
575static PyObject *
576ssl_Context_check_privatekey(ssl_ContextObj *self, PyObject *args)
577{
578 if (!PyArg_ParseTuple(args, ":check_privatekey"))
579 return NULL;
580
581 if (!SSL_CTX_check_private_key(self->ctx))
582 {
583 exception_from_error_queue();
584 return NULL;
585 }
586 else
587 {
588 Py_INCREF(Py_None);
589 return Py_None;
590 }
591}
592
593static char ssl_Context_load_client_ca_doc[] = "\n\
594Load the trusted certificates that will be sent to the client (basically\n\
595telling the client \"These are the guys I trust\")\n\
596\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400597@param cafile: The name of the certificates file\n\
598@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500599";
600static PyObject *
601ssl_Context_load_client_ca(ssl_ContextObj *self, PyObject *args)
602{
603 char *cafile;
604
605 if (!PyArg_ParseTuple(args, "s:load_client_ca", &cafile))
606 return NULL;
607
608 SSL_CTX_set_client_CA_list(self->ctx, SSL_load_client_CA_file(cafile));
609
610 Py_INCREF(Py_None);
611 return Py_None;
612}
613
614static char ssl_Context_set_session_id_doc[] = "\n\
615Set the session identifier, this is needed if you want to do session\n\
616resumption (which, ironically, isn't implemented yet)\n\
617\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400618@param buf: A Python object that can be safely converted to a string\n\
619@returns: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500620";
621static PyObject *
622ssl_Context_set_session_id(ssl_ContextObj *self, PyObject *args)
623{
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -0500624 unsigned char *buf;
625 unsigned int len;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500626
627 if (!PyArg_ParseTuple(args, "s#:set_session_id", &buf, &len))
628 return NULL;
629
630 if (!SSL_CTX_set_session_id_context(self->ctx, buf, len))
631 {
632 exception_from_error_queue();
633 return NULL;
634 }
635 else
636 {
637 Py_INCREF(Py_None);
638 return Py_None;
639 }
640}
641
642static char ssl_Context_set_verify_doc[] = "\n\
643Set the verify mode and verify callback\n\
644\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400645@param mode: The verify mode, this is either VERIFY_NONE or\n\
646 VERIFY_PEER combined with possible other flags\n\
647@param callback: The Python callback to use\n\
648@return: None\n\
Jean-Paul Calderone24aedf42008-03-06 22:01:16 -0500649\n\
650See SSL_CTX_set_verify(3SSL) for further details.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500651";
652static PyObject *
653ssl_Context_set_verify(ssl_ContextObj *self, PyObject *args)
654{
655 int mode;
656 PyObject *callback = NULL;
657
658 if (!PyArg_ParseTuple(args, "iO:set_verify", &mode, &callback))
659 return NULL;
660
661 if (!PyCallable_Check(callback))
662 {
663 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
664 return NULL;
665 }
666
667 Py_DECREF(self->verify_callback);
668 Py_INCREF(callback);
669 self->verify_callback = callback;
670 SSL_CTX_set_verify(self->ctx, mode, global_verify_callback);
671
672 Py_INCREF(Py_None);
673 return Py_None;
674}
675
676static char ssl_Context_set_verify_depth_doc[] = "\n\
677Set the verify depth\n\
678\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400679@param depth: An integer specifying the verify depth\n\
680@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500681";
682static PyObject *
683ssl_Context_set_verify_depth(ssl_ContextObj *self, PyObject *args)
684{
685 int depth;
686
687 if (!PyArg_ParseTuple(args, "i:set_verify_depth", &depth))
688 return NULL;
689
690 SSL_CTX_set_verify_depth(self->ctx, depth);
691 Py_INCREF(Py_None);
692 return Py_None;
693}
694
695static char ssl_Context_get_verify_mode_doc[] = "\n\
696Get the verify mode\n\
697\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400698@return: The verify mode\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500699";
700static PyObject *
701ssl_Context_get_verify_mode(ssl_ContextObj *self, PyObject *args)
702{
703 int mode;
704
705 if (!PyArg_ParseTuple(args, ":get_verify_mode"))
706 return NULL;
707
708 mode = SSL_CTX_get_verify_mode(self->ctx);
709 return PyInt_FromLong((long)mode);
710}
711
712static char ssl_Context_get_verify_depth_doc[] = "\n\
713Get the verify depth\n\
714\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400715@return: The verify depth\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500716";
717static PyObject *
718ssl_Context_get_verify_depth(ssl_ContextObj *self, PyObject *args)
719{
720 int depth;
721
722 if (!PyArg_ParseTuple(args, ":get_verify_depth"))
723 return NULL;
724
725 depth = SSL_CTX_get_verify_depth(self->ctx);
726 return PyInt_FromLong((long)depth);
727}
728
729static char ssl_Context_load_tmp_dh_doc[] = "\n\
730Load parameters for Ephemeral Diffie-Hellman\n\
731\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400732@param dhfile: The file to load EDH parameters from\n\
733@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500734";
735static PyObject *
736ssl_Context_load_tmp_dh(ssl_ContextObj *self, PyObject *args)
737{
738 char *dhfile;
739 BIO *bio;
740 DH *dh;
741
742 if (!PyArg_ParseTuple(args, "s:load_tmp_dh", &dhfile))
743 return NULL;
744
745 bio = BIO_new_file(dhfile, "r");
746 if (bio == NULL)
747 return PyErr_NoMemory();
748
749 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
750 SSL_CTX_set_tmp_dh(self->ctx, dh);
751 DH_free(dh);
752 BIO_free(bio);
753
754 Py_INCREF(Py_None);
755 return Py_None;
756}
757
758static char ssl_Context_set_cipher_list_doc[] = "\n\
759Change the cipher list\n\
760\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400761@param cipher_list: A cipher list, see ciphers(1)\n\
762@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500763";
764static PyObject *
765ssl_Context_set_cipher_list(ssl_ContextObj *self, PyObject *args)
766{
767 char *cipher_list;
768
769 if (!PyArg_ParseTuple(args, "s:set_cipher_list", &cipher_list))
770 return NULL;
771
772 if (!SSL_CTX_set_cipher_list(self->ctx, cipher_list))
773 {
774 exception_from_error_queue();
775 return NULL;
776 }
777 else
778 {
779 Py_INCREF(Py_None);
780 return Py_None;
781 }
782}
783
784static char ssl_Context_set_timeout_doc[] = "\n\
785Set session timeout\n\
786\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400787@param timeout: The timeout in seconds\n\
788@return: The previous session timeout\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500789";
790static PyObject *
791ssl_Context_set_timeout(ssl_ContextObj *self, PyObject *args)
792{
793 long t, ret;
794
795 if (!PyArg_ParseTuple(args, "l:set_timeout", &t))
796 return NULL;
797
798 ret = SSL_CTX_set_timeout(self->ctx, t);
799 return PyLong_FromLong(ret);
800}
801
802static char ssl_Context_get_timeout_doc[] = "\n\
803Get the session timeout\n\
804\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400805@return: The session timeout\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500806";
807static PyObject *
808ssl_Context_get_timeout(ssl_ContextObj *self, PyObject *args)
809{
810 long ret;
811
812 if (!PyArg_ParseTuple(args, ":get_timeout"))
813 return NULL;
814
815 ret = SSL_CTX_get_timeout(self->ctx);
816 return PyLong_FromLong(ret);
817}
818
819static char ssl_Context_set_info_callback_doc[] = "\n\
820Set the info callback\n\
821\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400822@param callback: The Python callback to use\n\
823@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500824";
825static PyObject *
826ssl_Context_set_info_callback(ssl_ContextObj *self, PyObject *args)
827{
828 PyObject *callback;
829
830 if (!PyArg_ParseTuple(args, "O:set_info_callback", &callback))
831 return NULL;
832
833 if (!PyCallable_Check(callback))
834 {
835 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
836 return NULL;
837 }
838
839 Py_DECREF(self->info_callback);
840 Py_INCREF(callback);
841 self->info_callback = callback;
842 SSL_CTX_set_info_callback(self->ctx, global_info_callback);
843
844 Py_INCREF(Py_None);
845 return Py_None;
846}
847
848static char ssl_Context_get_app_data_doc[] = "\n\
849Get the application data (supplied via set_app_data())\n\
850\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400851@return: The application data\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500852";
853static PyObject *
854ssl_Context_get_app_data(ssl_ContextObj *self, PyObject *args)
855{
856 if (!PyArg_ParseTuple(args, ":get_app_data"))
857 return NULL;
858
859 Py_INCREF(self->app_data);
860 return self->app_data;
861}
862
863static char ssl_Context_set_app_data_doc[] = "\n\
864Set the application data (will be returned from get_app_data())\n\
865\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400866@param data: Any Python object\n\
867@return: None\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500868";
869static PyObject *
870ssl_Context_set_app_data(ssl_ContextObj *self, PyObject *args)
871{
872 PyObject *data;
873
874 if (!PyArg_ParseTuple(args, "O:set_app_data", &data))
875 return NULL;
876
877 Py_DECREF(self->app_data);
878 Py_INCREF(data);
879 self->app_data = data;
880
881 Py_INCREF(Py_None);
882 return Py_None;
883}
884
885static char ssl_Context_get_cert_store_doc[] = "\n\
886Get the certificate store for the context\n\
887\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400888@return: A X509Store object\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500889";
890static PyObject *
891ssl_Context_get_cert_store(ssl_ContextObj *self, PyObject *args)
892{
893 X509_STORE *store;
894
895 if (!PyArg_ParseTuple(args, ":get_cert_store"))
896 return NULL;
897
898 if ((store = SSL_CTX_get_cert_store(self->ctx)) == NULL)
899 {
900 Py_INCREF(Py_None);
901 return Py_None;
902 }
903 else
904 {
905 return (PyObject *)crypto_X509Store_New(store, 0);
906 }
907}
908
909static char ssl_Context_set_options_doc[] = "\n\
910Add options. Options set before are not cleared!\n\
911\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400912@param options: The options to add.\n\
913@return: The new option bitmask.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500914";
915static PyObject *
916ssl_Context_set_options(ssl_ContextObj *self, PyObject *args)
917{
918 long options;
919
920 if (!PyArg_ParseTuple(args, "l:set_options", &options))
921 return NULL;
922
923 return PyInt_FromLong(SSL_CTX_set_options(self->ctx, options));
924}
925
926
927/*
928 * Member methods in the Context object
929 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
930 * { 'name', (PyCFunction)ssl_Context_name, METH_VARARGS }
931 * for convenience
932 * ADD_ALIAS(name,real) creates an "alias" of the ssl_Context_real
933 * function with the name 'name'
934 */
935#define ADD_METHOD(name) { #name, (PyCFunction)ssl_Context_##name, METH_VARARGS, ssl_Context_##name##_doc }
936static PyMethodDef ssl_Context_methods[] = {
937 ADD_METHOD(load_verify_locations),
938 ADD_METHOD(set_passwd_cb),
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400939 ADD_METHOD(set_default_verify_paths),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500940 ADD_METHOD(use_certificate_chain_file),
941 ADD_METHOD(use_certificate_file),
942 ADD_METHOD(use_certificate),
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500943 ADD_METHOD(add_extra_chain_cert),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500944 ADD_METHOD(use_privatekey_file),
945 ADD_METHOD(use_privatekey),
946 ADD_METHOD(check_privatekey),
947 ADD_METHOD(load_client_ca),
948 ADD_METHOD(set_session_id),
949 ADD_METHOD(set_verify),
950 ADD_METHOD(set_verify_depth),
951 ADD_METHOD(get_verify_mode),
952 ADD_METHOD(get_verify_depth),
953 ADD_METHOD(load_tmp_dh),
954 ADD_METHOD(set_cipher_list),
955 ADD_METHOD(set_timeout),
956 ADD_METHOD(get_timeout),
957 ADD_METHOD(set_info_callback),
958 ADD_METHOD(get_app_data),
959 ADD_METHOD(set_app_data),
960 ADD_METHOD(get_cert_store),
961 ADD_METHOD(set_options),
962 { NULL, NULL }
963};
964#undef ADD_METHOD
965
966
967/* Constructor, takes an int specifying which method to use */
968/*
969 * Constructor for Context objects
970 *
971 * Arguments: i_method - The SSL method to use, one of the SSLv2_METHOD,
972 * SSLv3_METHOD, SSLv23_METHOD and TLSv1_METHOD
973 * constants.
974 * Returns: The newly created Context object
975 */
976ssl_ContextObj *
977ssl_Context_New(int i_method)
978{
979 SSL_METHOD *method;
980 ssl_ContextObj *self;
981
982 switch (i_method)
983 {
984 /* Too bad TLSv1 servers can't accept SSLv3 clients */
985 case ssl_SSLv2_METHOD: method = SSLv2_method(); break;
986 case ssl_SSLv23_METHOD: method = SSLv23_method(); break;
987 case ssl_SSLv3_METHOD: method = SSLv3_method(); break;
988 case ssl_TLSv1_METHOD: method = TLSv1_method(); break;
989 default:
990 PyErr_SetString(PyExc_ValueError, "No such protocol");
991 return NULL;
992 }
993
994 self = PyObject_GC_New(ssl_ContextObj, &ssl_Context_Type);
995 if (self == NULL)
996 return (ssl_ContextObj *)PyErr_NoMemory();
997
998 self->ctx = SSL_CTX_new(method);
999 Py_INCREF(Py_None);
1000 self->passphrase_callback = Py_None;
1001 Py_INCREF(Py_None);
1002 self->verify_callback = Py_None;
1003 Py_INCREF(Py_None);
1004 self->info_callback = Py_None;
1005
1006 Py_INCREF(Py_None);
1007 self->passphrase_userdata = Py_None;
1008
1009 Py_INCREF(Py_None);
1010 self->app_data = Py_None;
1011
1012 /* Some initialization that's required to operate smoothly in Python */
1013 SSL_CTX_set_app_data(self->ctx, self);
1014 SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
1015 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1016 SSL_MODE_AUTO_RETRY);
1017
1018 self->tstate = NULL;
1019 PyObject_GC_Track((PyObject *)self);
1020
1021 return self;
1022}
1023
1024/*
1025 * Find attribute
1026 *
1027 * Arguments: self - The Context object
1028 * name - The attribute name
1029 * Returns: A Python object for the attribute, or NULL if something went
1030 * wrong
1031 */
1032static PyObject *
1033ssl_Context_getattr(ssl_ContextObj *self, char *name)
1034{
1035 return Py_FindMethod(ssl_Context_methods, (PyObject *)self, name);
1036}
1037
1038/*
1039 * Call the visitproc on all contained objects.
1040 *
1041 * Arguments: self - The Context object
1042 * visit - Function to call
1043 * arg - Extra argument to visit
1044 * Returns: 0 if all goes well, otherwise the return code from the first
1045 * call that gave non-zero result.
1046 */
1047static int
1048ssl_Context_traverse(ssl_ContextObj *self, visitproc visit, void *arg)
1049{
1050 int ret = 0;
1051
1052 if (ret == 0 && self->passphrase_callback != NULL)
1053 ret = visit((PyObject *)self->passphrase_callback, arg);
1054 if (ret == 0 && self->passphrase_userdata != NULL)
1055 ret = visit((PyObject *)self->passphrase_userdata, arg);
1056 if (ret == 0 && self->verify_callback != NULL)
1057 ret = visit((PyObject *)self->verify_callback, arg);
1058 if (ret == 0 && self->info_callback != NULL)
1059 ret = visit((PyObject *)self->info_callback, arg);
1060 if (ret == 0 && self->app_data != NULL)
1061 ret = visit(self->app_data, arg);
1062 return ret;
1063}
1064
1065/*
1066 * Decref all contained objects and zero the pointers.
1067 *
1068 * Arguments: self - The Context object
1069 * Returns: Always 0.
1070 */
1071static int
1072ssl_Context_clear(ssl_ContextObj *self)
1073{
1074 Py_XDECREF(self->passphrase_callback);
1075 self->passphrase_callback = NULL;
1076 Py_XDECREF(self->passphrase_userdata);
1077 self->passphrase_userdata = NULL;
1078 Py_XDECREF(self->verify_callback);
1079 self->verify_callback = NULL;
1080 Py_XDECREF(self->info_callback);
1081 self->info_callback = NULL;
1082 Py_XDECREF(self->app_data);
1083 self->app_data = NULL;
1084 return 0;
1085}
1086
1087/*
1088 * Deallocate the memory used by the Context object
1089 *
1090 * Arguments: self - The Context object
1091 * Returns: None
1092 */
1093static void
1094ssl_Context_dealloc(ssl_ContextObj *self)
1095{
1096 PyObject_GC_UnTrack((PyObject *)self);
1097 SSL_CTX_free(self->ctx);
1098 ssl_Context_clear(self);
1099 PyObject_GC_Del(self);
1100}
1101
1102
1103PyTypeObject ssl_Context_Type = {
1104 PyObject_HEAD_INIT(NULL)
1105 0,
1106 "Context",
1107 sizeof(ssl_ContextObj),
1108 0,
1109 (destructor)ssl_Context_dealloc,
1110 NULL, /* print */
1111 (getattrfunc)ssl_Context_getattr,
1112 NULL, /* setattr */
1113 NULL, /* compare */
1114 NULL, /* repr */
1115 NULL, /* as_number */
1116 NULL, /* as_sequence */
1117 NULL, /* as_mapping */
1118 NULL, /* hash */
1119 NULL, /* call */
1120 NULL, /* str */
1121 NULL, /* getattro */
1122 NULL, /* setattro */
1123 NULL, /* as_buffer */
1124 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1125 NULL, /* doc */
1126 (traverseproc)ssl_Context_traverse,
1127 (inquiry)ssl_Context_clear,
1128};
1129
1130
1131/*
1132 * Initialize the Context part of the SSL sub module
1133 *
1134 * Arguments: dict - Dictionary of the OpenSSL.SSL module
1135 * Returns: 1 for success, 0 otherwise
1136 */
1137int
1138init_ssl_context(PyObject *dict)
1139{
1140 ssl_Context_Type.ob_type = &PyType_Type;
1141 Py_INCREF(&ssl_Context_Type);
1142 if (PyDict_SetItemString(dict, "ContextType", (PyObject *)&ssl_Context_Type) != 0)
1143 return 0;
1144
1145 return 1;
1146}
1147