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