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