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