blob: a8a63dfa783e852288689a132d8ad54796267b77 [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
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500267static crypto_X509Obj *
268parse_certificate_argument(const char* format1, const char* format2, PyObject* args)
269{
270 static PyTypeObject *crypto_X509_type = NULL;
271 crypto_X509Obj *cert;
272
273 /* We need to check that cert really is an X509 object before
274 we deal with it. The problem is we can't just quickly verify
275 the type (since that comes from another module). This should
276 do the trick (reasonably well at least): Once we have one
277 verified object, we use it's type object for future
278 comparisons. */
279
280 if (!crypto_X509_type)
281 {
282 if (!PyArg_ParseTuple(args, format1, &cert))
283 return NULL;
284
285 if (strcmp(cert->ob_type->tp_name, "X509") != 0 ||
286 cert->ob_type->tp_basicsize != sizeof(crypto_X509Obj))
287 {
288 PyErr_SetString(PyExc_TypeError, "Expected an X509 object");
289 return NULL;
290 }
291
292 crypto_X509_type = cert->ob_type;
293 }
294 else
295 if (!PyArg_ParseTuple(args, format2, crypto_X509_type,
296 &cert))
297 return NULL;
298 return cert;
299}
300
301static char ssl_Context_add_extra_chain_cert_doc[] = "\n\
302Add certificate to chain\n\
303\n\
304Arguments: self - The Context object\n\
305 args - The Python argument tuple, should be:\n\
306 certobj - The X509 certificate object to add to the chain\n\
307Returns: None\n\
308";
309
310static PyObject *
311ssl_Context_add_extra_chain_cert(ssl_ContextObj *self, PyObject *args)
312{
313 crypto_X509Obj *cert = parse_certificate_argument(
314 "O:add_extra_chain_cert", "O!:add_extra_chain_cert", args);
315 if (cert == NULL) {
316 return NULL;
317 }
318
319 if (!SSL_CTX_add_extra_chain_cert(self->ctx, cert->x509))
320 {
321 exception_from_error_queue();
322 return NULL;
323 }
324 else
325 {
326 Py_INCREF(Py_None);
327 return Py_None;
328 }
329}
330
331
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500332static char ssl_Context_use_certificate_chain_file_doc[] = "\n\
333Load a certificate chain from a file\n\
334\n\
335Arguments: self - The Context object\n\
336 args - The Python argument tuple, should be:\n\
337 certfile - The name of the certificate chain file\n\
338Returns: None\n\
339";
340static PyObject *
341ssl_Context_use_certificate_chain_file(ssl_ContextObj *self, PyObject *args)
342{
343 char *certfile;
344
345 if (!PyArg_ParseTuple(args, "s:use_certificate_chain_file", &certfile))
346 return NULL;
347
348 if (!SSL_CTX_use_certificate_chain_file(self->ctx, certfile))
349 {
350 exception_from_error_queue();
351 return NULL;
352 }
353 else
354 {
355 Py_INCREF(Py_None);
356 return Py_None;
357 }
358}
359
360
361static char ssl_Context_use_certificate_file_doc[] = "\n\
362Load a certificate from a file\n\
363\n\
364Arguments: self - The Context object\n\
365 args - The Python argument tuple, should be:\n\
366 certfile - The name of the certificate file\n\
367 filetype - (optional) The encoding of the file, default is PEM\n\
368Returns: None\n\
369";
370static PyObject *
371ssl_Context_use_certificate_file(ssl_ContextObj *self, PyObject *args)
372{
373 char *certfile;
374 int filetype = SSL_FILETYPE_PEM;
375
376 if (!PyArg_ParseTuple(args, "s|i:use_certificate_file", &certfile, &filetype))
377 return NULL;
378
379 if (!SSL_CTX_use_certificate_file(self->ctx, certfile, filetype))
380 {
381 exception_from_error_queue();
382 return NULL;
383 }
384 else
385 {
386 Py_INCREF(Py_None);
387 return Py_None;
388 }
389}
390
391static char ssl_Context_use_certificate_doc[] = "\n\
392Load a certificate from a X509 object\n\
393\n\
394Arguments: self - The Context object\n\
395 args - The Python argument tuple, should be:\n\
396 cert - The X509 object\n\
397Returns: None\n\
398";
399static PyObject *
400ssl_Context_use_certificate(ssl_ContextObj *self, PyObject *args)
401{
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500402 crypto_X509Obj *cert = parse_certificate_argument(
403 "O:use_certificate", "O!:use_certificate", args);
404 if (cert == NULL) {
405 return NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500406 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500407
408 if (!SSL_CTX_use_certificate(self->ctx, cert->x509))
409 {
410 exception_from_error_queue();
411 return NULL;
412 }
413 else
414 {
415 Py_INCREF(Py_None);
416 return Py_None;
417 }
418}
419
420static char ssl_Context_use_privatekey_file_doc[] = "\n\
421Load a private key from a file\n\
422\n\
423Arguments: self - The Context object\n\
424 args - The Python argument tuple, should be:\n\
425 keyfile - The name of the key file\n\
426 filetype - (optional) The encoding of the file, default is PEM\n\
427Returns: None\n\
428";
429static PyObject *
430ssl_Context_use_privatekey_file(ssl_ContextObj *self, PyObject *args)
431{
432 char *keyfile;
433 int filetype = SSL_FILETYPE_PEM, ret;
434
435 if (!PyArg_ParseTuple(args, "s|i:use_privatekey_file", &keyfile, &filetype))
436 return NULL;
437
438 MY_BEGIN_ALLOW_THREADS(self->tstate);
439 ret = SSL_CTX_use_PrivateKey_file(self->ctx, keyfile, filetype);
440 MY_END_ALLOW_THREADS(self->tstate);
441
442 if (PyErr_Occurred())
443 {
444 flush_error_queue();
445 return NULL;
446 }
447
448 if (!ret)
449 {
450 exception_from_error_queue();
451 return NULL;
452 }
453 else
454 {
455 Py_INCREF(Py_None);
456 return Py_None;
457 }
458}
459
460static char ssl_Context_use_privatekey_doc[] = "\n\
461Load a private key from a PKey object\n\
462\n\
463Arguments: self - The Context object\n\
464 args - The Python argument tuple, should be:\n\
465 pkey - The PKey object\n\
466Returns: None\n\
467";
468static PyObject *
469ssl_Context_use_privatekey(ssl_ContextObj *self, PyObject *args)
470{
471 static PyTypeObject *crypto_PKey_type = NULL;
472 crypto_PKeyObj *pkey;
473
474 /* We need to check that cert really is a PKey object before
475 we deal with it. The problem is we can't just quickly verify
476 the type (since that comes from another module). This should
477 do the trick (reasonably well at least): Once we have one
478 verified object, we use it's type object for future
479 comparisons. */
480
481 if (!crypto_PKey_type)
482 {
483 if (!PyArg_ParseTuple(args, "O:use_privatekey", &pkey))
484 return NULL;
485
486 if (strcmp(pkey->ob_type->tp_name, "PKey") != 0 ||
487 pkey->ob_type->tp_basicsize != sizeof(crypto_PKeyObj))
488 {
489 PyErr_SetString(PyExc_TypeError, "Expected a PKey object");
490 return NULL;
491 }
492
493 crypto_PKey_type = pkey->ob_type;
494 }
495 else
496 if (!PyArg_ParseTuple(args, "O!:use_privatekey", crypto_PKey_type, &pkey))
497 return NULL;
498
499 if (!SSL_CTX_use_PrivateKey(self->ctx, pkey->pkey))
500 {
501 exception_from_error_queue();
502 return NULL;
503 }
504 else
505 {
506 Py_INCREF(Py_None);
507 return Py_None;
508 }
509}
510
511static char ssl_Context_check_privatekey_doc[] = "\n\
512Check that the private key and certificate match up\n\
513\n\
514Arguments: self - The Context object\n\
515 args - The Python argument tuple, should be empty\n\
516Returns: None (raises an exception if something's wrong)\n\
517";
518static PyObject *
519ssl_Context_check_privatekey(ssl_ContextObj *self, PyObject *args)
520{
521 if (!PyArg_ParseTuple(args, ":check_privatekey"))
522 return NULL;
523
524 if (!SSL_CTX_check_private_key(self->ctx))
525 {
526 exception_from_error_queue();
527 return NULL;
528 }
529 else
530 {
531 Py_INCREF(Py_None);
532 return Py_None;
533 }
534}
535
536static char ssl_Context_load_client_ca_doc[] = "\n\
537Load the trusted certificates that will be sent to the client (basically\n\
538telling the client \"These are the guys I trust\")\n\
539\n\
540Arguments: self - The Context object\n\
541 args - The Python argument tuple, should be:\n\
542 cafile - The name of the certificates file\n\
543Returns: None\n\
544";
545static PyObject *
546ssl_Context_load_client_ca(ssl_ContextObj *self, PyObject *args)
547{
548 char *cafile;
549
550 if (!PyArg_ParseTuple(args, "s:load_client_ca", &cafile))
551 return NULL;
552
553 SSL_CTX_set_client_CA_list(self->ctx, SSL_load_client_CA_file(cafile));
554
555 Py_INCREF(Py_None);
556 return Py_None;
557}
558
559static char ssl_Context_set_session_id_doc[] = "\n\
560Set the session identifier, this is needed if you want to do session\n\
561resumption (which, ironically, isn't implemented yet)\n\
562\n\
563Arguments: self - The Context object\n\
564 args - The Python argument tuple, should be:\n\
565 buf - A Python object that can be safely converted to a string\n\
566Returns: None\n\
567";
568static PyObject *
569ssl_Context_set_session_id(ssl_ContextObj *self, PyObject *args)
570{
571 char *buf;
572 int len;
573
574 if (!PyArg_ParseTuple(args, "s#:set_session_id", &buf, &len))
575 return NULL;
576
577 if (!SSL_CTX_set_session_id_context(self->ctx, buf, len))
578 {
579 exception_from_error_queue();
580 return NULL;
581 }
582 else
583 {
584 Py_INCREF(Py_None);
585 return Py_None;
586 }
587}
588
589static char ssl_Context_set_verify_doc[] = "\n\
590Set the verify mode and verify callback\n\
591\n\
592Arguments: self - The Context object\n\
593 args - The Python argument tuple, should be:\n\
594 mode - The verify mode, this is either SSL_VERIFY_NONE or\n\
595 SSL_VERIFY_PEER combined with possible other flags\n\
596 callback - The Python callback to use\n\
597Returns: None\n\
598";
599static PyObject *
600ssl_Context_set_verify(ssl_ContextObj *self, PyObject *args)
601{
602 int mode;
603 PyObject *callback = NULL;
604
605 if (!PyArg_ParseTuple(args, "iO:set_verify", &mode, &callback))
606 return NULL;
607
608 if (!PyCallable_Check(callback))
609 {
610 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
611 return NULL;
612 }
613
614 Py_DECREF(self->verify_callback);
615 Py_INCREF(callback);
616 self->verify_callback = callback;
617 SSL_CTX_set_verify(self->ctx, mode, global_verify_callback);
618
619 Py_INCREF(Py_None);
620 return Py_None;
621}
622
623static char ssl_Context_set_verify_depth_doc[] = "\n\
624Set the verify depth\n\
625\n\
626Arguments: self - The Context object\n\
627 args - The Python argument tuple, should be:\n\
628 depth - An integer specifying the verify depth\n\
629Returns: None\n\
630";
631static PyObject *
632ssl_Context_set_verify_depth(ssl_ContextObj *self, PyObject *args)
633{
634 int depth;
635
636 if (!PyArg_ParseTuple(args, "i:set_verify_depth", &depth))
637 return NULL;
638
639 SSL_CTX_set_verify_depth(self->ctx, depth);
640 Py_INCREF(Py_None);
641 return Py_None;
642}
643
644static char ssl_Context_get_verify_mode_doc[] = "\n\
645Get the verify mode\n\
646\n\
647Arguments: self - The Context object\n\
648 args - The Python argument tuple, should be empty\n\
649Returns: The verify mode\n\
650";
651static PyObject *
652ssl_Context_get_verify_mode(ssl_ContextObj *self, PyObject *args)
653{
654 int mode;
655
656 if (!PyArg_ParseTuple(args, ":get_verify_mode"))
657 return NULL;
658
659 mode = SSL_CTX_get_verify_mode(self->ctx);
660 return PyInt_FromLong((long)mode);
661}
662
663static char ssl_Context_get_verify_depth_doc[] = "\n\
664Get the verify depth\n\
665\n\
666Arguments: self - The Context object\n\
667 args - The Python argument tuple, should be empty\n\
668Returns: The verify depth\n\
669";
670static PyObject *
671ssl_Context_get_verify_depth(ssl_ContextObj *self, PyObject *args)
672{
673 int depth;
674
675 if (!PyArg_ParseTuple(args, ":get_verify_depth"))
676 return NULL;
677
678 depth = SSL_CTX_get_verify_depth(self->ctx);
679 return PyInt_FromLong((long)depth);
680}
681
682static char ssl_Context_load_tmp_dh_doc[] = "\n\
683Load parameters for Ephemeral Diffie-Hellman\n\
684\n\
685Arguments: self - The Context object\n\
686 args - The Python argument tuple, should be:\n\
687 dhfile - The file to load EDH parameters from\n\
688Returns: None\n\
689";
690static PyObject *
691ssl_Context_load_tmp_dh(ssl_ContextObj *self, PyObject *args)
692{
693 char *dhfile;
694 BIO *bio;
695 DH *dh;
696
697 if (!PyArg_ParseTuple(args, "s:load_tmp_dh", &dhfile))
698 return NULL;
699
700 bio = BIO_new_file(dhfile, "r");
701 if (bio == NULL)
702 return PyErr_NoMemory();
703
704 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
705 SSL_CTX_set_tmp_dh(self->ctx, dh);
706 DH_free(dh);
707 BIO_free(bio);
708
709 Py_INCREF(Py_None);
710 return Py_None;
711}
712
713static char ssl_Context_set_cipher_list_doc[] = "\n\
714Change the cipher list\n\
715\n\
716Arguments: self - The Context object\n\
717 args - The Python argument tuple, should be:\n\
718 cipher_list - A cipher list, see ciphers(1)\n\
719Returns: None\n\
720";
721static PyObject *
722ssl_Context_set_cipher_list(ssl_ContextObj *self, PyObject *args)
723{
724 char *cipher_list;
725
726 if (!PyArg_ParseTuple(args, "s:set_cipher_list", &cipher_list))
727 return NULL;
728
729 if (!SSL_CTX_set_cipher_list(self->ctx, cipher_list))
730 {
731 exception_from_error_queue();
732 return NULL;
733 }
734 else
735 {
736 Py_INCREF(Py_None);
737 return Py_None;
738 }
739}
740
741static char ssl_Context_set_timeout_doc[] = "\n\
742Set session timeout\n\
743\n\
744Arguments: self - The Context object\n\
745 args - The Python argument tuple, should be:\n\
746 t - The timeout in seconds\n\
747Returns: The previous session timeout\n\
748";
749static PyObject *
750ssl_Context_set_timeout(ssl_ContextObj *self, PyObject *args)
751{
752 long t, ret;
753
754 if (!PyArg_ParseTuple(args, "l:set_timeout", &t))
755 return NULL;
756
757 ret = SSL_CTX_set_timeout(self->ctx, t);
758 return PyLong_FromLong(ret);
759}
760
761static char ssl_Context_get_timeout_doc[] = "\n\
762Get the session timeout\n\
763\n\
764Arguments: self - The Context object\n\
765 args - The Python argument tuple, should be empty\n\
766Returns: The session timeout\n\
767";
768static PyObject *
769ssl_Context_get_timeout(ssl_ContextObj *self, PyObject *args)
770{
771 long ret;
772
773 if (!PyArg_ParseTuple(args, ":get_timeout"))
774 return NULL;
775
776 ret = SSL_CTX_get_timeout(self->ctx);
777 return PyLong_FromLong(ret);
778}
779
780static char ssl_Context_set_info_callback_doc[] = "\n\
781Set the info callback\n\
782\n\
783Arguments: self - The Context object\n\
784 args - The Python argument tuple, should be:\n\
785 callback - The Python callback to use\n\
786Returns: None\n\
787";
788static PyObject *
789ssl_Context_set_info_callback(ssl_ContextObj *self, PyObject *args)
790{
791 PyObject *callback;
792
793 if (!PyArg_ParseTuple(args, "O:set_info_callback", &callback))
794 return NULL;
795
796 if (!PyCallable_Check(callback))
797 {
798 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
799 return NULL;
800 }
801
802 Py_DECREF(self->info_callback);
803 Py_INCREF(callback);
804 self->info_callback = callback;
805 SSL_CTX_set_info_callback(self->ctx, global_info_callback);
806
807 Py_INCREF(Py_None);
808 return Py_None;
809}
810
811static char ssl_Context_get_app_data_doc[] = "\n\
812Get the application data (supplied via set_app_data())\n\
813\n\
814Arguments: self - The Context object\n\
815 args - The Python argument tuple, should be empty\n\
816Returns: The application data\n\
817";
818static PyObject *
819ssl_Context_get_app_data(ssl_ContextObj *self, PyObject *args)
820{
821 if (!PyArg_ParseTuple(args, ":get_app_data"))
822 return NULL;
823
824 Py_INCREF(self->app_data);
825 return self->app_data;
826}
827
828static char ssl_Context_set_app_data_doc[] = "\n\
829Set the application data (will be returned from get_app_data())\n\
830\n\
831Arguments: self - The Context object\n\
832 args - The Python argument tuple, should be:\n\
833 data - Any Python object\n\
834Returns: None\n\
835";
836static PyObject *
837ssl_Context_set_app_data(ssl_ContextObj *self, PyObject *args)
838{
839 PyObject *data;
840
841 if (!PyArg_ParseTuple(args, "O:set_app_data", &data))
842 return NULL;
843
844 Py_DECREF(self->app_data);
845 Py_INCREF(data);
846 self->app_data = data;
847
848 Py_INCREF(Py_None);
849 return Py_None;
850}
851
852static char ssl_Context_get_cert_store_doc[] = "\n\
853Get the certificate store for the context\n\
854\n\
855Arguments: self - The Context object\n\
856 args - The Python argument tuple, should be empty\n\
857Returns: A X509Store object\n\
858";
859static PyObject *
860ssl_Context_get_cert_store(ssl_ContextObj *self, PyObject *args)
861{
862 X509_STORE *store;
863
864 if (!PyArg_ParseTuple(args, ":get_cert_store"))
865 return NULL;
866
867 if ((store = SSL_CTX_get_cert_store(self->ctx)) == NULL)
868 {
869 Py_INCREF(Py_None);
870 return Py_None;
871 }
872 else
873 {
874 return (PyObject *)crypto_X509Store_New(store, 0);
875 }
876}
877
878static char ssl_Context_set_options_doc[] = "\n\
879Add options. Options set before are not cleared!\n\
880\n\
881Arguments: self - The Context object\n\
882 args - The Python argument tuple, should be:\n\
883 options - The options to add.\n\
884Returns: The new option bitmask.\n\
885";
886static PyObject *
887ssl_Context_set_options(ssl_ContextObj *self, PyObject *args)
888{
889 long options;
890
891 if (!PyArg_ParseTuple(args, "l:set_options", &options))
892 return NULL;
893
894 return PyInt_FromLong(SSL_CTX_set_options(self->ctx, options));
895}
896
897
898/*
899 * Member methods in the Context object
900 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
901 * { 'name', (PyCFunction)ssl_Context_name, METH_VARARGS }
902 * for convenience
903 * ADD_ALIAS(name,real) creates an "alias" of the ssl_Context_real
904 * function with the name 'name'
905 */
906#define ADD_METHOD(name) { #name, (PyCFunction)ssl_Context_##name, METH_VARARGS, ssl_Context_##name##_doc }
907static PyMethodDef ssl_Context_methods[] = {
908 ADD_METHOD(load_verify_locations),
909 ADD_METHOD(set_passwd_cb),
910 ADD_METHOD(use_certificate_chain_file),
911 ADD_METHOD(use_certificate_file),
912 ADD_METHOD(use_certificate),
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500913 ADD_METHOD(add_extra_chain_cert),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500914 ADD_METHOD(use_privatekey_file),
915 ADD_METHOD(use_privatekey),
916 ADD_METHOD(check_privatekey),
917 ADD_METHOD(load_client_ca),
918 ADD_METHOD(set_session_id),
919 ADD_METHOD(set_verify),
920 ADD_METHOD(set_verify_depth),
921 ADD_METHOD(get_verify_mode),
922 ADD_METHOD(get_verify_depth),
923 ADD_METHOD(load_tmp_dh),
924 ADD_METHOD(set_cipher_list),
925 ADD_METHOD(set_timeout),
926 ADD_METHOD(get_timeout),
927 ADD_METHOD(set_info_callback),
928 ADD_METHOD(get_app_data),
929 ADD_METHOD(set_app_data),
930 ADD_METHOD(get_cert_store),
931 ADD_METHOD(set_options),
932 { NULL, NULL }
933};
934#undef ADD_METHOD
935
936
937/* Constructor, takes an int specifying which method to use */
938/*
939 * Constructor for Context objects
940 *
941 * Arguments: i_method - The SSL method to use, one of the SSLv2_METHOD,
942 * SSLv3_METHOD, SSLv23_METHOD and TLSv1_METHOD
943 * constants.
944 * Returns: The newly created Context object
945 */
946ssl_ContextObj *
947ssl_Context_New(int i_method)
948{
949 SSL_METHOD *method;
950 ssl_ContextObj *self;
951
952 switch (i_method)
953 {
954 /* Too bad TLSv1 servers can't accept SSLv3 clients */
955 case ssl_SSLv2_METHOD: method = SSLv2_method(); break;
956 case ssl_SSLv23_METHOD: method = SSLv23_method(); break;
957 case ssl_SSLv3_METHOD: method = SSLv3_method(); break;
958 case ssl_TLSv1_METHOD: method = TLSv1_method(); break;
959 default:
960 PyErr_SetString(PyExc_ValueError, "No such protocol");
961 return NULL;
962 }
963
964 self = PyObject_GC_New(ssl_ContextObj, &ssl_Context_Type);
965 if (self == NULL)
966 return (ssl_ContextObj *)PyErr_NoMemory();
967
968 self->ctx = SSL_CTX_new(method);
969 Py_INCREF(Py_None);
970 self->passphrase_callback = Py_None;
971 Py_INCREF(Py_None);
972 self->verify_callback = Py_None;
973 Py_INCREF(Py_None);
974 self->info_callback = Py_None;
975
976 Py_INCREF(Py_None);
977 self->passphrase_userdata = Py_None;
978
979 Py_INCREF(Py_None);
980 self->app_data = Py_None;
981
982 /* Some initialization that's required to operate smoothly in Python */
983 SSL_CTX_set_app_data(self->ctx, self);
984 SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
985 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
986 SSL_MODE_AUTO_RETRY);
987
988 self->tstate = NULL;
989 PyObject_GC_Track((PyObject *)self);
990
991 return self;
992}
993
994/*
995 * Find attribute
996 *
997 * Arguments: self - The Context object
998 * name - The attribute name
999 * Returns: A Python object for the attribute, or NULL if something went
1000 * wrong
1001 */
1002static PyObject *
1003ssl_Context_getattr(ssl_ContextObj *self, char *name)
1004{
1005 return Py_FindMethod(ssl_Context_methods, (PyObject *)self, name);
1006}
1007
1008/*
1009 * Call the visitproc on all contained objects.
1010 *
1011 * Arguments: self - The Context object
1012 * visit - Function to call
1013 * arg - Extra argument to visit
1014 * Returns: 0 if all goes well, otherwise the return code from the first
1015 * call that gave non-zero result.
1016 */
1017static int
1018ssl_Context_traverse(ssl_ContextObj *self, visitproc visit, void *arg)
1019{
1020 int ret = 0;
1021
1022 if (ret == 0 && self->passphrase_callback != NULL)
1023 ret = visit((PyObject *)self->passphrase_callback, arg);
1024 if (ret == 0 && self->passphrase_userdata != NULL)
1025 ret = visit((PyObject *)self->passphrase_userdata, arg);
1026 if (ret == 0 && self->verify_callback != NULL)
1027 ret = visit((PyObject *)self->verify_callback, arg);
1028 if (ret == 0 && self->info_callback != NULL)
1029 ret = visit((PyObject *)self->info_callback, arg);
1030 if (ret == 0 && self->app_data != NULL)
1031 ret = visit(self->app_data, arg);
1032 return ret;
1033}
1034
1035/*
1036 * Decref all contained objects and zero the pointers.
1037 *
1038 * Arguments: self - The Context object
1039 * Returns: Always 0.
1040 */
1041static int
1042ssl_Context_clear(ssl_ContextObj *self)
1043{
1044 Py_XDECREF(self->passphrase_callback);
1045 self->passphrase_callback = NULL;
1046 Py_XDECREF(self->passphrase_userdata);
1047 self->passphrase_userdata = NULL;
1048 Py_XDECREF(self->verify_callback);
1049 self->verify_callback = NULL;
1050 Py_XDECREF(self->info_callback);
1051 self->info_callback = NULL;
1052 Py_XDECREF(self->app_data);
1053 self->app_data = NULL;
1054 return 0;
1055}
1056
1057/*
1058 * Deallocate the memory used by the Context object
1059 *
1060 * Arguments: self - The Context object
1061 * Returns: None
1062 */
1063static void
1064ssl_Context_dealloc(ssl_ContextObj *self)
1065{
1066 PyObject_GC_UnTrack((PyObject *)self);
1067 SSL_CTX_free(self->ctx);
1068 ssl_Context_clear(self);
1069 PyObject_GC_Del(self);
1070}
1071
1072
1073PyTypeObject ssl_Context_Type = {
1074 PyObject_HEAD_INIT(NULL)
1075 0,
1076 "Context",
1077 sizeof(ssl_ContextObj),
1078 0,
1079 (destructor)ssl_Context_dealloc,
1080 NULL, /* print */
1081 (getattrfunc)ssl_Context_getattr,
1082 NULL, /* setattr */
1083 NULL, /* compare */
1084 NULL, /* repr */
1085 NULL, /* as_number */
1086 NULL, /* as_sequence */
1087 NULL, /* as_mapping */
1088 NULL, /* hash */
1089 NULL, /* call */
1090 NULL, /* str */
1091 NULL, /* getattro */
1092 NULL, /* setattro */
1093 NULL, /* as_buffer */
1094 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1095 NULL, /* doc */
1096 (traverseproc)ssl_Context_traverse,
1097 (inquiry)ssl_Context_clear,
1098};
1099
1100
1101/*
1102 * Initialize the Context part of the SSL sub module
1103 *
1104 * Arguments: dict - Dictionary of the OpenSSL.SSL module
1105 * Returns: 1 for success, 0 otherwise
1106 */
1107int
1108init_ssl_context(PyObject *dict)
1109{
1110 ssl_Context_Type.ob_type = &PyType_Type;
1111 Py_INCREF(&ssl_Context_Type);
1112 if (PyDict_SetItemString(dict, "ContextType", (PyObject *)&ssl_Context_Type) != 0)
1113 return 0;
1114
1115 return 1;
1116}
1117