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