blob: ed0eabea1e3a501a4842efabaef69186644db34c [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 Calderone12ea9a02008-02-22 12:24:39 -050014#ifndef MS_WINDOWS
15# include <sys/socket.h>
16# include <netinet/in.h>
17# if !(defined(__BEOS__) || defined(__CYGWIN__))
18# include <netinet/tcp.h>
19# endif
20#else
21# include <winsock.h>
22# include <wincrypt.h>
23#endif
24
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050025#define SSL_MODULE
26#include "ssl.h"
27
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050028/*
29 * CALLBACKS
30 *
31 * Callbacks work like this: We provide a "global" callback in C which
32 * transforms the arguments into a Python argument tuple and calls the
33 * corresponding Python callback, and then parsing the return value back into
34 * things the C function can return.
35 *
36 * Three caveats:
37 * + How do we find the Context object where the Python callbacks are stored?
38 * + What about multithreading and execution frames?
39 * + What about Python callbacks that raise exceptions?
40 *
41 * The solution to the first issue is trivial if the callback provides
42 * "userdata" functionality. Since the only callbacks that don't provide
43 * userdata do provide a pointer to an SSL structure, we can associate an SSL
44 * object and a Connection one-to-one via the SSL_set/get_app_data()
45 * functions.
46 *
47 * The solution to the other issue is to rewrite the Py_BEGIN_ALLOW_THREADS
48 * macro allowing it (or rather a new macro) to specify where to save the
49 * thread state (in our case, as a member of the Connection/Context object) so
50 * we can retrieve it again before calling the Python callback.
51 */
52
53/*
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040054 * Globally defined passphrase callback. This is called from OpenSSL
55 * internally. The GIL will not be held when this function is invoked. It
56 * must not be held when the function returns.
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050057 *
58 * Arguments: buf - Buffer to store the returned passphrase in
59 * maxlen - Maximum length of the passphrase
60 * verify - If true, the passphrase callback should ask for a
61 * password twice and verify they're equal. If false, only
62 * ask once.
63 * arg - User data, always a Context object
64 * Returns: The length of the password if successful, 0 otherwise
65 */
66static int
67global_passphrase_callback(char *buf, int maxlen, int verify, void *arg)
68{
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040069 /*
70 * Initialize len here because we're always going to return it, and we
71 * might jump to the return before it gets initialized in any other way.
72 */
73 int len = 0;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050074 char *str;
75 PyObject *argv, *ret = NULL;
76 ssl_ContextObj *ctx = (ssl_ContextObj *)arg;
77
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040078 /*
79 * GIL isn't held yet. First things first - acquire it, or any Python API
80 * we invoke might segfault or blow up the sun. The reverse will be done
81 * before returning.
82 */
83 MY_END_ALLOW_THREADS(ctx->tstate);
84
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -040085 /* The Python callback is called with a (maxlen,verify,userdata) tuple */
86 argv = Py_BuildValue("(iiO)", maxlen, verify, ctx->passphrase_userdata);
87
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040088 /*
89 * XXX Didn't check argv to see if it was NULL. -exarkun
90 */
91 ret = PyEval_CallObject(ctx->passphrase_callback, argv);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050092 Py_DECREF(argv);
93
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040094 if (ret == NULL) {
95 /*
96 * XXX The callback raised an exception. At the very least, it should
97 * be printed out here. An *actual* solution would be to raise it up
98 * through OpenSSL. That might be a bit tricky, but it's probably
99 * possible. -exarkun
100 */
101 goto out;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500102 }
103
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400104 if (!PyObject_IsTrue(ret)) {
105 /*
106 * Returned "", or None, or something. Treat it as no passphrase.
107 */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500108 Py_DECREF(ret);
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400109 goto out;
110 }
111
112 if (!PyString_Check(ret)) {
113 /*
114 * XXX Returned something that wasn't a string. This is bogus. We
115 * should report an error or raise an exception (again, through OpenSSL
116 * - tricky). -exarkun
117 */
118 Py_DECREF(ret);
119 goto out;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500120 }
121
122 len = PyString_Size(ret);
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400123 if (len > maxlen) {
124 /*
125 * XXX Returned more than we said they were allowed to return. Report
126 * an error or raise an exception (tricky blah blah). -exarkun
127 */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500128 len = maxlen;
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400129 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500130
131 str = PyString_AsString(ret);
132 strncpy(buf, str, len);
133 Py_XDECREF(ret);
134
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400135 out:
136 /*
137 * This function is returning into OpenSSL. Release the GIL again.
138 */
139 MY_BEGIN_ALLOW_THREADS(ctx->tstate);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500140 return len;
141}
142
143/*
144 * Globally defined verify callback
145 *
146 * Arguments: ok - True everything is OK "so far", false otherwise
147 * x509_ctx - Contains the certificate being checked, the current
148 * error number and depth, and the Connection we're
149 * dealing with
150 * Returns: True if everything is okay, false otherwise
151 */
152static int
153global_verify_callback(int ok, X509_STORE_CTX *x509_ctx)
154{
155 PyObject *argv, *ret;
156 SSL *ssl;
157 ssl_ConnectionObj *conn;
158 crypto_X509Obj *cert;
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400159 int errnum, errdepth, c_ret, use_thread_state;
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400160
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400161 // Get Connection object to check thread state
162 ssl = (SSL *)X509_STORE_CTX_get_app_data(x509_ctx);
163 conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400164
Jean-Paul Calderone26aea022008-09-21 18:47:06 -0400165 MY_END_ALLOW_THREADS(conn->tstate);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400166
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500167 cert = crypto_X509_New(X509_STORE_CTX_get_current_cert(x509_ctx), 0);
168 errnum = X509_STORE_CTX_get_error(x509_ctx);
169 errdepth = X509_STORE_CTX_get_error_depth(x509_ctx);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400170
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500171 argv = Py_BuildValue("(OOiii)", (PyObject *)conn, (PyObject *)cert,
172 errnum, errdepth, ok);
173 Py_DECREF(cert);
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400174 ret = PyEval_CallObject(conn->context->verify_callback, argv);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500175 Py_DECREF(argv);
176
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400177 if (ret != NULL && PyObject_IsTrue(ret)) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500178 X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400179 Py_DECREF(ret);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500180 c_ret = 1;
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400181 } else {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500182 c_ret = 0;
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400183 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500184
Jean-Paul Calderone26aea022008-09-21 18:47:06 -0400185 MY_BEGIN_ALLOW_THREADS(conn->tstate);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500186 return c_ret;
187}
188
189/*
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400190 * Globally defined info callback. This is called from OpenSSL internally.
191 * The GIL will not be held when this function is invoked. It must not be held
192 * when the function returns.
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500193 *
194 * Arguments: ssl - The Connection
195 * where - The part of the SSL code that called us
196 * _ret - The return code of the SSL function that called us
197 * Returns: None
198 */
199static void
200global_info_callback(SSL *ssl, int where, int _ret)
201{
202 ssl_ConnectionObj *conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl);
203 PyObject *argv, *ret;
204
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400205 /*
206 * GIL isn't held yet. First things first - acquire it, or any Python API
207 * we invoke might segfault or blow up the sun. The reverse will be done
208 * before returning.
209 */
210 MY_END_ALLOW_THREADS(conn->tstate);
211
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500212 argv = Py_BuildValue("(Oii)", (PyObject *)conn, where, _ret);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400213 ret = PyEval_CallObject(conn->context->info_callback, argv);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500214 Py_DECREF(argv);
215
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400216 if (ret == NULL) {
217 /*
218 * XXX - This should be reported somehow. -exarkun
219 */
220 PyErr_Clear();
221 } else {
222 Py_DECREF(ret);
223 }
224
225 /*
226 * This function is returning into OpenSSL. Release the GIL again.
227 */
228 MY_BEGIN_ALLOW_THREADS(conn->tstate);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500229 return;
230}
231
232
233
234
235static char ssl_Context_load_verify_locations_doc[] = "\n\
236Let SSL know where we can find trusted certificates for the certificate\n\
237chain\n\
238\n\
239Arguments: self - The Context object\n\
240 args - The Python argument tuple, should be:\n\
241 cafile - Which file we can find the certificates\n\
242Returns: None\n\
243";
244static PyObject *
245ssl_Context_load_verify_locations(ssl_ContextObj *self, PyObject *args)
246{
247 char *cafile;
248
249 if (!PyArg_ParseTuple(args, "s:load_verify_locations", &cafile))
250 return NULL;
251
252 if (!SSL_CTX_load_verify_locations(self->ctx, cafile, NULL))
253 {
254 exception_from_error_queue();
255 return NULL;
256 }
257 else
258 {
259 Py_INCREF(Py_None);
260 return Py_None;
261 }
262}
263
264static char ssl_Context_set_passwd_cb_doc[] = "\n\
265Set the passphrase callback\n\
266\n\
267Arguments: self - The Context object\n\
268 args - The Python argument tuple, should be:\n\
269 callback - The Python callback to use\n\
270 userdata - (optional) A Python object which will be given as\n\
271 argument to the callback\n\
272Returns: None\n\
273";
274static PyObject *
275ssl_Context_set_passwd_cb(ssl_ContextObj *self, PyObject *args)
276{
277 PyObject *callback = NULL, *userdata = Py_None;
278
279 if (!PyArg_ParseTuple(args, "O|O:set_passwd_cb", &callback, &userdata))
280 return NULL;
281
282 if (!PyCallable_Check(callback))
283 {
284 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
285 return NULL;
286 }
287
288 Py_DECREF(self->passphrase_callback);
289 Py_INCREF(callback);
290 self->passphrase_callback = callback;
291 SSL_CTX_set_default_passwd_cb(self->ctx, global_passphrase_callback);
292
293 Py_DECREF(self->passphrase_userdata);
294 Py_INCREF(userdata);
295 self->passphrase_userdata = userdata;
296 SSL_CTX_set_default_passwd_cb_userdata(self->ctx, (void *)self);
297
298 Py_INCREF(Py_None);
299 return Py_None;
300}
301
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500302static crypto_X509Obj *
303parse_certificate_argument(const char* format1, const char* format2, PyObject* args)
304{
305 static PyTypeObject *crypto_X509_type = NULL;
306 crypto_X509Obj *cert;
307
308 /* We need to check that cert really is an X509 object before
309 we deal with it. The problem is we can't just quickly verify
310 the type (since that comes from another module). This should
311 do the trick (reasonably well at least): Once we have one
312 verified object, we use it's type object for future
313 comparisons. */
314
315 if (!crypto_X509_type)
316 {
317 if (!PyArg_ParseTuple(args, format1, &cert))
318 return NULL;
319
320 if (strcmp(cert->ob_type->tp_name, "X509") != 0 ||
321 cert->ob_type->tp_basicsize != sizeof(crypto_X509Obj))
322 {
323 PyErr_SetString(PyExc_TypeError, "Expected an X509 object");
324 return NULL;
325 }
326
327 crypto_X509_type = cert->ob_type;
328 }
329 else
330 if (!PyArg_ParseTuple(args, format2, crypto_X509_type,
331 &cert))
332 return NULL;
333 return cert;
334}
335
336static char ssl_Context_add_extra_chain_cert_doc[] = "\n\
337Add certificate to chain\n\
338\n\
339Arguments: self - The Context object\n\
340 args - The Python argument tuple, should be:\n\
341 certobj - The X509 certificate object to add to the chain\n\
342Returns: None\n\
343";
344
345static PyObject *
346ssl_Context_add_extra_chain_cert(ssl_ContextObj *self, PyObject *args)
347{
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500348 X509* cert_original;
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500349 crypto_X509Obj *cert = parse_certificate_argument(
350 "O:add_extra_chain_cert", "O!:add_extra_chain_cert", args);
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500351 if (cert == NULL)
352 {
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500353 return NULL;
354 }
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500355 if (!(cert_original = X509_dup(cert->x509)))
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500356 {
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500357 /* exception_from_error_queue(); */
358 PyErr_SetString(PyExc_RuntimeError, "X509_dup failed");
359 return NULL;
360 }
361 if (!SSL_CTX_add_extra_chain_cert(self->ctx, cert_original))
362 {
363 X509_free(cert_original);
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500364 exception_from_error_queue();
365 return NULL;
366 }
367 else
368 {
369 Py_INCREF(Py_None);
370 return Py_None;
371 }
372}
373
374
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500375static char ssl_Context_use_certificate_chain_file_doc[] = "\n\
376Load a certificate chain from a file\n\
377\n\
378Arguments: self - The Context object\n\
379 args - The Python argument tuple, should be:\n\
380 certfile - The name of the certificate chain file\n\
381Returns: None\n\
382";
383static PyObject *
384ssl_Context_use_certificate_chain_file(ssl_ContextObj *self, PyObject *args)
385{
386 char *certfile;
387
388 if (!PyArg_ParseTuple(args, "s:use_certificate_chain_file", &certfile))
389 return NULL;
390
391 if (!SSL_CTX_use_certificate_chain_file(self->ctx, certfile))
392 {
393 exception_from_error_queue();
394 return NULL;
395 }
396 else
397 {
398 Py_INCREF(Py_None);
399 return Py_None;
400 }
401}
402
403
404static char ssl_Context_use_certificate_file_doc[] = "\n\
405Load a certificate from a file\n\
406\n\
407Arguments: self - The Context object\n\
408 args - The Python argument tuple, should be:\n\
409 certfile - The name of the certificate file\n\
410 filetype - (optional) The encoding of the file, default is PEM\n\
411Returns: None\n\
412";
413static PyObject *
414ssl_Context_use_certificate_file(ssl_ContextObj *self, PyObject *args)
415{
416 char *certfile;
417 int filetype = SSL_FILETYPE_PEM;
418
419 if (!PyArg_ParseTuple(args, "s|i:use_certificate_file", &certfile, &filetype))
420 return NULL;
421
422 if (!SSL_CTX_use_certificate_file(self->ctx, certfile, filetype))
423 {
424 exception_from_error_queue();
425 return NULL;
426 }
427 else
428 {
429 Py_INCREF(Py_None);
430 return Py_None;
431 }
432}
433
434static char ssl_Context_use_certificate_doc[] = "\n\
435Load a certificate from a X509 object\n\
436\n\
437Arguments: self - The Context object\n\
438 args - The Python argument tuple, should be:\n\
439 cert - The X509 object\n\
440Returns: None\n\
441";
442static PyObject *
443ssl_Context_use_certificate(ssl_ContextObj *self, PyObject *args)
444{
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500445 crypto_X509Obj *cert = parse_certificate_argument(
446 "O:use_certificate", "O!:use_certificate", args);
447 if (cert == NULL) {
448 return NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500449 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500450
451 if (!SSL_CTX_use_certificate(self->ctx, cert->x509))
452 {
453 exception_from_error_queue();
454 return NULL;
455 }
456 else
457 {
458 Py_INCREF(Py_None);
459 return Py_None;
460 }
461}
462
463static char ssl_Context_use_privatekey_file_doc[] = "\n\
464Load a private key from a file\n\
465\n\
466Arguments: self - The Context object\n\
467 args - The Python argument tuple, should be:\n\
468 keyfile - The name of the key file\n\
469 filetype - (optional) The encoding of the file, default is PEM\n\
470Returns: None\n\
471";
472static PyObject *
473ssl_Context_use_privatekey_file(ssl_ContextObj *self, PyObject *args)
474{
475 char *keyfile;
476 int filetype = SSL_FILETYPE_PEM, ret;
477
478 if (!PyArg_ParseTuple(args, "s|i:use_privatekey_file", &keyfile, &filetype))
479 return NULL;
480
481 MY_BEGIN_ALLOW_THREADS(self->tstate);
482 ret = SSL_CTX_use_PrivateKey_file(self->ctx, keyfile, filetype);
483 MY_END_ALLOW_THREADS(self->tstate);
484
485 if (PyErr_Occurred())
486 {
487 flush_error_queue();
488 return NULL;
489 }
490
491 if (!ret)
492 {
493 exception_from_error_queue();
494 return NULL;
495 }
496 else
497 {
498 Py_INCREF(Py_None);
499 return Py_None;
500 }
501}
502
503static char ssl_Context_use_privatekey_doc[] = "\n\
504Load a private key from a PKey object\n\
505\n\
506Arguments: self - The Context object\n\
507 args - The Python argument tuple, should be:\n\
508 pkey - The PKey object\n\
509Returns: None\n\
510";
511static PyObject *
512ssl_Context_use_privatekey(ssl_ContextObj *self, PyObject *args)
513{
514 static PyTypeObject *crypto_PKey_type = NULL;
515 crypto_PKeyObj *pkey;
516
517 /* We need to check that cert really is a PKey object before
518 we deal with it. The problem is we can't just quickly verify
519 the type (since that comes from another module). This should
520 do the trick (reasonably well at least): Once we have one
521 verified object, we use it's type object for future
522 comparisons. */
523
524 if (!crypto_PKey_type)
525 {
526 if (!PyArg_ParseTuple(args, "O:use_privatekey", &pkey))
527 return NULL;
528
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400529 if (strcmp(pkey->ob_type->tp_name, "PKey") != 0 ||
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500530 pkey->ob_type->tp_basicsize != sizeof(crypto_PKeyObj))
531 {
532 PyErr_SetString(PyExc_TypeError, "Expected a PKey object");
533 return NULL;
534 }
535
536 crypto_PKey_type = pkey->ob_type;
537 }
538 else
539 if (!PyArg_ParseTuple(args, "O!:use_privatekey", crypto_PKey_type, &pkey))
540 return NULL;
541
542 if (!SSL_CTX_use_PrivateKey(self->ctx, pkey->pkey))
543 {
544 exception_from_error_queue();
545 return NULL;
546 }
547 else
548 {
549 Py_INCREF(Py_None);
550 return Py_None;
551 }
552}
553
554static char ssl_Context_check_privatekey_doc[] = "\n\
555Check that the private key and certificate match up\n\
556\n\
557Arguments: self - The Context object\n\
558 args - The Python argument tuple, should be empty\n\
559Returns: None (raises an exception if something's wrong)\n\
560";
561static PyObject *
562ssl_Context_check_privatekey(ssl_ContextObj *self, PyObject *args)
563{
564 if (!PyArg_ParseTuple(args, ":check_privatekey"))
565 return NULL;
566
567 if (!SSL_CTX_check_private_key(self->ctx))
568 {
569 exception_from_error_queue();
570 return NULL;
571 }
572 else
573 {
574 Py_INCREF(Py_None);
575 return Py_None;
576 }
577}
578
579static char ssl_Context_load_client_ca_doc[] = "\n\
580Load the trusted certificates that will be sent to the client (basically\n\
581telling the client \"These are the guys I trust\")\n\
582\n\
583Arguments: self - The Context object\n\
584 args - The Python argument tuple, should be:\n\
585 cafile - The name of the certificates file\n\
586Returns: None\n\
587";
588static PyObject *
589ssl_Context_load_client_ca(ssl_ContextObj *self, PyObject *args)
590{
591 char *cafile;
592
593 if (!PyArg_ParseTuple(args, "s:load_client_ca", &cafile))
594 return NULL;
595
596 SSL_CTX_set_client_CA_list(self->ctx, SSL_load_client_CA_file(cafile));
597
598 Py_INCREF(Py_None);
599 return Py_None;
600}
601
602static char ssl_Context_set_session_id_doc[] = "\n\
603Set the session identifier, this is needed if you want to do session\n\
604resumption (which, ironically, isn't implemented yet)\n\
605\n\
606Arguments: self - The Context object\n\
607 args - The Python argument tuple, should be:\n\
608 buf - A Python object that can be safely converted to a string\n\
609Returns: None\n\
610";
611static PyObject *
612ssl_Context_set_session_id(ssl_ContextObj *self, PyObject *args)
613{
614 char *buf;
615 int len;
616
617 if (!PyArg_ParseTuple(args, "s#:set_session_id", &buf, &len))
618 return NULL;
619
620 if (!SSL_CTX_set_session_id_context(self->ctx, buf, len))
621 {
622 exception_from_error_queue();
623 return NULL;
624 }
625 else
626 {
627 Py_INCREF(Py_None);
628 return Py_None;
629 }
630}
631
632static char ssl_Context_set_verify_doc[] = "\n\
633Set the verify mode and verify callback\n\
634\n\
635Arguments: self - The Context object\n\
636 args - The Python argument tuple, should be:\n\
Jean-Paul Calderone24aedf42008-03-06 22:01:16 -0500637 mode - The verify mode, this is either VERIFY_NONE or\n\
638 VERIFY_PEER combined with possible other flags\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500639 callback - The Python callback to use\n\
640Returns: None\n\
Jean-Paul Calderone24aedf42008-03-06 22:01:16 -0500641\n\
642See SSL_CTX_set_verify(3SSL) for further details.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500643";
644static PyObject *
645ssl_Context_set_verify(ssl_ContextObj *self, PyObject *args)
646{
647 int mode;
648 PyObject *callback = NULL;
649
650 if (!PyArg_ParseTuple(args, "iO:set_verify", &mode, &callback))
651 return NULL;
652
653 if (!PyCallable_Check(callback))
654 {
655 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
656 return NULL;
657 }
658
659 Py_DECREF(self->verify_callback);
660 Py_INCREF(callback);
661 self->verify_callback = callback;
662 SSL_CTX_set_verify(self->ctx, mode, global_verify_callback);
663
664 Py_INCREF(Py_None);
665 return Py_None;
666}
667
668static char ssl_Context_set_verify_depth_doc[] = "\n\
669Set the verify depth\n\
670\n\
671Arguments: self - The Context object\n\
672 args - The Python argument tuple, should be:\n\
673 depth - An integer specifying the verify depth\n\
674Returns: None\n\
675";
676static PyObject *
677ssl_Context_set_verify_depth(ssl_ContextObj *self, PyObject *args)
678{
679 int depth;
680
681 if (!PyArg_ParseTuple(args, "i:set_verify_depth", &depth))
682 return NULL;
683
684 SSL_CTX_set_verify_depth(self->ctx, depth);
685 Py_INCREF(Py_None);
686 return Py_None;
687}
688
689static char ssl_Context_get_verify_mode_doc[] = "\n\
690Get the verify mode\n\
691\n\
692Arguments: self - The Context object\n\
693 args - The Python argument tuple, should be empty\n\
694Returns: The verify mode\n\
695";
696static PyObject *
697ssl_Context_get_verify_mode(ssl_ContextObj *self, PyObject *args)
698{
699 int mode;
700
701 if (!PyArg_ParseTuple(args, ":get_verify_mode"))
702 return NULL;
703
704 mode = SSL_CTX_get_verify_mode(self->ctx);
705 return PyInt_FromLong((long)mode);
706}
707
708static char ssl_Context_get_verify_depth_doc[] = "\n\
709Get the verify depth\n\
710\n\
711Arguments: self - The Context object\n\
712 args - The Python argument tuple, should be empty\n\
713Returns: The verify depth\n\
714";
715static PyObject *
716ssl_Context_get_verify_depth(ssl_ContextObj *self, PyObject *args)
717{
718 int depth;
719
720 if (!PyArg_ParseTuple(args, ":get_verify_depth"))
721 return NULL;
722
723 depth = SSL_CTX_get_verify_depth(self->ctx);
724 return PyInt_FromLong((long)depth);
725}
726
727static char ssl_Context_load_tmp_dh_doc[] = "\n\
728Load parameters for Ephemeral Diffie-Hellman\n\
729\n\
730Arguments: self - The Context object\n\
731 args - The Python argument tuple, should be:\n\
732 dhfile - The file to load EDH parameters from\n\
733Returns: None\n\
734";
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\
761Arguments: self - The Context object\n\
762 args - The Python argument tuple, should be:\n\
763 cipher_list - A cipher list, see ciphers(1)\n\
764Returns: None\n\
765";
766static PyObject *
767ssl_Context_set_cipher_list(ssl_ContextObj *self, PyObject *args)
768{
769 char *cipher_list;
770
771 if (!PyArg_ParseTuple(args, "s:set_cipher_list", &cipher_list))
772 return NULL;
773
774 if (!SSL_CTX_set_cipher_list(self->ctx, cipher_list))
775 {
776 exception_from_error_queue();
777 return NULL;
778 }
779 else
780 {
781 Py_INCREF(Py_None);
782 return Py_None;
783 }
784}
785
786static char ssl_Context_set_timeout_doc[] = "\n\
787Set session timeout\n\
788\n\
789Arguments: self - The Context object\n\
790 args - The Python argument tuple, should be:\n\
791 t - The timeout in seconds\n\
792Returns: The previous session timeout\n\
793";
794static PyObject *
795ssl_Context_set_timeout(ssl_ContextObj *self, PyObject *args)
796{
797 long t, ret;
798
799 if (!PyArg_ParseTuple(args, "l:set_timeout", &t))
800 return NULL;
801
802 ret = SSL_CTX_set_timeout(self->ctx, t);
803 return PyLong_FromLong(ret);
804}
805
806static char ssl_Context_get_timeout_doc[] = "\n\
807Get the session timeout\n\
808\n\
809Arguments: self - The Context object\n\
810 args - The Python argument tuple, should be empty\n\
811Returns: The session timeout\n\
812";
813static PyObject *
814ssl_Context_get_timeout(ssl_ContextObj *self, PyObject *args)
815{
816 long ret;
817
818 if (!PyArg_ParseTuple(args, ":get_timeout"))
819 return NULL;
820
821 ret = SSL_CTX_get_timeout(self->ctx);
822 return PyLong_FromLong(ret);
823}
824
825static char ssl_Context_set_info_callback_doc[] = "\n\
826Set the info callback\n\
827\n\
828Arguments: self - The Context object\n\
829 args - The Python argument tuple, should be:\n\
830 callback - The Python callback to use\n\
831Returns: None\n\
832";
833static PyObject *
834ssl_Context_set_info_callback(ssl_ContextObj *self, PyObject *args)
835{
836 PyObject *callback;
837
838 if (!PyArg_ParseTuple(args, "O:set_info_callback", &callback))
839 return NULL;
840
841 if (!PyCallable_Check(callback))
842 {
843 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
844 return NULL;
845 }
846
847 Py_DECREF(self->info_callback);
848 Py_INCREF(callback);
849 self->info_callback = callback;
850 SSL_CTX_set_info_callback(self->ctx, global_info_callback);
851
852 Py_INCREF(Py_None);
853 return Py_None;
854}
855
856static char ssl_Context_get_app_data_doc[] = "\n\
857Get the application data (supplied via set_app_data())\n\
858\n\
859Arguments: self - The Context object\n\
860 args - The Python argument tuple, should be empty\n\
861Returns: The application data\n\
862";
863static PyObject *
864ssl_Context_get_app_data(ssl_ContextObj *self, PyObject *args)
865{
866 if (!PyArg_ParseTuple(args, ":get_app_data"))
867 return NULL;
868
869 Py_INCREF(self->app_data);
870 return self->app_data;
871}
872
873static char ssl_Context_set_app_data_doc[] = "\n\
874Set the application data (will be returned from get_app_data())\n\
875\n\
876Arguments: self - The Context object\n\
877 args - The Python argument tuple, should be:\n\
878 data - Any Python object\n\
879Returns: None\n\
880";
881static PyObject *
882ssl_Context_set_app_data(ssl_ContextObj *self, PyObject *args)
883{
884 PyObject *data;
885
886 if (!PyArg_ParseTuple(args, "O:set_app_data", &data))
887 return NULL;
888
889 Py_DECREF(self->app_data);
890 Py_INCREF(data);
891 self->app_data = data;
892
893 Py_INCREF(Py_None);
894 return Py_None;
895}
896
897static char ssl_Context_get_cert_store_doc[] = "\n\
898Get the certificate store for the context\n\
899\n\
900Arguments: self - The Context object\n\
901 args - The Python argument tuple, should be empty\n\
902Returns: A X509Store object\n\
903";
904static PyObject *
905ssl_Context_get_cert_store(ssl_ContextObj *self, PyObject *args)
906{
907 X509_STORE *store;
908
909 if (!PyArg_ParseTuple(args, ":get_cert_store"))
910 return NULL;
911
912 if ((store = SSL_CTX_get_cert_store(self->ctx)) == NULL)
913 {
914 Py_INCREF(Py_None);
915 return Py_None;
916 }
917 else
918 {
919 return (PyObject *)crypto_X509Store_New(store, 0);
920 }
921}
922
923static char ssl_Context_set_options_doc[] = "\n\
924Add options. Options set before are not cleared!\n\
925\n\
926Arguments: self - The Context object\n\
927 args - The Python argument tuple, should be:\n\
928 options - The options to add.\n\
929Returns: The new option bitmask.\n\
930";
931static PyObject *
932ssl_Context_set_options(ssl_ContextObj *self, PyObject *args)
933{
934 long options;
935
936 if (!PyArg_ParseTuple(args, "l:set_options", &options))
937 return NULL;
938
939 return PyInt_FromLong(SSL_CTX_set_options(self->ctx, options));
940}
941
942
943/*
944 * Member methods in the Context object
945 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
946 * { 'name', (PyCFunction)ssl_Context_name, METH_VARARGS }
947 * for convenience
948 * ADD_ALIAS(name,real) creates an "alias" of the ssl_Context_real
949 * function with the name 'name'
950 */
951#define ADD_METHOD(name) { #name, (PyCFunction)ssl_Context_##name, METH_VARARGS, ssl_Context_##name##_doc }
952static PyMethodDef ssl_Context_methods[] = {
953 ADD_METHOD(load_verify_locations),
954 ADD_METHOD(set_passwd_cb),
955 ADD_METHOD(use_certificate_chain_file),
956 ADD_METHOD(use_certificate_file),
957 ADD_METHOD(use_certificate),
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500958 ADD_METHOD(add_extra_chain_cert),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500959 ADD_METHOD(use_privatekey_file),
960 ADD_METHOD(use_privatekey),
961 ADD_METHOD(check_privatekey),
962 ADD_METHOD(load_client_ca),
963 ADD_METHOD(set_session_id),
964 ADD_METHOD(set_verify),
965 ADD_METHOD(set_verify_depth),
966 ADD_METHOD(get_verify_mode),
967 ADD_METHOD(get_verify_depth),
968 ADD_METHOD(load_tmp_dh),
969 ADD_METHOD(set_cipher_list),
970 ADD_METHOD(set_timeout),
971 ADD_METHOD(get_timeout),
972 ADD_METHOD(set_info_callback),
973 ADD_METHOD(get_app_data),
974 ADD_METHOD(set_app_data),
975 ADD_METHOD(get_cert_store),
976 ADD_METHOD(set_options),
977 { NULL, NULL }
978};
979#undef ADD_METHOD
980
981
982/* Constructor, takes an int specifying which method to use */
983/*
984 * Constructor for Context objects
985 *
986 * Arguments: i_method - The SSL method to use, one of the SSLv2_METHOD,
987 * SSLv3_METHOD, SSLv23_METHOD and TLSv1_METHOD
988 * constants.
989 * Returns: The newly created Context object
990 */
991ssl_ContextObj *
992ssl_Context_New(int i_method)
993{
994 SSL_METHOD *method;
995 ssl_ContextObj *self;
996
997 switch (i_method)
998 {
999 /* Too bad TLSv1 servers can't accept SSLv3 clients */
1000 case ssl_SSLv2_METHOD: method = SSLv2_method(); break;
1001 case ssl_SSLv23_METHOD: method = SSLv23_method(); break;
1002 case ssl_SSLv3_METHOD: method = SSLv3_method(); break;
1003 case ssl_TLSv1_METHOD: method = TLSv1_method(); break;
1004 default:
1005 PyErr_SetString(PyExc_ValueError, "No such protocol");
1006 return NULL;
1007 }
1008
1009 self = PyObject_GC_New(ssl_ContextObj, &ssl_Context_Type);
1010 if (self == NULL)
1011 return (ssl_ContextObj *)PyErr_NoMemory();
1012
1013 self->ctx = SSL_CTX_new(method);
1014 Py_INCREF(Py_None);
1015 self->passphrase_callback = Py_None;
1016 Py_INCREF(Py_None);
1017 self->verify_callback = Py_None;
1018 Py_INCREF(Py_None);
1019 self->info_callback = Py_None;
1020
1021 Py_INCREF(Py_None);
1022 self->passphrase_userdata = Py_None;
1023
1024 Py_INCREF(Py_None);
1025 self->app_data = Py_None;
1026
1027 /* Some initialization that's required to operate smoothly in Python */
1028 SSL_CTX_set_app_data(self->ctx, self);
1029 SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
1030 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1031 SSL_MODE_AUTO_RETRY);
1032
1033 self->tstate = NULL;
1034 PyObject_GC_Track((PyObject *)self);
1035
1036 return self;
1037}
1038
1039/*
1040 * Find attribute
1041 *
1042 * Arguments: self - The Context object
1043 * name - The attribute name
1044 * Returns: A Python object for the attribute, or NULL if something went
1045 * wrong
1046 */
1047static PyObject *
1048ssl_Context_getattr(ssl_ContextObj *self, char *name)
1049{
1050 return Py_FindMethod(ssl_Context_methods, (PyObject *)self, name);
1051}
1052
1053/*
1054 * Call the visitproc on all contained objects.
1055 *
1056 * Arguments: self - The Context object
1057 * visit - Function to call
1058 * arg - Extra argument to visit
1059 * Returns: 0 if all goes well, otherwise the return code from the first
1060 * call that gave non-zero result.
1061 */
1062static int
1063ssl_Context_traverse(ssl_ContextObj *self, visitproc visit, void *arg)
1064{
1065 int ret = 0;
1066
1067 if (ret == 0 && self->passphrase_callback != NULL)
1068 ret = visit((PyObject *)self->passphrase_callback, arg);
1069 if (ret == 0 && self->passphrase_userdata != NULL)
1070 ret = visit((PyObject *)self->passphrase_userdata, arg);
1071 if (ret == 0 && self->verify_callback != NULL)
1072 ret = visit((PyObject *)self->verify_callback, arg);
1073 if (ret == 0 && self->info_callback != NULL)
1074 ret = visit((PyObject *)self->info_callback, arg);
1075 if (ret == 0 && self->app_data != NULL)
1076 ret = visit(self->app_data, arg);
1077 return ret;
1078}
1079
1080/*
1081 * Decref all contained objects and zero the pointers.
1082 *
1083 * Arguments: self - The Context object
1084 * Returns: Always 0.
1085 */
1086static int
1087ssl_Context_clear(ssl_ContextObj *self)
1088{
1089 Py_XDECREF(self->passphrase_callback);
1090 self->passphrase_callback = NULL;
1091 Py_XDECREF(self->passphrase_userdata);
1092 self->passphrase_userdata = NULL;
1093 Py_XDECREF(self->verify_callback);
1094 self->verify_callback = NULL;
1095 Py_XDECREF(self->info_callback);
1096 self->info_callback = NULL;
1097 Py_XDECREF(self->app_data);
1098 self->app_data = NULL;
1099 return 0;
1100}
1101
1102/*
1103 * Deallocate the memory used by the Context object
1104 *
1105 * Arguments: self - The Context object
1106 * Returns: None
1107 */
1108static void
1109ssl_Context_dealloc(ssl_ContextObj *self)
1110{
1111 PyObject_GC_UnTrack((PyObject *)self);
1112 SSL_CTX_free(self->ctx);
1113 ssl_Context_clear(self);
1114 PyObject_GC_Del(self);
1115}
1116
1117
1118PyTypeObject ssl_Context_Type = {
1119 PyObject_HEAD_INIT(NULL)
1120 0,
1121 "Context",
1122 sizeof(ssl_ContextObj),
1123 0,
1124 (destructor)ssl_Context_dealloc,
1125 NULL, /* print */
1126 (getattrfunc)ssl_Context_getattr,
1127 NULL, /* setattr */
1128 NULL, /* compare */
1129 NULL, /* repr */
1130 NULL, /* as_number */
1131 NULL, /* as_sequence */
1132 NULL, /* as_mapping */
1133 NULL, /* hash */
1134 NULL, /* call */
1135 NULL, /* str */
1136 NULL, /* getattro */
1137 NULL, /* setattro */
1138 NULL, /* as_buffer */
1139 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1140 NULL, /* doc */
1141 (traverseproc)ssl_Context_traverse,
1142 (inquiry)ssl_Context_clear,
1143};
1144
1145
1146/*
1147 * Initialize the Context part of the SSL sub module
1148 *
1149 * Arguments: dict - Dictionary of the OpenSSL.SSL module
1150 * Returns: 1 for success, 0 otherwise
1151 */
1152int
1153init_ssl_context(PyObject *dict)
1154{
1155 ssl_Context_Type.ob_type = &PyType_Type;
1156 Py_INCREF(&ssl_Context_Type);
1157 if (PyDict_SetItemString(dict, "ContextType", (PyObject *)&ssl_Context_Type) != 0)
1158 return 0;
1159
1160 return 1;
1161}
1162