blob: 93f1c83e5971a10dbb2fb9f752819fd7c4075a9b [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
5 *
6 * SSL Context objects and their methods.
7 * See the file RATIONALE for a short explanation of why this module was written.
8 *
9 * Reviewed 2001-07-23
10 */
11#include <Python.h>
12#define SSL_MODULE
13#include "ssl.h"
14
15static char *CVSid = "@(#) $Id: context.c,v 1.17 2004/08/06 10:21:56 martin Exp $";
16
17/*
18 * CALLBACKS
19 *
20 * Callbacks work like this: We provide a "global" callback in C which
21 * transforms the arguments into a Python argument tuple and calls the
22 * corresponding Python callback, and then parsing the return value back into
23 * things the C function can return.
24 *
25 * Three caveats:
26 * + How do we find the Context object where the Python callbacks are stored?
27 * + What about multithreading and execution frames?
28 * + What about Python callbacks that raise exceptions?
29 *
30 * The solution to the first issue is trivial if the callback provides
31 * "userdata" functionality. Since the only callbacks that don't provide
32 * userdata do provide a pointer to an SSL structure, we can associate an SSL
33 * object and a Connection one-to-one via the SSL_set/get_app_data()
34 * functions.
35 *
36 * The solution to the other issue is to rewrite the Py_BEGIN_ALLOW_THREADS
37 * macro allowing it (or rather a new macro) to specify where to save the
38 * thread state (in our case, as a member of the Connection/Context object) so
39 * we can retrieve it again before calling the Python callback.
40 */
41
42/*
43 * Globally defined passphrase callback.
44 *
45 * Arguments: buf - Buffer to store the returned passphrase in
46 * maxlen - Maximum length of the passphrase
47 * verify - If true, the passphrase callback should ask for a
48 * password twice and verify they're equal. If false, only
49 * ask once.
50 * arg - User data, always a Context object
51 * Returns: The length of the password if successful, 0 otherwise
52 */
53static int
54global_passphrase_callback(char *buf, int maxlen, int verify, void *arg)
55{
56 int len;
57 char *str;
58 PyObject *argv, *ret = NULL;
59 ssl_ContextObj *ctx = (ssl_ContextObj *)arg;
60
61 /* The Python callback is called with a (maxlen,verify,userdata) tuple */
62 argv = Py_BuildValue("(iiO)", maxlen, verify, ctx->passphrase_userdata);
63 if (ctx->tstate != NULL)
64 {
65 /* We need to get back our thread state before calling the callback */
66 MY_END_ALLOW_THREADS(ctx->tstate);
67 ret = PyEval_CallObject(ctx->passphrase_callback, argv);
68 MY_BEGIN_ALLOW_THREADS(ctx->tstate);
69 }
70 else
71 {
72 ret = PyEval_CallObject(ctx->passphrase_callback, argv);
73 }
74 Py_DECREF(argv);
75
76 if (ret == NULL)
77 return 0;
78
79 if (!PyObject_IsTrue(ret))
80 {
81 Py_DECREF(ret);
82 return 0;
83 }
84
85 if (!PyString_Check(ret))
86 {
87 Py_DECREF(ret);
88 return 0;
89 }
90
91 len = PyString_Size(ret);
92 if (len > maxlen)
93 len = maxlen;
94
95 str = PyString_AsString(ret);
96 strncpy(buf, str, len);
97 Py_XDECREF(ret);
98
99 return len;
100}
101
102/*
103 * Globally defined verify callback
104 *
105 * Arguments: ok - True everything is OK "so far", false otherwise
106 * x509_ctx - Contains the certificate being checked, the current
107 * error number and depth, and the Connection we're
108 * dealing with
109 * Returns: True if everything is okay, false otherwise
110 */
111static int
112global_verify_callback(int ok, X509_STORE_CTX *x509_ctx)
113{
114 PyObject *argv, *ret;
115 SSL *ssl;
116 ssl_ConnectionObj *conn;
117 crypto_X509Obj *cert;
118 int errnum, errdepth, c_ret;
119
120 cert = crypto_X509_New(X509_STORE_CTX_get_current_cert(x509_ctx), 0);
121 errnum = X509_STORE_CTX_get_error(x509_ctx);
122 errdepth = X509_STORE_CTX_get_error_depth(x509_ctx);
123 ssl = (SSL *)X509_STORE_CTX_get_app_data(x509_ctx);
124 conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl);
125
126 argv = Py_BuildValue("(OOiii)", (PyObject *)conn, (PyObject *)cert,
127 errnum, errdepth, ok);
128 Py_DECREF(cert);
129 if (conn->tstate != NULL)
130 {
131 /* We need to get back our thread state before calling the callback */
132 MY_END_ALLOW_THREADS(conn->tstate);
133 ret = PyEval_CallObject(conn->context->verify_callback, argv);
134 MY_BEGIN_ALLOW_THREADS(conn->tstate);
135 }
136 else
137 {
138 ret = PyEval_CallObject(conn->context->verify_callback, argv);
139 }
140 Py_DECREF(argv);
141
142 if (ret == NULL)
143 return 0;
144
145 if (PyObject_IsTrue(ret))
146 {
147 X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
148 c_ret = 1;
149 }
150 else
151 c_ret = 0;
152
153 Py_DECREF(ret);
154
155 return c_ret;
156}
157
158/*
159 * Globally defined info callback
160 *
161 * Arguments: ssl - The Connection
162 * where - The part of the SSL code that called us
163 * _ret - The return code of the SSL function that called us
164 * Returns: None
165 */
166static void
167global_info_callback(SSL *ssl, int where, int _ret)
168{
169 ssl_ConnectionObj *conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl);
170 PyObject *argv, *ret;
171
172 argv = Py_BuildValue("(Oii)", (PyObject *)conn, where, _ret);
173 if (conn->tstate != NULL)
174 {
175 /* We need to get back our thread state before calling the callback */
176 MY_END_ALLOW_THREADS(conn->tstate);
177 ret = PyEval_CallObject(conn->context->info_callback, argv);
178 if (ret == NULL)
179 PyErr_Clear();
180 else
181 Py_DECREF(ret);
182 MY_BEGIN_ALLOW_THREADS(conn->tstate);
183 }
184 else
185 {
186 ret = PyEval_CallObject(conn->context->info_callback, argv);
187 if (ret == NULL)
188 PyErr_Clear();
189 else
190 Py_DECREF(ret);
191 }
192 Py_DECREF(argv);
193
194 return;
195}
196
197
198
199
200static char ssl_Context_load_verify_locations_doc[] = "\n\
201Let SSL know where we can find trusted certificates for the certificate\n\
202chain\n\
203\n\
204Arguments: self - The Context object\n\
205 args - The Python argument tuple, should be:\n\
206 cafile - Which file we can find the certificates\n\
207Returns: None\n\
208";
209static PyObject *
210ssl_Context_load_verify_locations(ssl_ContextObj *self, PyObject *args)
211{
212 char *cafile;
213
214 if (!PyArg_ParseTuple(args, "s:load_verify_locations", &cafile))
215 return NULL;
216
217 if (!SSL_CTX_load_verify_locations(self->ctx, cafile, NULL))
218 {
219 exception_from_error_queue();
220 return NULL;
221 }
222 else
223 {
224 Py_INCREF(Py_None);
225 return Py_None;
226 }
227}
228
229static char ssl_Context_set_passwd_cb_doc[] = "\n\
230Set the passphrase callback\n\
231\n\
232Arguments: self - The Context object\n\
233 args - The Python argument tuple, should be:\n\
234 callback - The Python callback to use\n\
235 userdata - (optional) A Python object which will be given as\n\
236 argument to the callback\n\
237Returns: None\n\
238";
239static PyObject *
240ssl_Context_set_passwd_cb(ssl_ContextObj *self, PyObject *args)
241{
242 PyObject *callback = NULL, *userdata = Py_None;
243
244 if (!PyArg_ParseTuple(args, "O|O:set_passwd_cb", &callback, &userdata))
245 return NULL;
246
247 if (!PyCallable_Check(callback))
248 {
249 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
250 return NULL;
251 }
252
253 Py_DECREF(self->passphrase_callback);
254 Py_INCREF(callback);
255 self->passphrase_callback = callback;
256 SSL_CTX_set_default_passwd_cb(self->ctx, global_passphrase_callback);
257
258 Py_DECREF(self->passphrase_userdata);
259 Py_INCREF(userdata);
260 self->passphrase_userdata = userdata;
261 SSL_CTX_set_default_passwd_cb_userdata(self->ctx, (void *)self);
262
263 Py_INCREF(Py_None);
264 return Py_None;
265}
266
267static char ssl_Context_use_certificate_chain_file_doc[] = "\n\
268Load a certificate chain from a file\n\
269\n\
270Arguments: self - The Context object\n\
271 args - The Python argument tuple, should be:\n\
272 certfile - The name of the certificate chain file\n\
273Returns: None\n\
274";
275static PyObject *
276ssl_Context_use_certificate_chain_file(ssl_ContextObj *self, PyObject *args)
277{
278 char *certfile;
279
280 if (!PyArg_ParseTuple(args, "s:use_certificate_chain_file", &certfile))
281 return NULL;
282
283 if (!SSL_CTX_use_certificate_chain_file(self->ctx, certfile))
284 {
285 exception_from_error_queue();
286 return NULL;
287 }
288 else
289 {
290 Py_INCREF(Py_None);
291 return Py_None;
292 }
293}
294
295
296static char ssl_Context_use_certificate_file_doc[] = "\n\
297Load a certificate from a file\n\
298\n\
299Arguments: self - The Context object\n\
300 args - The Python argument tuple, should be:\n\
301 certfile - The name of the certificate file\n\
302 filetype - (optional) The encoding of the file, default is PEM\n\
303Returns: None\n\
304";
305static PyObject *
306ssl_Context_use_certificate_file(ssl_ContextObj *self, PyObject *args)
307{
308 char *certfile;
309 int filetype = SSL_FILETYPE_PEM;
310
311 if (!PyArg_ParseTuple(args, "s|i:use_certificate_file", &certfile, &filetype))
312 return NULL;
313
314 if (!SSL_CTX_use_certificate_file(self->ctx, certfile, filetype))
315 {
316 exception_from_error_queue();
317 return NULL;
318 }
319 else
320 {
321 Py_INCREF(Py_None);
322 return Py_None;
323 }
324}
325
326static char ssl_Context_use_certificate_doc[] = "\n\
327Load a certificate from a X509 object\n\
328\n\
329Arguments: self - The Context object\n\
330 args - The Python argument tuple, should be:\n\
331 cert - The X509 object\n\
332Returns: None\n\
333";
334static PyObject *
335ssl_Context_use_certificate(ssl_ContextObj *self, PyObject *args)
336{
337 static PyTypeObject *crypto_X509_type = NULL;
338 crypto_X509Obj *cert;
339
340 /* We need to check that cert really is an X509 object before
341 we deal with it. The problem is we can't just quickly verify
342 the type (since that comes from another module). This should
343 do the trick (reasonably well at least): Once we have one
344 verified object, we use it's type object for future
345 comparisons. */
346
347 if (!crypto_X509_type)
348 {
349 if (!PyArg_ParseTuple(args, "O:use_certificate", &cert))
350 return NULL;
351
352 if (strcmp(cert->ob_type->tp_name, "X509") != 0 ||
353 cert->ob_type->tp_basicsize != sizeof(crypto_X509Obj))
354 {
355 PyErr_SetString(PyExc_TypeError, "Expected an X509 object");
356 return NULL;
357 }
358
359 crypto_X509_type = cert->ob_type;
360 }
361 else
362 if (!PyArg_ParseTuple(args, "O!:use_certificate", crypto_X509_type,
363 &cert))
364 return NULL;
365
366 if (!SSL_CTX_use_certificate(self->ctx, cert->x509))
367 {
368 exception_from_error_queue();
369 return NULL;
370 }
371 else
372 {
373 Py_INCREF(Py_None);
374 return Py_None;
375 }
376}
377
378static char ssl_Context_use_privatekey_file_doc[] = "\n\
379Load a private key from a file\n\
380\n\
381Arguments: self - The Context object\n\
382 args - The Python argument tuple, should be:\n\
383 keyfile - The name of the key file\n\
384 filetype - (optional) The encoding of the file, default is PEM\n\
385Returns: None\n\
386";
387static PyObject *
388ssl_Context_use_privatekey_file(ssl_ContextObj *self, PyObject *args)
389{
390 char *keyfile;
391 int filetype = SSL_FILETYPE_PEM, ret;
392
393 if (!PyArg_ParseTuple(args, "s|i:use_privatekey_file", &keyfile, &filetype))
394 return NULL;
395
396 MY_BEGIN_ALLOW_THREADS(self->tstate);
397 ret = SSL_CTX_use_PrivateKey_file(self->ctx, keyfile, filetype);
398 MY_END_ALLOW_THREADS(self->tstate);
399
400 if (PyErr_Occurred())
401 {
402 flush_error_queue();
403 return NULL;
404 }
405
406 if (!ret)
407 {
408 exception_from_error_queue();
409 return NULL;
410 }
411 else
412 {
413 Py_INCREF(Py_None);
414 return Py_None;
415 }
416}
417
418static char ssl_Context_use_privatekey_doc[] = "\n\
419Load a private key from a PKey object\n\
420\n\
421Arguments: self - The Context object\n\
422 args - The Python argument tuple, should be:\n\
423 pkey - The PKey object\n\
424Returns: None\n\
425";
426static PyObject *
427ssl_Context_use_privatekey(ssl_ContextObj *self, PyObject *args)
428{
429 static PyTypeObject *crypto_PKey_type = NULL;
430 crypto_PKeyObj *pkey;
431
432 /* We need to check that cert really is a PKey object before
433 we deal with it. The problem is we can't just quickly verify
434 the type (since that comes from another module). This should
435 do the trick (reasonably well at least): Once we have one
436 verified object, we use it's type object for future
437 comparisons. */
438
439 if (!crypto_PKey_type)
440 {
441 if (!PyArg_ParseTuple(args, "O:use_privatekey", &pkey))
442 return NULL;
443
444 if (strcmp(pkey->ob_type->tp_name, "PKey") != 0 ||
445 pkey->ob_type->tp_basicsize != sizeof(crypto_PKeyObj))
446 {
447 PyErr_SetString(PyExc_TypeError, "Expected a PKey object");
448 return NULL;
449 }
450
451 crypto_PKey_type = pkey->ob_type;
452 }
453 else
454 if (!PyArg_ParseTuple(args, "O!:use_privatekey", crypto_PKey_type, &pkey))
455 return NULL;
456
457 if (!SSL_CTX_use_PrivateKey(self->ctx, pkey->pkey))
458 {
459 exception_from_error_queue();
460 return NULL;
461 }
462 else
463 {
464 Py_INCREF(Py_None);
465 return Py_None;
466 }
467}
468
469static char ssl_Context_check_privatekey_doc[] = "\n\
470Check that the private key and certificate match up\n\
471\n\
472Arguments: self - The Context object\n\
473 args - The Python argument tuple, should be empty\n\
474Returns: None (raises an exception if something's wrong)\n\
475";
476static PyObject *
477ssl_Context_check_privatekey(ssl_ContextObj *self, PyObject *args)
478{
479 if (!PyArg_ParseTuple(args, ":check_privatekey"))
480 return NULL;
481
482 if (!SSL_CTX_check_private_key(self->ctx))
483 {
484 exception_from_error_queue();
485 return NULL;
486 }
487 else
488 {
489 Py_INCREF(Py_None);
490 return Py_None;
491 }
492}
493
494static char ssl_Context_load_client_ca_doc[] = "\n\
495Load the trusted certificates that will be sent to the client (basically\n\
496telling the client \"These are the guys I trust\")\n\
497\n\
498Arguments: self - The Context object\n\
499 args - The Python argument tuple, should be:\n\
500 cafile - The name of the certificates file\n\
501Returns: None\n\
502";
503static PyObject *
504ssl_Context_load_client_ca(ssl_ContextObj *self, PyObject *args)
505{
506 char *cafile;
507
508 if (!PyArg_ParseTuple(args, "s:load_client_ca", &cafile))
509 return NULL;
510
511 SSL_CTX_set_client_CA_list(self->ctx, SSL_load_client_CA_file(cafile));
512
513 Py_INCREF(Py_None);
514 return Py_None;
515}
516
517static char ssl_Context_set_session_id_doc[] = "\n\
518Set the session identifier, this is needed if you want to do session\n\
519resumption (which, ironically, isn't implemented yet)\n\
520\n\
521Arguments: self - The Context object\n\
522 args - The Python argument tuple, should be:\n\
523 buf - A Python object that can be safely converted to a string\n\
524Returns: None\n\
525";
526static PyObject *
527ssl_Context_set_session_id(ssl_ContextObj *self, PyObject *args)
528{
529 char *buf;
530 int len;
531
532 if (!PyArg_ParseTuple(args, "s#:set_session_id", &buf, &len))
533 return NULL;
534
535 if (!SSL_CTX_set_session_id_context(self->ctx, buf, len))
536 {
537 exception_from_error_queue();
538 return NULL;
539 }
540 else
541 {
542 Py_INCREF(Py_None);
543 return Py_None;
544 }
545}
546
547static char ssl_Context_set_verify_doc[] = "\n\
548Set the verify mode and verify callback\n\
549\n\
550Arguments: self - The Context object\n\
551 args - The Python argument tuple, should be:\n\
552 mode - The verify mode, this is either SSL_VERIFY_NONE or\n\
553 SSL_VERIFY_PEER combined with possible other flags\n\
554 callback - The Python callback to use\n\
555Returns: None\n\
556";
557static PyObject *
558ssl_Context_set_verify(ssl_ContextObj *self, PyObject *args)
559{
560 int mode;
561 PyObject *callback = NULL;
562
563 if (!PyArg_ParseTuple(args, "iO:set_verify", &mode, &callback))
564 return NULL;
565
566 if (!PyCallable_Check(callback))
567 {
568 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
569 return NULL;
570 }
571
572 Py_DECREF(self->verify_callback);
573 Py_INCREF(callback);
574 self->verify_callback = callback;
575 SSL_CTX_set_verify(self->ctx, mode, global_verify_callback);
576
577 Py_INCREF(Py_None);
578 return Py_None;
579}
580
581static char ssl_Context_set_verify_depth_doc[] = "\n\
582Set the verify depth\n\
583\n\
584Arguments: self - The Context object\n\
585 args - The Python argument tuple, should be:\n\
586 depth - An integer specifying the verify depth\n\
587Returns: None\n\
588";
589static PyObject *
590ssl_Context_set_verify_depth(ssl_ContextObj *self, PyObject *args)
591{
592 int depth;
593
594 if (!PyArg_ParseTuple(args, "i:set_verify_depth", &depth))
595 return NULL;
596
597 SSL_CTX_set_verify_depth(self->ctx, depth);
598 Py_INCREF(Py_None);
599 return Py_None;
600}
601
602static char ssl_Context_get_verify_mode_doc[] = "\n\
603Get the verify mode\n\
604\n\
605Arguments: self - The Context object\n\
606 args - The Python argument tuple, should be empty\n\
607Returns: The verify mode\n\
608";
609static PyObject *
610ssl_Context_get_verify_mode(ssl_ContextObj *self, PyObject *args)
611{
612 int mode;
613
614 if (!PyArg_ParseTuple(args, ":get_verify_mode"))
615 return NULL;
616
617 mode = SSL_CTX_get_verify_mode(self->ctx);
618 return PyInt_FromLong((long)mode);
619}
620
621static char ssl_Context_get_verify_depth_doc[] = "\n\
622Get the verify depth\n\
623\n\
624Arguments: self - The Context object\n\
625 args - The Python argument tuple, should be empty\n\
626Returns: The verify depth\n\
627";
628static PyObject *
629ssl_Context_get_verify_depth(ssl_ContextObj *self, PyObject *args)
630{
631 int depth;
632
633 if (!PyArg_ParseTuple(args, ":get_verify_depth"))
634 return NULL;
635
636 depth = SSL_CTX_get_verify_depth(self->ctx);
637 return PyInt_FromLong((long)depth);
638}
639
640static char ssl_Context_load_tmp_dh_doc[] = "\n\
641Load parameters for Ephemeral Diffie-Hellman\n\
642\n\
643Arguments: self - The Context object\n\
644 args - The Python argument tuple, should be:\n\
645 dhfile - The file to load EDH parameters from\n\
646Returns: None\n\
647";
648static PyObject *
649ssl_Context_load_tmp_dh(ssl_ContextObj *self, PyObject *args)
650{
651 char *dhfile;
652 BIO *bio;
653 DH *dh;
654
655 if (!PyArg_ParseTuple(args, "s:load_tmp_dh", &dhfile))
656 return NULL;
657
658 bio = BIO_new_file(dhfile, "r");
659 if (bio == NULL)
660 return PyErr_NoMemory();
661
662 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
663 SSL_CTX_set_tmp_dh(self->ctx, dh);
664 DH_free(dh);
665 BIO_free(bio);
666
667 Py_INCREF(Py_None);
668 return Py_None;
669}
670
671static char ssl_Context_set_cipher_list_doc[] = "\n\
672Change the cipher list\n\
673\n\
674Arguments: self - The Context object\n\
675 args - The Python argument tuple, should be:\n\
676 cipher_list - A cipher list, see ciphers(1)\n\
677Returns: None\n\
678";
679static PyObject *
680ssl_Context_set_cipher_list(ssl_ContextObj *self, PyObject *args)
681{
682 char *cipher_list;
683
684 if (!PyArg_ParseTuple(args, "s:set_cipher_list", &cipher_list))
685 return NULL;
686
687 if (!SSL_CTX_set_cipher_list(self->ctx, cipher_list))
688 {
689 exception_from_error_queue();
690 return NULL;
691 }
692 else
693 {
694 Py_INCREF(Py_None);
695 return Py_None;
696 }
697}
698
699static char ssl_Context_set_timeout_doc[] = "\n\
700Set session timeout\n\
701\n\
702Arguments: self - The Context object\n\
703 args - The Python argument tuple, should be:\n\
704 t - The timeout in seconds\n\
705Returns: The previous session timeout\n\
706";
707static PyObject *
708ssl_Context_set_timeout(ssl_ContextObj *self, PyObject *args)
709{
710 long t, ret;
711
712 if (!PyArg_ParseTuple(args, "l:set_timeout", &t))
713 return NULL;
714
715 ret = SSL_CTX_set_timeout(self->ctx, t);
716 return PyLong_FromLong(ret);
717}
718
719static char ssl_Context_get_timeout_doc[] = "\n\
720Get the session timeout\n\
721\n\
722Arguments: self - The Context object\n\
723 args - The Python argument tuple, should be empty\n\
724Returns: The session timeout\n\
725";
726static PyObject *
727ssl_Context_get_timeout(ssl_ContextObj *self, PyObject *args)
728{
729 long ret;
730
731 if (!PyArg_ParseTuple(args, ":get_timeout"))
732 return NULL;
733
734 ret = SSL_CTX_get_timeout(self->ctx);
735 return PyLong_FromLong(ret);
736}
737
738static char ssl_Context_set_info_callback_doc[] = "\n\
739Set the info callback\n\
740\n\
741Arguments: self - The Context object\n\
742 args - The Python argument tuple, should be:\n\
743 callback - The Python callback to use\n\
744Returns: None\n\
745";
746static PyObject *
747ssl_Context_set_info_callback(ssl_ContextObj *self, PyObject *args)
748{
749 PyObject *callback;
750
751 if (!PyArg_ParseTuple(args, "O:set_info_callback", &callback))
752 return NULL;
753
754 if (!PyCallable_Check(callback))
755 {
756 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
757 return NULL;
758 }
759
760 Py_DECREF(self->info_callback);
761 Py_INCREF(callback);
762 self->info_callback = callback;
763 SSL_CTX_set_info_callback(self->ctx, global_info_callback);
764
765 Py_INCREF(Py_None);
766 return Py_None;
767}
768
769static char ssl_Context_get_app_data_doc[] = "\n\
770Get the application data (supplied via set_app_data())\n\
771\n\
772Arguments: self - The Context object\n\
773 args - The Python argument tuple, should be empty\n\
774Returns: The application data\n\
775";
776static PyObject *
777ssl_Context_get_app_data(ssl_ContextObj *self, PyObject *args)
778{
779 if (!PyArg_ParseTuple(args, ":get_app_data"))
780 return NULL;
781
782 Py_INCREF(self->app_data);
783 return self->app_data;
784}
785
786static char ssl_Context_set_app_data_doc[] = "\n\
787Set the application data (will be returned from get_app_data())\n\
788\n\
789Arguments: self - The Context object\n\
790 args - The Python argument tuple, should be:\n\
791 data - Any Python object\n\
792Returns: None\n\
793";
794static PyObject *
795ssl_Context_set_app_data(ssl_ContextObj *self, PyObject *args)
796{
797 PyObject *data;
798
799 if (!PyArg_ParseTuple(args, "O:set_app_data", &data))
800 return NULL;
801
802 Py_DECREF(self->app_data);
803 Py_INCREF(data);
804 self->app_data = data;
805
806 Py_INCREF(Py_None);
807 return Py_None;
808}
809
810static char ssl_Context_get_cert_store_doc[] = "\n\
811Get the certificate store for the context\n\
812\n\
813Arguments: self - The Context object\n\
814 args - The Python argument tuple, should be empty\n\
815Returns: A X509Store object\n\
816";
817static PyObject *
818ssl_Context_get_cert_store(ssl_ContextObj *self, PyObject *args)
819{
820 X509_STORE *store;
821
822 if (!PyArg_ParseTuple(args, ":get_cert_store"))
823 return NULL;
824
825 if ((store = SSL_CTX_get_cert_store(self->ctx)) == NULL)
826 {
827 Py_INCREF(Py_None);
828 return Py_None;
829 }
830 else
831 {
832 return (PyObject *)crypto_X509Store_New(store, 0);
833 }
834}
835
836static char ssl_Context_set_options_doc[] = "\n\
837Add options. Options set before are not cleared!\n\
838\n\
839Arguments: self - The Context object\n\
840 args - The Python argument tuple, should be:\n\
841 options - The options to add.\n\
842Returns: The new option bitmask.\n\
843";
844static PyObject *
845ssl_Context_set_options(ssl_ContextObj *self, PyObject *args)
846{
847 long options;
848
849 if (!PyArg_ParseTuple(args, "l:set_options", &options))
850 return NULL;
851
852 return PyInt_FromLong(SSL_CTX_set_options(self->ctx, options));
853}
854
855
856/*
857 * Member methods in the Context object
858 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
859 * { 'name', (PyCFunction)ssl_Context_name, METH_VARARGS }
860 * for convenience
861 * ADD_ALIAS(name,real) creates an "alias" of the ssl_Context_real
862 * function with the name 'name'
863 */
864#define ADD_METHOD(name) { #name, (PyCFunction)ssl_Context_##name, METH_VARARGS, ssl_Context_##name##_doc }
865static PyMethodDef ssl_Context_methods[] = {
866 ADD_METHOD(load_verify_locations),
867 ADD_METHOD(set_passwd_cb),
868 ADD_METHOD(use_certificate_chain_file),
869 ADD_METHOD(use_certificate_file),
870 ADD_METHOD(use_certificate),
871 ADD_METHOD(use_privatekey_file),
872 ADD_METHOD(use_privatekey),
873 ADD_METHOD(check_privatekey),
874 ADD_METHOD(load_client_ca),
875 ADD_METHOD(set_session_id),
876 ADD_METHOD(set_verify),
877 ADD_METHOD(set_verify_depth),
878 ADD_METHOD(get_verify_mode),
879 ADD_METHOD(get_verify_depth),
880 ADD_METHOD(load_tmp_dh),
881 ADD_METHOD(set_cipher_list),
882 ADD_METHOD(set_timeout),
883 ADD_METHOD(get_timeout),
884 ADD_METHOD(set_info_callback),
885 ADD_METHOD(get_app_data),
886 ADD_METHOD(set_app_data),
887 ADD_METHOD(get_cert_store),
888 ADD_METHOD(set_options),
889 { NULL, NULL }
890};
891#undef ADD_METHOD
892
893
894/* Constructor, takes an int specifying which method to use */
895/*
896 * Constructor for Context objects
897 *
898 * Arguments: i_method - The SSL method to use, one of the SSLv2_METHOD,
899 * SSLv3_METHOD, SSLv23_METHOD and TLSv1_METHOD
900 * constants.
901 * Returns: The newly created Context object
902 */
903ssl_ContextObj *
904ssl_Context_New(int i_method)
905{
906 SSL_METHOD *method;
907 ssl_ContextObj *self;
908
909 switch (i_method)
910 {
911 /* Too bad TLSv1 servers can't accept SSLv3 clients */
912 case ssl_SSLv2_METHOD: method = SSLv2_method(); break;
913 case ssl_SSLv23_METHOD: method = SSLv23_method(); break;
914 case ssl_SSLv3_METHOD: method = SSLv3_method(); break;
915 case ssl_TLSv1_METHOD: method = TLSv1_method(); break;
916 default:
917 PyErr_SetString(PyExc_ValueError, "No such protocol");
918 return NULL;
919 }
920
921 self = PyObject_GC_New(ssl_ContextObj, &ssl_Context_Type);
922 if (self == NULL)
923 return (ssl_ContextObj *)PyErr_NoMemory();
924
925 self->ctx = SSL_CTX_new(method);
926 Py_INCREF(Py_None);
927 self->passphrase_callback = Py_None;
928 Py_INCREF(Py_None);
929 self->verify_callback = Py_None;
930 Py_INCREF(Py_None);
931 self->info_callback = Py_None;
932
933 Py_INCREF(Py_None);
934 self->passphrase_userdata = Py_None;
935
936 Py_INCREF(Py_None);
937 self->app_data = Py_None;
938
939 /* Some initialization that's required to operate smoothly in Python */
940 SSL_CTX_set_app_data(self->ctx, self);
941 SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
942 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
943 SSL_MODE_AUTO_RETRY);
944
945 self->tstate = NULL;
946 PyObject_GC_Track((PyObject *)self);
947
948 return self;
949}
950
951/*
952 * Find attribute
953 *
954 * Arguments: self - The Context object
955 * name - The attribute name
956 * Returns: A Python object for the attribute, or NULL if something went
957 * wrong
958 */
959static PyObject *
960ssl_Context_getattr(ssl_ContextObj *self, char *name)
961{
962 return Py_FindMethod(ssl_Context_methods, (PyObject *)self, name);
963}
964
965/*
966 * Call the visitproc on all contained objects.
967 *
968 * Arguments: self - The Context object
969 * visit - Function to call
970 * arg - Extra argument to visit
971 * Returns: 0 if all goes well, otherwise the return code from the first
972 * call that gave non-zero result.
973 */
974static int
975ssl_Context_traverse(ssl_ContextObj *self, visitproc visit, void *arg)
976{
977 int ret = 0;
978
979 if (ret == 0 && self->passphrase_callback != NULL)
980 ret = visit((PyObject *)self->passphrase_callback, arg);
981 if (ret == 0 && self->passphrase_userdata != NULL)
982 ret = visit((PyObject *)self->passphrase_userdata, arg);
983 if (ret == 0 && self->verify_callback != NULL)
984 ret = visit((PyObject *)self->verify_callback, arg);
985 if (ret == 0 && self->info_callback != NULL)
986 ret = visit((PyObject *)self->info_callback, arg);
987 if (ret == 0 && self->app_data != NULL)
988 ret = visit(self->app_data, arg);
989 return ret;
990}
991
992/*
993 * Decref all contained objects and zero the pointers.
994 *
995 * Arguments: self - The Context object
996 * Returns: Always 0.
997 */
998static int
999ssl_Context_clear(ssl_ContextObj *self)
1000{
1001 Py_XDECREF(self->passphrase_callback);
1002 self->passphrase_callback = NULL;
1003 Py_XDECREF(self->passphrase_userdata);
1004 self->passphrase_userdata = NULL;
1005 Py_XDECREF(self->verify_callback);
1006 self->verify_callback = NULL;
1007 Py_XDECREF(self->info_callback);
1008 self->info_callback = NULL;
1009 Py_XDECREF(self->app_data);
1010 self->app_data = NULL;
1011 return 0;
1012}
1013
1014/*
1015 * Deallocate the memory used by the Context object
1016 *
1017 * Arguments: self - The Context object
1018 * Returns: None
1019 */
1020static void
1021ssl_Context_dealloc(ssl_ContextObj *self)
1022{
1023 PyObject_GC_UnTrack((PyObject *)self);
1024 SSL_CTX_free(self->ctx);
1025 ssl_Context_clear(self);
1026 PyObject_GC_Del(self);
1027}
1028
1029
1030PyTypeObject ssl_Context_Type = {
1031 PyObject_HEAD_INIT(NULL)
1032 0,
1033 "Context",
1034 sizeof(ssl_ContextObj),
1035 0,
1036 (destructor)ssl_Context_dealloc,
1037 NULL, /* print */
1038 (getattrfunc)ssl_Context_getattr,
1039 NULL, /* setattr */
1040 NULL, /* compare */
1041 NULL, /* repr */
1042 NULL, /* as_number */
1043 NULL, /* as_sequence */
1044 NULL, /* as_mapping */
1045 NULL, /* hash */
1046 NULL, /* call */
1047 NULL, /* str */
1048 NULL, /* getattro */
1049 NULL, /* setattro */
1050 NULL, /* as_buffer */
1051 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1052 NULL, /* doc */
1053 (traverseproc)ssl_Context_traverse,
1054 (inquiry)ssl_Context_clear,
1055};
1056
1057
1058/*
1059 * Initialize the Context part of the SSL sub module
1060 *
1061 * Arguments: dict - Dictionary of the OpenSSL.SSL module
1062 * Returns: 1 for success, 0 otherwise
1063 */
1064int
1065init_ssl_context(PyObject *dict)
1066{
1067 ssl_Context_Type.ob_type = &PyType_Type;
1068 Py_INCREF(&ssl_Context_Type);
1069 if (PyDict_SetItemString(dict, "ContextType", (PyObject *)&ssl_Context_Type) != 0)
1070 return 0;
1071
1072 return 1;
1073}
1074