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