blob: 6cbebbe0bd8e5a016811d4c0c84ae35c74cbc5ff [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\
Jean-Paul Calderone24aedf42008-03-06 22:01:16 -0500616 mode - The verify mode, this is either VERIFY_NONE or\n\
617 VERIFY_PEER combined with possible other flags\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500618 callback - The Python callback to use\n\
619Returns: None\n\
Jean-Paul Calderone24aedf42008-03-06 22:01:16 -0500620\n\
621See SSL_CTX_set_verify(3SSL) for further details.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500622";
623static PyObject *
624ssl_Context_set_verify(ssl_ContextObj *self, PyObject *args)
625{
626 int mode;
627 PyObject *callback = NULL;
628
629 if (!PyArg_ParseTuple(args, "iO:set_verify", &mode, &callback))
630 return NULL;
631
632 if (!PyCallable_Check(callback))
633 {
634 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
635 return NULL;
636 }
637
638 Py_DECREF(self->verify_callback);
639 Py_INCREF(callback);
640 self->verify_callback = callback;
641 SSL_CTX_set_verify(self->ctx, mode, global_verify_callback);
642
643 Py_INCREF(Py_None);
644 return Py_None;
645}
646
647static char ssl_Context_set_verify_depth_doc[] = "\n\
648Set the verify depth\n\
649\n\
650Arguments: self - The Context object\n\
651 args - The Python argument tuple, should be:\n\
652 depth - An integer specifying the verify depth\n\
653Returns: None\n\
654";
655static PyObject *
656ssl_Context_set_verify_depth(ssl_ContextObj *self, PyObject *args)
657{
658 int depth;
659
660 if (!PyArg_ParseTuple(args, "i:set_verify_depth", &depth))
661 return NULL;
662
663 SSL_CTX_set_verify_depth(self->ctx, depth);
664 Py_INCREF(Py_None);
665 return Py_None;
666}
667
668static char ssl_Context_get_verify_mode_doc[] = "\n\
669Get the verify mode\n\
670\n\
671Arguments: self - The Context object\n\
672 args - The Python argument tuple, should be empty\n\
673Returns: The verify mode\n\
674";
675static PyObject *
676ssl_Context_get_verify_mode(ssl_ContextObj *self, PyObject *args)
677{
678 int mode;
679
680 if (!PyArg_ParseTuple(args, ":get_verify_mode"))
681 return NULL;
682
683 mode = SSL_CTX_get_verify_mode(self->ctx);
684 return PyInt_FromLong((long)mode);
685}
686
687static char ssl_Context_get_verify_depth_doc[] = "\n\
688Get the verify depth\n\
689\n\
690Arguments: self - The Context object\n\
691 args - The Python argument tuple, should be empty\n\
692Returns: The verify depth\n\
693";
694static PyObject *
695ssl_Context_get_verify_depth(ssl_ContextObj *self, PyObject *args)
696{
697 int depth;
698
699 if (!PyArg_ParseTuple(args, ":get_verify_depth"))
700 return NULL;
701
702 depth = SSL_CTX_get_verify_depth(self->ctx);
703 return PyInt_FromLong((long)depth);
704}
705
706static char ssl_Context_load_tmp_dh_doc[] = "\n\
707Load parameters for Ephemeral Diffie-Hellman\n\
708\n\
709Arguments: self - The Context object\n\
710 args - The Python argument tuple, should be:\n\
711 dhfile - The file to load EDH parameters from\n\
712Returns: None\n\
713";
714static PyObject *
715ssl_Context_load_tmp_dh(ssl_ContextObj *self, PyObject *args)
716{
717 char *dhfile;
718 BIO *bio;
719 DH *dh;
720
721 if (!PyArg_ParseTuple(args, "s:load_tmp_dh", &dhfile))
722 return NULL;
723
724 bio = BIO_new_file(dhfile, "r");
725 if (bio == NULL)
726 return PyErr_NoMemory();
727
728 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
729 SSL_CTX_set_tmp_dh(self->ctx, dh);
730 DH_free(dh);
731 BIO_free(bio);
732
733 Py_INCREF(Py_None);
734 return Py_None;
735}
736
737static char ssl_Context_set_cipher_list_doc[] = "\n\
738Change the cipher list\n\
739\n\
740Arguments: self - The Context object\n\
741 args - The Python argument tuple, should be:\n\
742 cipher_list - A cipher list, see ciphers(1)\n\
743Returns: None\n\
744";
745static PyObject *
746ssl_Context_set_cipher_list(ssl_ContextObj *self, PyObject *args)
747{
748 char *cipher_list;
749
750 if (!PyArg_ParseTuple(args, "s:set_cipher_list", &cipher_list))
751 return NULL;
752
753 if (!SSL_CTX_set_cipher_list(self->ctx, cipher_list))
754 {
755 exception_from_error_queue();
756 return NULL;
757 }
758 else
759 {
760 Py_INCREF(Py_None);
761 return Py_None;
762 }
763}
764
765static char ssl_Context_set_timeout_doc[] = "\n\
766Set session timeout\n\
767\n\
768Arguments: self - The Context object\n\
769 args - The Python argument tuple, should be:\n\
770 t - The timeout in seconds\n\
771Returns: The previous session timeout\n\
772";
773static PyObject *
774ssl_Context_set_timeout(ssl_ContextObj *self, PyObject *args)
775{
776 long t, ret;
777
778 if (!PyArg_ParseTuple(args, "l:set_timeout", &t))
779 return NULL;
780
781 ret = SSL_CTX_set_timeout(self->ctx, t);
782 return PyLong_FromLong(ret);
783}
784
785static char ssl_Context_get_timeout_doc[] = "\n\
786Get the session timeout\n\
787\n\
788Arguments: self - The Context object\n\
789 args - The Python argument tuple, should be empty\n\
790Returns: The session timeout\n\
791";
792static PyObject *
793ssl_Context_get_timeout(ssl_ContextObj *self, PyObject *args)
794{
795 long ret;
796
797 if (!PyArg_ParseTuple(args, ":get_timeout"))
798 return NULL;
799
800 ret = SSL_CTX_get_timeout(self->ctx);
801 return PyLong_FromLong(ret);
802}
803
804static char ssl_Context_set_info_callback_doc[] = "\n\
805Set the info callback\n\
806\n\
807Arguments: self - The Context object\n\
808 args - The Python argument tuple, should be:\n\
809 callback - The Python callback to use\n\
810Returns: None\n\
811";
812static PyObject *
813ssl_Context_set_info_callback(ssl_ContextObj *self, PyObject *args)
814{
815 PyObject *callback;
816
817 if (!PyArg_ParseTuple(args, "O:set_info_callback", &callback))
818 return NULL;
819
820 if (!PyCallable_Check(callback))
821 {
822 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
823 return NULL;
824 }
825
826 Py_DECREF(self->info_callback);
827 Py_INCREF(callback);
828 self->info_callback = callback;
829 SSL_CTX_set_info_callback(self->ctx, global_info_callback);
830
831 Py_INCREF(Py_None);
832 return Py_None;
833}
834
835static char ssl_Context_get_app_data_doc[] = "\n\
836Get the application data (supplied via set_app_data())\n\
837\n\
838Arguments: self - The Context object\n\
839 args - The Python argument tuple, should be empty\n\
840Returns: The application data\n\
841";
842static PyObject *
843ssl_Context_get_app_data(ssl_ContextObj *self, PyObject *args)
844{
845 if (!PyArg_ParseTuple(args, ":get_app_data"))
846 return NULL;
847
848 Py_INCREF(self->app_data);
849 return self->app_data;
850}
851
852static char ssl_Context_set_app_data_doc[] = "\n\
853Set the application data (will be returned from get_app_data())\n\
854\n\
855Arguments: self - The Context object\n\
856 args - The Python argument tuple, should be:\n\
857 data - Any Python object\n\
858Returns: None\n\
859";
860static PyObject *
861ssl_Context_set_app_data(ssl_ContextObj *self, PyObject *args)
862{
863 PyObject *data;
864
865 if (!PyArg_ParseTuple(args, "O:set_app_data", &data))
866 return NULL;
867
868 Py_DECREF(self->app_data);
869 Py_INCREF(data);
870 self->app_data = data;
871
872 Py_INCREF(Py_None);
873 return Py_None;
874}
875
876static char ssl_Context_get_cert_store_doc[] = "\n\
877Get the certificate store for the context\n\
878\n\
879Arguments: self - The Context object\n\
880 args - The Python argument tuple, should be empty\n\
881Returns: A X509Store object\n\
882";
883static PyObject *
884ssl_Context_get_cert_store(ssl_ContextObj *self, PyObject *args)
885{
886 X509_STORE *store;
887
888 if (!PyArg_ParseTuple(args, ":get_cert_store"))
889 return NULL;
890
891 if ((store = SSL_CTX_get_cert_store(self->ctx)) == NULL)
892 {
893 Py_INCREF(Py_None);
894 return Py_None;
895 }
896 else
897 {
898 return (PyObject *)crypto_X509Store_New(store, 0);
899 }
900}
901
902static char ssl_Context_set_options_doc[] = "\n\
903Add options. Options set before are not cleared!\n\
904\n\
905Arguments: self - The Context object\n\
906 args - The Python argument tuple, should be:\n\
907 options - The options to add.\n\
908Returns: The new option bitmask.\n\
909";
910static PyObject *
911ssl_Context_set_options(ssl_ContextObj *self, PyObject *args)
912{
913 long options;
914
915 if (!PyArg_ParseTuple(args, "l:set_options", &options))
916 return NULL;
917
918 return PyInt_FromLong(SSL_CTX_set_options(self->ctx, options));
919}
920
921
922/*
923 * Member methods in the Context object
924 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
925 * { 'name', (PyCFunction)ssl_Context_name, METH_VARARGS }
926 * for convenience
927 * ADD_ALIAS(name,real) creates an "alias" of the ssl_Context_real
928 * function with the name 'name'
929 */
930#define ADD_METHOD(name) { #name, (PyCFunction)ssl_Context_##name, METH_VARARGS, ssl_Context_##name##_doc }
931static PyMethodDef ssl_Context_methods[] = {
932 ADD_METHOD(load_verify_locations),
933 ADD_METHOD(set_passwd_cb),
934 ADD_METHOD(use_certificate_chain_file),
935 ADD_METHOD(use_certificate_file),
936 ADD_METHOD(use_certificate),
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500937 ADD_METHOD(add_extra_chain_cert),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500938 ADD_METHOD(use_privatekey_file),
939 ADD_METHOD(use_privatekey),
940 ADD_METHOD(check_privatekey),
941 ADD_METHOD(load_client_ca),
942 ADD_METHOD(set_session_id),
943 ADD_METHOD(set_verify),
944 ADD_METHOD(set_verify_depth),
945 ADD_METHOD(get_verify_mode),
946 ADD_METHOD(get_verify_depth),
947 ADD_METHOD(load_tmp_dh),
948 ADD_METHOD(set_cipher_list),
949 ADD_METHOD(set_timeout),
950 ADD_METHOD(get_timeout),
951 ADD_METHOD(set_info_callback),
952 ADD_METHOD(get_app_data),
953 ADD_METHOD(set_app_data),
954 ADD_METHOD(get_cert_store),
955 ADD_METHOD(set_options),
956 { NULL, NULL }
957};
958#undef ADD_METHOD
959
960
961/* Constructor, takes an int specifying which method to use */
962/*
963 * Constructor for Context objects
964 *
965 * Arguments: i_method - The SSL method to use, one of the SSLv2_METHOD,
966 * SSLv3_METHOD, SSLv23_METHOD and TLSv1_METHOD
967 * constants.
968 * Returns: The newly created Context object
969 */
970ssl_ContextObj *
971ssl_Context_New(int i_method)
972{
973 SSL_METHOD *method;
974 ssl_ContextObj *self;
975
976 switch (i_method)
977 {
978 /* Too bad TLSv1 servers can't accept SSLv3 clients */
979 case ssl_SSLv2_METHOD: method = SSLv2_method(); break;
980 case ssl_SSLv23_METHOD: method = SSLv23_method(); break;
981 case ssl_SSLv3_METHOD: method = SSLv3_method(); break;
982 case ssl_TLSv1_METHOD: method = TLSv1_method(); break;
983 default:
984 PyErr_SetString(PyExc_ValueError, "No such protocol");
985 return NULL;
986 }
987
988 self = PyObject_GC_New(ssl_ContextObj, &ssl_Context_Type);
989 if (self == NULL)
990 return (ssl_ContextObj *)PyErr_NoMemory();
991
992 self->ctx = SSL_CTX_new(method);
993 Py_INCREF(Py_None);
994 self->passphrase_callback = Py_None;
995 Py_INCREF(Py_None);
996 self->verify_callback = Py_None;
997 Py_INCREF(Py_None);
998 self->info_callback = Py_None;
999
1000 Py_INCREF(Py_None);
1001 self->passphrase_userdata = Py_None;
1002
1003 Py_INCREF(Py_None);
1004 self->app_data = Py_None;
1005
1006 /* Some initialization that's required to operate smoothly in Python */
1007 SSL_CTX_set_app_data(self->ctx, self);
1008 SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
1009 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1010 SSL_MODE_AUTO_RETRY);
1011
1012 self->tstate = NULL;
1013 PyObject_GC_Track((PyObject *)self);
1014
1015 return self;
1016}
1017
1018/*
1019 * Find attribute
1020 *
1021 * Arguments: self - The Context object
1022 * name - The attribute name
1023 * Returns: A Python object for the attribute, or NULL if something went
1024 * wrong
1025 */
1026static PyObject *
1027ssl_Context_getattr(ssl_ContextObj *self, char *name)
1028{
1029 return Py_FindMethod(ssl_Context_methods, (PyObject *)self, name);
1030}
1031
1032/*
1033 * Call the visitproc on all contained objects.
1034 *
1035 * Arguments: self - The Context object
1036 * visit - Function to call
1037 * arg - Extra argument to visit
1038 * Returns: 0 if all goes well, otherwise the return code from the first
1039 * call that gave non-zero result.
1040 */
1041static int
1042ssl_Context_traverse(ssl_ContextObj *self, visitproc visit, void *arg)
1043{
1044 int ret = 0;
1045
1046 if (ret == 0 && self->passphrase_callback != NULL)
1047 ret = visit((PyObject *)self->passphrase_callback, arg);
1048 if (ret == 0 && self->passphrase_userdata != NULL)
1049 ret = visit((PyObject *)self->passphrase_userdata, arg);
1050 if (ret == 0 && self->verify_callback != NULL)
1051 ret = visit((PyObject *)self->verify_callback, arg);
1052 if (ret == 0 && self->info_callback != NULL)
1053 ret = visit((PyObject *)self->info_callback, arg);
1054 if (ret == 0 && self->app_data != NULL)
1055 ret = visit(self->app_data, arg);
1056 return ret;
1057}
1058
1059/*
1060 * Decref all contained objects and zero the pointers.
1061 *
1062 * Arguments: self - The Context object
1063 * Returns: Always 0.
1064 */
1065static int
1066ssl_Context_clear(ssl_ContextObj *self)
1067{
1068 Py_XDECREF(self->passphrase_callback);
1069 self->passphrase_callback = NULL;
1070 Py_XDECREF(self->passphrase_userdata);
1071 self->passphrase_userdata = NULL;
1072 Py_XDECREF(self->verify_callback);
1073 self->verify_callback = NULL;
1074 Py_XDECREF(self->info_callback);
1075 self->info_callback = NULL;
1076 Py_XDECREF(self->app_data);
1077 self->app_data = NULL;
1078 return 0;
1079}
1080
1081/*
1082 * Deallocate the memory used by the Context object
1083 *
1084 * Arguments: self - The Context object
1085 * Returns: None
1086 */
1087static void
1088ssl_Context_dealloc(ssl_ContextObj *self)
1089{
1090 PyObject_GC_UnTrack((PyObject *)self);
1091 SSL_CTX_free(self->ctx);
1092 ssl_Context_clear(self);
1093 PyObject_GC_Del(self);
1094}
1095
1096
1097PyTypeObject ssl_Context_Type = {
1098 PyObject_HEAD_INIT(NULL)
1099 0,
1100 "Context",
1101 sizeof(ssl_ContextObj),
1102 0,
1103 (destructor)ssl_Context_dealloc,
1104 NULL, /* print */
1105 (getattrfunc)ssl_Context_getattr,
1106 NULL, /* setattr */
1107 NULL, /* compare */
1108 NULL, /* repr */
1109 NULL, /* as_number */
1110 NULL, /* as_sequence */
1111 NULL, /* as_mapping */
1112 NULL, /* hash */
1113 NULL, /* call */
1114 NULL, /* str */
1115 NULL, /* getattro */
1116 NULL, /* setattro */
1117 NULL, /* as_buffer */
1118 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1119 NULL, /* doc */
1120 (traverseproc)ssl_Context_traverse,
1121 (inquiry)ssl_Context_clear,
1122};
1123
1124
1125/*
1126 * Initialize the Context part of the SSL sub module
1127 *
1128 * Arguments: dict - Dictionary of the OpenSSL.SSL module
1129 * Returns: 1 for success, 0 otherwise
1130 */
1131int
1132init_ssl_context(PyObject *dict)
1133{
1134 ssl_Context_Type.ob_type = &PyType_Type;
1135 Py_INCREF(&ssl_Context_Type);
1136 if (PyDict_SetItemString(dict, "ContextType", (PyObject *)&ssl_Context_Type) != 0)
1137 return 0;
1138
1139 return 1;
1140}
1141