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