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