blob: 1fecc9bd2361fa0c7599252ab927a9ac6a3006de [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 Calderone28ebb302008-12-29 16:25:30 -050014#if PY_VERSION_HEX >= 0x02050000
15# define PYARG_PARSETUPLE_FORMAT const char
16#else
17# define PYARG_PARSETUPLE_FORMAT char
18#endif
19
Jean-Paul Calderone12ea9a02008-02-22 12:24:39 -050020#ifndef MS_WINDOWS
21# include <sys/socket.h>
22# include <netinet/in.h>
23# if !(defined(__BEOS__) || defined(__CYGWIN__))
24# include <netinet/tcp.h>
25# endif
26#else
27# include <winsock.h>
28# include <wincrypt.h>
29#endif
30
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050031#define SSL_MODULE
32#include "ssl.h"
33
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050034/*
35 * CALLBACKS
36 *
37 * Callbacks work like this: We provide a "global" callback in C which
38 * transforms the arguments into a Python argument tuple and calls the
39 * corresponding Python callback, and then parsing the return value back into
40 * things the C function can return.
41 *
42 * Three caveats:
43 * + How do we find the Context object where the Python callbacks are stored?
44 * + What about multithreading and execution frames?
45 * + What about Python callbacks that raise exceptions?
46 *
47 * The solution to the first issue is trivial if the callback provides
48 * "userdata" functionality. Since the only callbacks that don't provide
49 * userdata do provide a pointer to an SSL structure, we can associate an SSL
50 * object and a Connection one-to-one via the SSL_set/get_app_data()
51 * functions.
52 *
53 * The solution to the other issue is to rewrite the Py_BEGIN_ALLOW_THREADS
54 * macro allowing it (or rather a new macro) to specify where to save the
55 * thread state (in our case, as a member of the Connection/Context object) so
56 * we can retrieve it again before calling the Python callback.
57 */
58
59/*
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040060 * Globally defined passphrase callback. This is called from OpenSSL
61 * internally. The GIL will not be held when this function is invoked. It
62 * must not be held when the function returns.
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050063 *
64 * Arguments: buf - Buffer to store the returned passphrase in
65 * maxlen - Maximum length of the passphrase
66 * verify - If true, the passphrase callback should ask for a
67 * password twice and verify they're equal. If false, only
68 * ask once.
69 * arg - User data, always a Context object
70 * Returns: The length of the password if successful, 0 otherwise
71 */
72static int
73global_passphrase_callback(char *buf, int maxlen, int verify, void *arg)
74{
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040075 /*
76 * Initialize len here because we're always going to return it, and we
77 * might jump to the return before it gets initialized in any other way.
78 */
79 int len = 0;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050080 char *str;
81 PyObject *argv, *ret = NULL;
82 ssl_ContextObj *ctx = (ssl_ContextObj *)arg;
83
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040084 /*
85 * GIL isn't held yet. First things first - acquire it, or any Python API
86 * we invoke might segfault or blow up the sun. The reverse will be done
87 * before returning.
88 */
89 MY_END_ALLOW_THREADS(ctx->tstate);
90
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -040091 /* The Python callback is called with a (maxlen,verify,userdata) tuple */
92 argv = Py_BuildValue("(iiO)", maxlen, verify, ctx->passphrase_userdata);
93
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -040094 /*
95 * XXX Didn't check argv to see if it was NULL. -exarkun
96 */
97 ret = PyEval_CallObject(ctx->passphrase_callback, argv);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050098 Py_DECREF(argv);
99
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400100 if (ret == NULL) {
101 /*
102 * XXX The callback raised an exception. At the very least, it should
103 * be printed out here. An *actual* solution would be to raise it up
104 * through OpenSSL. That might be a bit tricky, but it's probably
105 * possible. -exarkun
106 */
107 goto out;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500108 }
109
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400110 if (!PyObject_IsTrue(ret)) {
111 /*
112 * Returned "", or None, or something. Treat it as no passphrase.
113 */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500114 Py_DECREF(ret);
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400115 goto out;
116 }
117
118 if (!PyString_Check(ret)) {
119 /*
120 * XXX Returned something that wasn't a string. This is bogus. We
121 * should report an error or raise an exception (again, through OpenSSL
122 * - tricky). -exarkun
123 */
124 Py_DECREF(ret);
125 goto out;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500126 }
127
128 len = PyString_Size(ret);
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400129 if (len > maxlen) {
130 /*
131 * XXX Returned more than we said they were allowed to return. Report
132 * an error or raise an exception (tricky blah blah). -exarkun
133 */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500134 len = maxlen;
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400135 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500136
137 str = PyString_AsString(ret);
138 strncpy(buf, str, len);
139 Py_XDECREF(ret);
140
Jean-Paul Calderone828c9cb2008-04-26 18:06:54 -0400141 out:
142 /*
143 * This function is returning into OpenSSL. Release the GIL again.
144 */
145 MY_BEGIN_ALLOW_THREADS(ctx->tstate);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500146 return len;
147}
148
149/*
150 * Globally defined verify callback
151 *
152 * Arguments: ok - True everything is OK "so far", false otherwise
153 * x509_ctx - Contains the certificate being checked, the current
154 * error number and depth, and the Connection we're
155 * dealing with
156 * Returns: True if everything is okay, false otherwise
157 */
158static int
159global_verify_callback(int ok, X509_STORE_CTX *x509_ctx)
160{
161 PyObject *argv, *ret;
162 SSL *ssl;
163 ssl_ConnectionObj *conn;
164 crypto_X509Obj *cert;
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -0500165 int errnum, errdepth, c_ret;
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400166
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400167 // Get Connection object to check thread state
168 ssl = (SSL *)X509_STORE_CTX_get_app_data(x509_ctx);
169 conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400170
Jean-Paul Calderone26aea022008-09-21 18:47:06 -0400171 MY_END_ALLOW_THREADS(conn->tstate);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400172
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500173 cert = crypto_X509_New(X509_STORE_CTX_get_current_cert(x509_ctx), 0);
174 errnum = X509_STORE_CTX_get_error(x509_ctx);
175 errdepth = X509_STORE_CTX_get_error_depth(x509_ctx);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400176
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500177 argv = Py_BuildValue("(OOiii)", (PyObject *)conn, (PyObject *)cert,
178 errnum, errdepth, ok);
179 Py_DECREF(cert);
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400180 ret = PyEval_CallObject(conn->context->verify_callback, argv);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500181 Py_DECREF(argv);
182
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400183 if (ret != NULL && PyObject_IsTrue(ret)) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500184 X509_STORE_CTX_set_error(x509_ctx, X509_V_OK);
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400185 Py_DECREF(ret);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500186 c_ret = 1;
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400187 } else {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500188 c_ret = 0;
Jean-Paul Calderoneac0d95f2008-03-10 00:00:42 -0400189 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500190
Jean-Paul Calderone26aea022008-09-21 18:47:06 -0400191 MY_BEGIN_ALLOW_THREADS(conn->tstate);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500192 return c_ret;
193}
194
195/*
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400196 * Globally defined info callback. This is called from OpenSSL internally.
197 * The GIL will not be held when this function is invoked. It must not be held
198 * when the function returns.
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500199 *
200 * Arguments: ssl - The Connection
201 * where - The part of the SSL code that called us
202 * _ret - The return code of the SSL function that called us
203 * Returns: None
204 */
205static void
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -0500206global_info_callback(const SSL *ssl, int where, int _ret)
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500207{
208 ssl_ConnectionObj *conn = (ssl_ConnectionObj *)SSL_get_app_data(ssl);
209 PyObject *argv, *ret;
210
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400211 /*
212 * GIL isn't held yet. First things first - acquire it, or any Python API
213 * we invoke might segfault or blow up the sun. The reverse will be done
214 * before returning.
215 */
216 MY_END_ALLOW_THREADS(conn->tstate);
217
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500218 argv = Py_BuildValue("(Oii)", (PyObject *)conn, where, _ret);
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400219 ret = PyEval_CallObject(conn->context->info_callback, argv);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500220 Py_DECREF(argv);
221
Jean-Paul Calderone5ef86512008-04-26 19:06:28 -0400222 if (ret == NULL) {
223 /*
224 * XXX - This should be reported somehow. -exarkun
225 */
226 PyErr_Clear();
227 } else {
228 Py_DECREF(ret);
229 }
230
231 /*
232 * This function is returning into OpenSSL. Release the GIL again.
233 */
234 MY_BEGIN_ALLOW_THREADS(conn->tstate);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500235 return;
236}
237
238
239
240
241static char ssl_Context_load_verify_locations_doc[] = "\n\
242Let SSL know where we can find trusted certificates for the certificate\n\
243chain\n\
244\n\
245Arguments: self - The Context object\n\
246 args - The Python argument tuple, should be:\n\
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400247 cafile - In which file we can find the certificates\n\
248 capath - In which directory we can find the certificates\r\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500249Returns: None\n\
250";
251static PyObject *
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400252ssl_Context_load_verify_locations(ssl_ContextObj *self, PyObject *args) {
253 char *cafile = NULL;
254 char *capath = NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500255
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400256 if (!PyArg_ParseTuple(args, "z|z:load_verify_locations", &cafile, &capath)) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500257 return NULL;
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400258 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500259
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400260 if (!SSL_CTX_load_verify_locations(self->ctx, cafile, capath))
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500261 {
262 exception_from_error_queue();
263 return NULL;
264 }
265 else
266 {
267 Py_INCREF(Py_None);
268 return Py_None;
269 }
270}
271
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400272static char ssl_Context_set_default_verify_paths_doc[] = "\n\
273Use the platform-specific CA certificate locations\n\
274\n\
275Arguments: self - The Context object\n\
276 args - None\n\
277\n\
278Returns: None\n\
279";
280static PyObject *
281ssl_Context_set_default_verify_paths(ssl_ContextObj *self, PyObject *args) {
Jean-Paul Calderone9eadb962008-09-07 21:20:44 -0400282 if (!PyArg_ParseTuple(args, ":set_default_verify_paths")) {
283 return NULL;
284 }
285
Jean-Paul Calderone286b1922008-09-07 21:35:38 -0400286 /*
287 * XXX Error handling for SSL_CTX_set_default_verify_paths is untested.
288 * -exarkun
289 */
290 if (!SSL_CTX_set_default_verify_paths(self->ctx)) {
291 exception_from_error_queue();
292 return NULL;
293 }
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400294 Py_INCREF(Py_None);
295 return Py_None;
296};
297
298
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500299static char ssl_Context_set_passwd_cb_doc[] = "\n\
300Set the passphrase callback\n\
301\n\
302Arguments: self - The Context object\n\
303 args - The Python argument tuple, should be:\n\
304 callback - The Python callback to use\n\
305 userdata - (optional) A Python object which will be given as\n\
306 argument to the callback\n\
307Returns: None\n\
308";
309static PyObject *
310ssl_Context_set_passwd_cb(ssl_ContextObj *self, PyObject *args)
311{
312 PyObject *callback = NULL, *userdata = Py_None;
313
314 if (!PyArg_ParseTuple(args, "O|O:set_passwd_cb", &callback, &userdata))
315 return NULL;
316
317 if (!PyCallable_Check(callback))
318 {
319 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
320 return NULL;
321 }
322
323 Py_DECREF(self->passphrase_callback);
324 Py_INCREF(callback);
325 self->passphrase_callback = callback;
326 SSL_CTX_set_default_passwd_cb(self->ctx, global_passphrase_callback);
327
328 Py_DECREF(self->passphrase_userdata);
329 Py_INCREF(userdata);
330 self->passphrase_userdata = userdata;
331 SSL_CTX_set_default_passwd_cb_userdata(self->ctx, (void *)self);
332
333 Py_INCREF(Py_None);
334 return Py_None;
335}
336
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500337static crypto_X509Obj *
338parse_certificate_argument(const char* format1, const char* format2, PyObject* args)
339{
340 static PyTypeObject *crypto_X509_type = NULL;
341 crypto_X509Obj *cert;
342
343 /* We need to check that cert really is an X509 object before
344 we deal with it. The problem is we can't just quickly verify
345 the type (since that comes from another module). This should
346 do the trick (reasonably well at least): Once we have one
347 verified object, we use it's type object for future
348 comparisons. */
349
350 if (!crypto_X509_type)
351 {
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -0500352 if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format1, &cert))
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500353 return NULL;
354
355 if (strcmp(cert->ob_type->tp_name, "X509") != 0 ||
356 cert->ob_type->tp_basicsize != sizeof(crypto_X509Obj))
357 {
358 PyErr_SetString(PyExc_TypeError, "Expected an X509 object");
359 return NULL;
360 }
361
362 crypto_X509_type = cert->ob_type;
363 }
364 else
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -0500365 if (!PyArg_ParseTuple(args, (PYARG_PARSETUPLE_FORMAT *)format2, crypto_X509_type,
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500366 &cert))
367 return NULL;
368 return cert;
369}
370
371static char ssl_Context_add_extra_chain_cert_doc[] = "\n\
372Add certificate to chain\n\
373\n\
374Arguments: self - The Context object\n\
375 args - The Python argument tuple, should be:\n\
376 certobj - The X509 certificate object to add to the chain\n\
377Returns: None\n\
378";
379
380static PyObject *
381ssl_Context_add_extra_chain_cert(ssl_ContextObj *self, PyObject *args)
382{
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500383 X509* cert_original;
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500384 crypto_X509Obj *cert = parse_certificate_argument(
385 "O:add_extra_chain_cert", "O!:add_extra_chain_cert", args);
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500386 if (cert == NULL)
387 {
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500388 return NULL;
389 }
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500390 if (!(cert_original = X509_dup(cert->x509)))
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500391 {
Jean-Paul Calderone0ce98072008-02-18 23:22:29 -0500392 /* exception_from_error_queue(); */
393 PyErr_SetString(PyExc_RuntimeError, "X509_dup failed");
394 return NULL;
395 }
396 if (!SSL_CTX_add_extra_chain_cert(self->ctx, cert_original))
397 {
398 X509_free(cert_original);
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500399 exception_from_error_queue();
400 return NULL;
401 }
402 else
403 {
404 Py_INCREF(Py_None);
405 return Py_None;
406 }
407}
408
409
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500410static char ssl_Context_use_certificate_chain_file_doc[] = "\n\
411Load a certificate chain from a file\n\
412\n\
413Arguments: self - The Context object\n\
414 args - The Python argument tuple, should be:\n\
415 certfile - The name of the certificate chain file\n\
416Returns: None\n\
417";
418static PyObject *
419ssl_Context_use_certificate_chain_file(ssl_ContextObj *self, PyObject *args)
420{
421 char *certfile;
422
423 if (!PyArg_ParseTuple(args, "s:use_certificate_chain_file", &certfile))
424 return NULL;
425
426 if (!SSL_CTX_use_certificate_chain_file(self->ctx, certfile))
427 {
428 exception_from_error_queue();
429 return NULL;
430 }
431 else
432 {
433 Py_INCREF(Py_None);
434 return Py_None;
435 }
436}
437
438
439static char ssl_Context_use_certificate_file_doc[] = "\n\
440Load a certificate from a file\n\
441\n\
442Arguments: self - The Context object\n\
443 args - The Python argument tuple, should be:\n\
444 certfile - The name of the certificate file\n\
445 filetype - (optional) The encoding of the file, default is PEM\n\
446Returns: None\n\
447";
448static PyObject *
449ssl_Context_use_certificate_file(ssl_ContextObj *self, PyObject *args)
450{
451 char *certfile;
452 int filetype = SSL_FILETYPE_PEM;
453
454 if (!PyArg_ParseTuple(args, "s|i:use_certificate_file", &certfile, &filetype))
455 return NULL;
456
457 if (!SSL_CTX_use_certificate_file(self->ctx, certfile, filetype))
458 {
459 exception_from_error_queue();
460 return NULL;
461 }
462 else
463 {
464 Py_INCREF(Py_None);
465 return Py_None;
466 }
467}
468
469static char ssl_Context_use_certificate_doc[] = "\n\
470Load a certificate from a X509 object\n\
471\n\
472Arguments: self - The Context object\n\
473 args - The Python argument tuple, should be:\n\
474 cert - The X509 object\n\
475Returns: None\n\
476";
477static PyObject *
478ssl_Context_use_certificate(ssl_ContextObj *self, PyObject *args)
479{
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500480 crypto_X509Obj *cert = parse_certificate_argument(
481 "O:use_certificate", "O!:use_certificate", args);
482 if (cert == NULL) {
483 return NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500484 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500485
486 if (!SSL_CTX_use_certificate(self->ctx, cert->x509))
487 {
488 exception_from_error_queue();
489 return NULL;
490 }
491 else
492 {
493 Py_INCREF(Py_None);
494 return Py_None;
495 }
496}
497
498static char ssl_Context_use_privatekey_file_doc[] = "\n\
499Load a private key from a file\n\
500\n\
501Arguments: self - The Context object\n\
502 args - The Python argument tuple, should be:\n\
503 keyfile - The name of the key file\n\
504 filetype - (optional) The encoding of the file, default is PEM\n\
505Returns: None\n\
506";
507static PyObject *
508ssl_Context_use_privatekey_file(ssl_ContextObj *self, PyObject *args)
509{
510 char *keyfile;
511 int filetype = SSL_FILETYPE_PEM, ret;
512
513 if (!PyArg_ParseTuple(args, "s|i:use_privatekey_file", &keyfile, &filetype))
514 return NULL;
515
516 MY_BEGIN_ALLOW_THREADS(self->tstate);
517 ret = SSL_CTX_use_PrivateKey_file(self->ctx, keyfile, filetype);
518 MY_END_ALLOW_THREADS(self->tstate);
519
520 if (PyErr_Occurred())
521 {
522 flush_error_queue();
523 return NULL;
524 }
525
526 if (!ret)
527 {
528 exception_from_error_queue();
529 return NULL;
530 }
531 else
532 {
533 Py_INCREF(Py_None);
534 return Py_None;
535 }
536}
537
538static char ssl_Context_use_privatekey_doc[] = "\n\
539Load a private key from a PKey object\n\
540\n\
541Arguments: self - The Context object\n\
542 args - The Python argument tuple, should be:\n\
543 pkey - The PKey object\n\
544Returns: None\n\
545";
546static PyObject *
547ssl_Context_use_privatekey(ssl_ContextObj *self, PyObject *args)
548{
549 static PyTypeObject *crypto_PKey_type = NULL;
550 crypto_PKeyObj *pkey;
551
552 /* We need to check that cert really is a PKey object before
553 we deal with it. The problem is we can't just quickly verify
554 the type (since that comes from another module). This should
555 do the trick (reasonably well at least): Once we have one
556 verified object, we use it's type object for future
557 comparisons. */
558
559 if (!crypto_PKey_type)
560 {
561 if (!PyArg_ParseTuple(args, "O:use_privatekey", &pkey))
562 return NULL;
563
Jean-Paul Calderone30c09ea2008-03-21 17:04:05 -0400564 if (strcmp(pkey->ob_type->tp_name, "PKey") != 0 ||
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500565 pkey->ob_type->tp_basicsize != sizeof(crypto_PKeyObj))
566 {
567 PyErr_SetString(PyExc_TypeError, "Expected a PKey object");
568 return NULL;
569 }
570
571 crypto_PKey_type = pkey->ob_type;
572 }
573 else
574 if (!PyArg_ParseTuple(args, "O!:use_privatekey", crypto_PKey_type, &pkey))
575 return NULL;
576
577 if (!SSL_CTX_use_PrivateKey(self->ctx, pkey->pkey))
578 {
579 exception_from_error_queue();
580 return NULL;
581 }
582 else
583 {
584 Py_INCREF(Py_None);
585 return Py_None;
586 }
587}
588
589static char ssl_Context_check_privatekey_doc[] = "\n\
590Check that the private key and certificate match up\n\
591\n\
592Arguments: self - The Context object\n\
593 args - The Python argument tuple, should be empty\n\
594Returns: None (raises an exception if something's wrong)\n\
595";
596static PyObject *
597ssl_Context_check_privatekey(ssl_ContextObj *self, PyObject *args)
598{
599 if (!PyArg_ParseTuple(args, ":check_privatekey"))
600 return NULL;
601
602 if (!SSL_CTX_check_private_key(self->ctx))
603 {
604 exception_from_error_queue();
605 return NULL;
606 }
607 else
608 {
609 Py_INCREF(Py_None);
610 return Py_None;
611 }
612}
613
614static char ssl_Context_load_client_ca_doc[] = "\n\
615Load the trusted certificates that will be sent to the client (basically\n\
616telling the client \"These are the guys I trust\")\n\
617\n\
618Arguments: self - The Context object\n\
619 args - The Python argument tuple, should be:\n\
620 cafile - The name of the certificates file\n\
621Returns: None\n\
622";
623static PyObject *
624ssl_Context_load_client_ca(ssl_ContextObj *self, PyObject *args)
625{
626 char *cafile;
627
628 if (!PyArg_ParseTuple(args, "s:load_client_ca", &cafile))
629 return NULL;
630
631 SSL_CTX_set_client_CA_list(self->ctx, SSL_load_client_CA_file(cafile));
632
633 Py_INCREF(Py_None);
634 return Py_None;
635}
636
637static char ssl_Context_set_session_id_doc[] = "\n\
638Set the session identifier, this is needed if you want to do session\n\
639resumption (which, ironically, isn't implemented yet)\n\
640\n\
641Arguments: self - The Context object\n\
642 args - The Python argument tuple, should be:\n\
643 buf - A Python object that can be safely converted to a string\n\
644Returns: None\n\
645";
646static PyObject *
647ssl_Context_set_session_id(ssl_ContextObj *self, PyObject *args)
648{
Jean-Paul Calderone28ebb302008-12-29 16:25:30 -0500649 unsigned char *buf;
650 unsigned int len;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500651
652 if (!PyArg_ParseTuple(args, "s#:set_session_id", &buf, &len))
653 return NULL;
654
655 if (!SSL_CTX_set_session_id_context(self->ctx, buf, len))
656 {
657 exception_from_error_queue();
658 return NULL;
659 }
660 else
661 {
662 Py_INCREF(Py_None);
663 return Py_None;
664 }
665}
666
667static char ssl_Context_set_verify_doc[] = "\n\
668Set the verify mode and verify callback\n\
669\n\
670Arguments: self - The Context object\n\
671 args - The Python argument tuple, should be:\n\
Jean-Paul Calderone24aedf42008-03-06 22:01:16 -0500672 mode - The verify mode, this is either VERIFY_NONE or\n\
673 VERIFY_PEER combined with possible other flags\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500674 callback - The Python callback to use\n\
675Returns: None\n\
Jean-Paul Calderone24aedf42008-03-06 22:01:16 -0500676\n\
677See SSL_CTX_set_verify(3SSL) for further details.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500678";
679static PyObject *
680ssl_Context_set_verify(ssl_ContextObj *self, PyObject *args)
681{
682 int mode;
683 PyObject *callback = NULL;
684
685 if (!PyArg_ParseTuple(args, "iO:set_verify", &mode, &callback))
686 return NULL;
687
688 if (!PyCallable_Check(callback))
689 {
690 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
691 return NULL;
692 }
693
694 Py_DECREF(self->verify_callback);
695 Py_INCREF(callback);
696 self->verify_callback = callback;
697 SSL_CTX_set_verify(self->ctx, mode, global_verify_callback);
698
699 Py_INCREF(Py_None);
700 return Py_None;
701}
702
703static char ssl_Context_set_verify_depth_doc[] = "\n\
704Set the verify depth\n\
705\n\
706Arguments: self - The Context object\n\
707 args - The Python argument tuple, should be:\n\
708 depth - An integer specifying the verify depth\n\
709Returns: None\n\
710";
711static PyObject *
712ssl_Context_set_verify_depth(ssl_ContextObj *self, PyObject *args)
713{
714 int depth;
715
716 if (!PyArg_ParseTuple(args, "i:set_verify_depth", &depth))
717 return NULL;
718
719 SSL_CTX_set_verify_depth(self->ctx, depth);
720 Py_INCREF(Py_None);
721 return Py_None;
722}
723
724static char ssl_Context_get_verify_mode_doc[] = "\n\
725Get the verify mode\n\
726\n\
727Arguments: self - The Context object\n\
728 args - The Python argument tuple, should be empty\n\
729Returns: The verify mode\n\
730";
731static PyObject *
732ssl_Context_get_verify_mode(ssl_ContextObj *self, PyObject *args)
733{
734 int mode;
735
736 if (!PyArg_ParseTuple(args, ":get_verify_mode"))
737 return NULL;
738
739 mode = SSL_CTX_get_verify_mode(self->ctx);
740 return PyInt_FromLong((long)mode);
741}
742
743static char ssl_Context_get_verify_depth_doc[] = "\n\
744Get the verify depth\n\
745\n\
746Arguments: self - The Context object\n\
747 args - The Python argument tuple, should be empty\n\
748Returns: The verify depth\n\
749";
750static PyObject *
751ssl_Context_get_verify_depth(ssl_ContextObj *self, PyObject *args)
752{
753 int depth;
754
755 if (!PyArg_ParseTuple(args, ":get_verify_depth"))
756 return NULL;
757
758 depth = SSL_CTX_get_verify_depth(self->ctx);
759 return PyInt_FromLong((long)depth);
760}
761
762static char ssl_Context_load_tmp_dh_doc[] = "\n\
763Load parameters for Ephemeral Diffie-Hellman\n\
764\n\
765Arguments: self - The Context object\n\
766 args - The Python argument tuple, should be:\n\
767 dhfile - The file to load EDH parameters from\n\
768Returns: None\n\
769";
770static PyObject *
771ssl_Context_load_tmp_dh(ssl_ContextObj *self, PyObject *args)
772{
773 char *dhfile;
774 BIO *bio;
775 DH *dh;
776
777 if (!PyArg_ParseTuple(args, "s:load_tmp_dh", &dhfile))
778 return NULL;
779
780 bio = BIO_new_file(dhfile, "r");
781 if (bio == NULL)
782 return PyErr_NoMemory();
783
784 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
785 SSL_CTX_set_tmp_dh(self->ctx, dh);
786 DH_free(dh);
787 BIO_free(bio);
788
789 Py_INCREF(Py_None);
790 return Py_None;
791}
792
793static char ssl_Context_set_cipher_list_doc[] = "\n\
794Change the cipher list\n\
795\n\
796Arguments: self - The Context object\n\
797 args - The Python argument tuple, should be:\n\
798 cipher_list - A cipher list, see ciphers(1)\n\
799Returns: None\n\
800";
801static PyObject *
802ssl_Context_set_cipher_list(ssl_ContextObj *self, PyObject *args)
803{
804 char *cipher_list;
805
806 if (!PyArg_ParseTuple(args, "s:set_cipher_list", &cipher_list))
807 return NULL;
808
809 if (!SSL_CTX_set_cipher_list(self->ctx, cipher_list))
810 {
811 exception_from_error_queue();
812 return NULL;
813 }
814 else
815 {
816 Py_INCREF(Py_None);
817 return Py_None;
818 }
819}
820
821static char ssl_Context_set_timeout_doc[] = "\n\
822Set session timeout\n\
823\n\
824Arguments: self - The Context object\n\
825 args - The Python argument tuple, should be:\n\
826 t - The timeout in seconds\n\
827Returns: The previous session timeout\n\
828";
829static PyObject *
830ssl_Context_set_timeout(ssl_ContextObj *self, PyObject *args)
831{
832 long t, ret;
833
834 if (!PyArg_ParseTuple(args, "l:set_timeout", &t))
835 return NULL;
836
837 ret = SSL_CTX_set_timeout(self->ctx, t);
838 return PyLong_FromLong(ret);
839}
840
841static char ssl_Context_get_timeout_doc[] = "\n\
842Get the session timeout\n\
843\n\
844Arguments: self - The Context object\n\
845 args - The Python argument tuple, should be empty\n\
846Returns: The session timeout\n\
847";
848static PyObject *
849ssl_Context_get_timeout(ssl_ContextObj *self, PyObject *args)
850{
851 long ret;
852
853 if (!PyArg_ParseTuple(args, ":get_timeout"))
854 return NULL;
855
856 ret = SSL_CTX_get_timeout(self->ctx);
857 return PyLong_FromLong(ret);
858}
859
860static char ssl_Context_set_info_callback_doc[] = "\n\
861Set the info callback\n\
862\n\
863Arguments: self - The Context object\n\
864 args - The Python argument tuple, should be:\n\
865 callback - The Python callback to use\n\
866Returns: None\n\
867";
868static PyObject *
869ssl_Context_set_info_callback(ssl_ContextObj *self, PyObject *args)
870{
871 PyObject *callback;
872
873 if (!PyArg_ParseTuple(args, "O:set_info_callback", &callback))
874 return NULL;
875
876 if (!PyCallable_Check(callback))
877 {
878 PyErr_SetString(PyExc_TypeError, "expected PyCallable");
879 return NULL;
880 }
881
882 Py_DECREF(self->info_callback);
883 Py_INCREF(callback);
884 self->info_callback = callback;
885 SSL_CTX_set_info_callback(self->ctx, global_info_callback);
886
887 Py_INCREF(Py_None);
888 return Py_None;
889}
890
891static char ssl_Context_get_app_data_doc[] = "\n\
892Get the application data (supplied via set_app_data())\n\
893\n\
894Arguments: self - The Context object\n\
895 args - The Python argument tuple, should be empty\n\
896Returns: The application data\n\
897";
898static PyObject *
899ssl_Context_get_app_data(ssl_ContextObj *self, PyObject *args)
900{
901 if (!PyArg_ParseTuple(args, ":get_app_data"))
902 return NULL;
903
904 Py_INCREF(self->app_data);
905 return self->app_data;
906}
907
908static char ssl_Context_set_app_data_doc[] = "\n\
909Set the application data (will be returned from get_app_data())\n\
910\n\
911Arguments: self - The Context object\n\
912 args - The Python argument tuple, should be:\n\
913 data - Any Python object\n\
914Returns: None\n\
915";
916static PyObject *
917ssl_Context_set_app_data(ssl_ContextObj *self, PyObject *args)
918{
919 PyObject *data;
920
921 if (!PyArg_ParseTuple(args, "O:set_app_data", &data))
922 return NULL;
923
924 Py_DECREF(self->app_data);
925 Py_INCREF(data);
926 self->app_data = data;
927
928 Py_INCREF(Py_None);
929 return Py_None;
930}
931
932static char ssl_Context_get_cert_store_doc[] = "\n\
933Get the certificate store for the context\n\
934\n\
935Arguments: self - The Context object\n\
936 args - The Python argument tuple, should be empty\n\
937Returns: A X509Store object\n\
938";
939static PyObject *
940ssl_Context_get_cert_store(ssl_ContextObj *self, PyObject *args)
941{
942 X509_STORE *store;
943
944 if (!PyArg_ParseTuple(args, ":get_cert_store"))
945 return NULL;
946
947 if ((store = SSL_CTX_get_cert_store(self->ctx)) == NULL)
948 {
949 Py_INCREF(Py_None);
950 return Py_None;
951 }
952 else
953 {
954 return (PyObject *)crypto_X509Store_New(store, 0);
955 }
956}
957
958static char ssl_Context_set_options_doc[] = "\n\
959Add options. Options set before are not cleared!\n\
960\n\
961Arguments: self - The Context object\n\
962 args - The Python argument tuple, should be:\n\
963 options - The options to add.\n\
964Returns: The new option bitmask.\n\
965";
966static PyObject *
967ssl_Context_set_options(ssl_ContextObj *self, PyObject *args)
968{
969 long options;
970
971 if (!PyArg_ParseTuple(args, "l:set_options", &options))
972 return NULL;
973
974 return PyInt_FromLong(SSL_CTX_set_options(self->ctx, options));
975}
976
977
978/*
979 * Member methods in the Context object
980 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
981 * { 'name', (PyCFunction)ssl_Context_name, METH_VARARGS }
982 * for convenience
983 * ADD_ALIAS(name,real) creates an "alias" of the ssl_Context_real
984 * function with the name 'name'
985 */
986#define ADD_METHOD(name) { #name, (PyCFunction)ssl_Context_##name, METH_VARARGS, ssl_Context_##name##_doc }
987static PyMethodDef ssl_Context_methods[] = {
988 ADD_METHOD(load_verify_locations),
989 ADD_METHOD(set_passwd_cb),
Jean-Paul Calderone1cb5d022008-09-07 20:58:50 -0400990 ADD_METHOD(set_default_verify_paths),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500991 ADD_METHOD(use_certificate_chain_file),
992 ADD_METHOD(use_certificate_file),
993 ADD_METHOD(use_certificate),
Jean-Paul Calderoned3ada852008-02-18 21:17:29 -0500994 ADD_METHOD(add_extra_chain_cert),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500995 ADD_METHOD(use_privatekey_file),
996 ADD_METHOD(use_privatekey),
997 ADD_METHOD(check_privatekey),
998 ADD_METHOD(load_client_ca),
999 ADD_METHOD(set_session_id),
1000 ADD_METHOD(set_verify),
1001 ADD_METHOD(set_verify_depth),
1002 ADD_METHOD(get_verify_mode),
1003 ADD_METHOD(get_verify_depth),
1004 ADD_METHOD(load_tmp_dh),
1005 ADD_METHOD(set_cipher_list),
1006 ADD_METHOD(set_timeout),
1007 ADD_METHOD(get_timeout),
1008 ADD_METHOD(set_info_callback),
1009 ADD_METHOD(get_app_data),
1010 ADD_METHOD(set_app_data),
1011 ADD_METHOD(get_cert_store),
1012 ADD_METHOD(set_options),
1013 { NULL, NULL }
1014};
1015#undef ADD_METHOD
1016
1017
1018/* Constructor, takes an int specifying which method to use */
1019/*
1020 * Constructor for Context objects
1021 *
1022 * Arguments: i_method - The SSL method to use, one of the SSLv2_METHOD,
1023 * SSLv3_METHOD, SSLv23_METHOD and TLSv1_METHOD
1024 * constants.
1025 * Returns: The newly created Context object
1026 */
1027ssl_ContextObj *
1028ssl_Context_New(int i_method)
1029{
1030 SSL_METHOD *method;
1031 ssl_ContextObj *self;
1032
1033 switch (i_method)
1034 {
1035 /* Too bad TLSv1 servers can't accept SSLv3 clients */
1036 case ssl_SSLv2_METHOD: method = SSLv2_method(); break;
1037 case ssl_SSLv23_METHOD: method = SSLv23_method(); break;
1038 case ssl_SSLv3_METHOD: method = SSLv3_method(); break;
1039 case ssl_TLSv1_METHOD: method = TLSv1_method(); break;
1040 default:
1041 PyErr_SetString(PyExc_ValueError, "No such protocol");
1042 return NULL;
1043 }
1044
1045 self = PyObject_GC_New(ssl_ContextObj, &ssl_Context_Type);
1046 if (self == NULL)
1047 return (ssl_ContextObj *)PyErr_NoMemory();
1048
1049 self->ctx = SSL_CTX_new(method);
1050 Py_INCREF(Py_None);
1051 self->passphrase_callback = Py_None;
1052 Py_INCREF(Py_None);
1053 self->verify_callback = Py_None;
1054 Py_INCREF(Py_None);
1055 self->info_callback = Py_None;
1056
1057 Py_INCREF(Py_None);
1058 self->passphrase_userdata = Py_None;
1059
1060 Py_INCREF(Py_None);
1061 self->app_data = Py_None;
1062
1063 /* Some initialization that's required to operate smoothly in Python */
1064 SSL_CTX_set_app_data(self->ctx, self);
1065 SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
1066 SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
1067 SSL_MODE_AUTO_RETRY);
1068
1069 self->tstate = NULL;
1070 PyObject_GC_Track((PyObject *)self);
1071
1072 return self;
1073}
1074
1075/*
1076 * Find attribute
1077 *
1078 * Arguments: self - The Context object
1079 * name - The attribute name
1080 * Returns: A Python object for the attribute, or NULL if something went
1081 * wrong
1082 */
1083static PyObject *
1084ssl_Context_getattr(ssl_ContextObj *self, char *name)
1085{
1086 return Py_FindMethod(ssl_Context_methods, (PyObject *)self, name);
1087}
1088
1089/*
1090 * Call the visitproc on all contained objects.
1091 *
1092 * Arguments: self - The Context object
1093 * visit - Function to call
1094 * arg - Extra argument to visit
1095 * Returns: 0 if all goes well, otherwise the return code from the first
1096 * call that gave non-zero result.
1097 */
1098static int
1099ssl_Context_traverse(ssl_ContextObj *self, visitproc visit, void *arg)
1100{
1101 int ret = 0;
1102
1103 if (ret == 0 && self->passphrase_callback != NULL)
1104 ret = visit((PyObject *)self->passphrase_callback, arg);
1105 if (ret == 0 && self->passphrase_userdata != NULL)
1106 ret = visit((PyObject *)self->passphrase_userdata, arg);
1107 if (ret == 0 && self->verify_callback != NULL)
1108 ret = visit((PyObject *)self->verify_callback, arg);
1109 if (ret == 0 && self->info_callback != NULL)
1110 ret = visit((PyObject *)self->info_callback, arg);
1111 if (ret == 0 && self->app_data != NULL)
1112 ret = visit(self->app_data, arg);
1113 return ret;
1114}
1115
1116/*
1117 * Decref all contained objects and zero the pointers.
1118 *
1119 * Arguments: self - The Context object
1120 * Returns: Always 0.
1121 */
1122static int
1123ssl_Context_clear(ssl_ContextObj *self)
1124{
1125 Py_XDECREF(self->passphrase_callback);
1126 self->passphrase_callback = NULL;
1127 Py_XDECREF(self->passphrase_userdata);
1128 self->passphrase_userdata = NULL;
1129 Py_XDECREF(self->verify_callback);
1130 self->verify_callback = NULL;
1131 Py_XDECREF(self->info_callback);
1132 self->info_callback = NULL;
1133 Py_XDECREF(self->app_data);
1134 self->app_data = NULL;
1135 return 0;
1136}
1137
1138/*
1139 * Deallocate the memory used by the Context object
1140 *
1141 * Arguments: self - The Context object
1142 * Returns: None
1143 */
1144static void
1145ssl_Context_dealloc(ssl_ContextObj *self)
1146{
1147 PyObject_GC_UnTrack((PyObject *)self);
1148 SSL_CTX_free(self->ctx);
1149 ssl_Context_clear(self);
1150 PyObject_GC_Del(self);
1151}
1152
1153
1154PyTypeObject ssl_Context_Type = {
1155 PyObject_HEAD_INIT(NULL)
1156 0,
1157 "Context",
1158 sizeof(ssl_ContextObj),
1159 0,
1160 (destructor)ssl_Context_dealloc,
1161 NULL, /* print */
1162 (getattrfunc)ssl_Context_getattr,
1163 NULL, /* setattr */
1164 NULL, /* compare */
1165 NULL, /* repr */
1166 NULL, /* as_number */
1167 NULL, /* as_sequence */
1168 NULL, /* as_mapping */
1169 NULL, /* hash */
1170 NULL, /* call */
1171 NULL, /* str */
1172 NULL, /* getattro */
1173 NULL, /* setattro */
1174 NULL, /* as_buffer */
1175 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
1176 NULL, /* doc */
1177 (traverseproc)ssl_Context_traverse,
1178 (inquiry)ssl_Context_clear,
1179};
1180
1181
1182/*
1183 * Initialize the Context part of the SSL sub module
1184 *
1185 * Arguments: dict - Dictionary of the OpenSSL.SSL module
1186 * Returns: 1 for success, 0 otherwise
1187 */
1188int
1189init_ssl_context(PyObject *dict)
1190{
1191 ssl_Context_Type.ob_type = &PyType_Type;
1192 Py_INCREF(&ssl_Context_Type);
1193 if (PyDict_SetItemString(dict, "ContextType", (PyObject *)&ssl_Context_Type) != 0)
1194 return 0;
1195
1196 return 1;
1197}
1198