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