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