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