This commit was manufactured by cvs2svn to create tag 'r23a1-fork'.
[python/dscho.git] / Modules / _ssl.c
blobad0b59b894434efa0b183c8b705a38ec83d7d12d
1 /* SSL socket module
3 SSL support based on patches by Brian E Gallew and Laszlo Kovacs.
5 This module is imported by socket.py. It should *not* be used
6 directly.
8 */
10 #include "Python.h"
11 enum py_ssl_error {
12 /* these mirror ssl.h */
13 PY_SSL_ERROR_NONE,
14 PY_SSL_ERROR_SSL,
15 PY_SSL_ERROR_WANT_READ,
16 PY_SSL_ERROR_WANT_WRITE,
17 PY_SSL_ERROR_WANT_X509_LOOKUP,
18 PY_SSL_ERROR_SYSCALL, /* look at error stack/return value/errno */
19 PY_SSL_ERROR_ZERO_RETURN,
20 PY_SSL_ERROR_WANT_CONNECT,
21 /* start of non ssl.h errorcodes */
22 PY_SSL_ERROR_EOF, /* special case of SSL_ERROR_SYSCALL */
23 PY_SSL_ERROR_INVALID_ERROR_CODE
26 /* Include symbols from _socket module */
27 #include "socketmodule.h"
29 /* Include OpenSSL header files */
30 #include "openssl/rsa.h"
31 #include "openssl/crypto.h"
32 #include "openssl/x509.h"
33 #include "openssl/pem.h"
34 #include "openssl/ssl.h"
35 #include "openssl/err.h"
36 #include "openssl/rand.h"
38 /* SSL error object */
39 static PyObject *PySSLErrorObject;
41 /* SSL socket object */
43 #define X509_NAME_MAXLEN 256
45 /* RAND_* APIs got added to OpenSSL in 0.9.5 */
46 #if OPENSSL_VERSION_NUMBER >= 0x0090500fL
47 # define HAVE_OPENSSL_RAND 1
48 #else
49 # undef HAVE_OPENSSL_RAND
50 #endif
52 typedef struct {
53 PyObject_HEAD
54 PySocketSockObject *Socket; /* Socket on which we're layered */
55 SSL_CTX* ctx;
56 SSL* ssl;
57 X509* server_cert;
58 BIO* sbio;
59 char server[X509_NAME_MAXLEN];
60 char issuer[X509_NAME_MAXLEN];
62 } PySSLObject;
64 static PyTypeObject PySSL_Type;
65 static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args);
66 static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args);
68 #define PySSLObject_Check(v) ((v)->ob_type == &PySSL_Type)
70 /* XXX It might be helpful to augment the error message generated
71 below with the name of the SSL function that generated the error.
72 I expect it's obvious most of the time.
75 static PyObject *
76 PySSL_SetError(PySSLObject *obj, int ret)
78 PyObject *v, *n, *s;
79 char *errstr;
80 int err;
81 enum py_ssl_error p;
83 assert(ret <= 0);
85 err = SSL_get_error(obj->ssl, ret);
87 switch (err) {
88 case SSL_ERROR_ZERO_RETURN:
89 errstr = "TLS/SSL connection has been closed";
90 p = PY_SSL_ERROR_ZERO_RETURN;
91 break;
92 case SSL_ERROR_WANT_READ:
93 errstr = "The operation did not complete (read)";
94 p = PY_SSL_ERROR_WANT_READ;
95 break;
96 case SSL_ERROR_WANT_WRITE:
97 p = PY_SSL_ERROR_WANT_WRITE;
98 errstr = "The operation did not complete (write)";
99 break;
100 case SSL_ERROR_WANT_X509_LOOKUP:
101 p = PY_SSL_ERROR_WANT_X509_LOOKUP;
102 errstr = "The operation did not complete (X509 lookup)";
103 break;
104 case SSL_ERROR_WANT_CONNECT:
105 p = PY_SSL_ERROR_WANT_CONNECT;
106 errstr = "The operation did not complete (connect)";
107 break;
108 case SSL_ERROR_SYSCALL:
110 unsigned long e = ERR_get_error();
111 if (e == 0) {
112 if (ret == 0) {
113 p = PY_SSL_ERROR_EOF;
114 errstr = "EOF occurred in violation of protocol";
115 } else if (ret == -1) {
116 /* the underlying BIO reported an I/O error */
117 return obj->Socket->errorhandler();
118 } else { /* possible? */
119 p = PY_SSL_ERROR_SYSCALL;
120 errstr = "Some I/O error occurred";
122 } else {
123 p = PY_SSL_ERROR_SYSCALL;
124 /* XXX Protected by global interpreter lock */
125 errstr = ERR_error_string(e, NULL);
127 break;
129 case SSL_ERROR_SSL:
131 unsigned long e = ERR_get_error();
132 p = PY_SSL_ERROR_SSL;
133 if (e != 0)
134 /* XXX Protected by global interpreter lock */
135 errstr = ERR_error_string(e, NULL);
136 else { /* possible? */
137 errstr = "A failure in the SSL library occurred";
139 break;
141 default:
142 p = PY_SSL_ERROR_INVALID_ERROR_CODE;
143 errstr = "Invalid error code";
145 n = PyInt_FromLong((long) p);
146 if (n == NULL)
147 return NULL;
148 v = PyTuple_New(2);
149 if (v == NULL) {
150 Py_DECREF(n);
151 return NULL;
154 s = PyString_FromString(errstr);
155 if (s == NULL) {
156 Py_DECREF(v);
157 Py_DECREF(n);
159 PyTuple_SET_ITEM(v, 0, n);
160 PyTuple_SET_ITEM(v, 1, s);
161 PyErr_SetObject(PySSLErrorObject, v);
162 return NULL;
165 static PySSLObject *
166 newPySSLObject(PySocketSockObject *Sock, char *key_file, char *cert_file)
168 PySSLObject *self;
169 char *errstr = NULL;
170 int ret;
172 self = PyObject_New(PySSLObject, &PySSL_Type); /* Create new object */
173 if (self == NULL){
174 errstr = "newPySSLObject error";
175 goto fail;
177 memset(self->server, '\0', sizeof(char) * X509_NAME_MAXLEN);
178 memset(self->issuer, '\0', sizeof(char) * X509_NAME_MAXLEN);
179 self->server_cert = NULL;
180 self->ssl = NULL;
181 self->ctx = NULL;
182 self->Socket = NULL;
184 if ((key_file && !cert_file) || (!key_file && cert_file)) {
185 errstr = "Both the key & certificate files must be specified";
186 goto fail;
189 Py_BEGIN_ALLOW_THREADS
190 self->ctx = SSL_CTX_new(SSLv23_method()); /* Set up context */
191 Py_END_ALLOW_THREADS
192 if (self->ctx == NULL) {
193 errstr = "SSL_CTX_new error";
194 goto fail;
197 if (key_file) {
198 Py_BEGIN_ALLOW_THREADS
199 ret = SSL_CTX_use_PrivateKey_file(self->ctx, key_file,
200 SSL_FILETYPE_PEM);
201 Py_END_ALLOW_THREADS
202 if (ret < 1) {
203 errstr = "SSL_CTX_use_PrivateKey_file error";
204 goto fail;
207 Py_BEGIN_ALLOW_THREADS
208 ret = SSL_CTX_use_certificate_chain_file(self->ctx,
209 cert_file);
210 Py_END_ALLOW_THREADS
211 if (ret < 1) {
212 errstr = "SSL_CTX_use_certificate_chain_file error";
213 goto fail;
217 Py_BEGIN_ALLOW_THREADS
218 SSL_CTX_set_verify(self->ctx,
219 SSL_VERIFY_NONE, NULL); /* set verify lvl */
220 self->ssl = SSL_new(self->ctx); /* New ssl struct */
221 Py_END_ALLOW_THREADS
222 SSL_set_fd(self->ssl, Sock->sock_fd); /* Set the socket for SSL */
223 Py_BEGIN_ALLOW_THREADS
224 SSL_set_connect_state(self->ssl);
227 /* Actually negotiate SSL connection */
228 /* XXX If SSL_connect() returns 0, it's also a failure. */
229 ret = SSL_connect(self->ssl);
230 Py_END_ALLOW_THREADS
231 if (ret <= 0) {
232 PySSL_SetError(self, ret);
233 goto fail;
235 self->ssl->debug = 1;
237 Py_BEGIN_ALLOW_THREADS
238 if ((self->server_cert = SSL_get_peer_certificate(self->ssl))) {
239 X509_NAME_oneline(X509_get_subject_name(self->server_cert),
240 self->server, X509_NAME_MAXLEN);
241 X509_NAME_oneline(X509_get_issuer_name(self->server_cert),
242 self->issuer, X509_NAME_MAXLEN);
244 Py_END_ALLOW_THREADS
245 self->Socket = Sock;
246 Py_INCREF(self->Socket);
247 return self;
248 fail:
249 if (errstr)
250 PyErr_SetString(PySSLErrorObject, errstr);
251 Py_DECREF(self);
252 return NULL;
255 static PyObject *
256 PySocket_ssl(PyObject *self, PyObject *args)
258 PySSLObject *rv;
259 PySocketSockObject *Sock;
260 char *key_file = NULL;
261 char *cert_file = NULL;
263 if (!PyArg_ParseTuple(args, "O!|zz:ssl",
264 PySocketModule.Sock_Type,
265 (PyObject*)&Sock,
266 &key_file, &cert_file))
267 return NULL;
269 rv = newPySSLObject(Sock, key_file, cert_file);
270 if (rv == NULL)
271 return NULL;
272 return (PyObject *)rv;
275 PyDoc_STRVAR(ssl_doc,
276 "ssl(socket, [keyfile, certfile]) -> sslobject");
278 /* SSL object methods */
280 static PyObject *
281 PySSL_server(PySSLObject *self)
283 return PyString_FromString(self->server);
286 static PyObject *
287 PySSL_issuer(PySSLObject *self)
289 return PyString_FromString(self->issuer);
293 static void PySSL_dealloc(PySSLObject *self)
295 if (self->server_cert) /* Possible not to have one? */
296 X509_free (self->server_cert);
297 if (self->ssl)
298 SSL_free(self->ssl);
299 if (self->ctx)
300 SSL_CTX_free(self->ctx);
301 Py_XDECREF(self->Socket);
302 PyObject_Del(self);
305 static PyObject *PySSL_SSLwrite(PySSLObject *self, PyObject *args)
307 char *data;
308 int len;
310 if (!PyArg_ParseTuple(args, "s#:write", &data, &len))
311 return NULL;
313 Py_BEGIN_ALLOW_THREADS
314 len = SSL_write(self->ssl, data, len);
315 Py_END_ALLOW_THREADS
316 if (len > 0)
317 return PyInt_FromLong(len);
318 else
319 return PySSL_SetError(self, len);
322 PyDoc_STRVAR(PySSL_SSLwrite_doc,
323 "write(s) -> len\n\
325 Writes the string s into the SSL object. Returns the number\n\
326 of bytes written.");
328 static PyObject *PySSL_SSLread(PySSLObject *self, PyObject *args)
330 PyObject *buf;
331 int count = 0;
332 int len = 1024;
334 if (!PyArg_ParseTuple(args, "|i:read", &len))
335 return NULL;
337 if (!(buf = PyString_FromStringAndSize((char *) 0, len)))
338 return NULL;
340 Py_BEGIN_ALLOW_THREADS
341 count = SSL_read(self->ssl, PyString_AsString(buf), len);
342 Py_END_ALLOW_THREADS
343 if (count <= 0) {
344 Py_DECREF(buf);
345 return PySSL_SetError(self, count);
347 if (count != len)
348 _PyString_Resize(&buf, count);
349 return buf;
352 PyDoc_STRVAR(PySSL_SSLread_doc,
353 "read([len]) -> string\n\
355 Read up to len bytes from the SSL socket.");
357 static PyMethodDef PySSLMethods[] = {
358 {"write", (PyCFunction)PySSL_SSLwrite, METH_VARARGS,
359 PySSL_SSLwrite_doc},
360 {"read", (PyCFunction)PySSL_SSLread, METH_VARARGS,
361 PySSL_SSLread_doc},
362 {"server", (PyCFunction)PySSL_server, METH_NOARGS},
363 {"issuer", (PyCFunction)PySSL_issuer, METH_NOARGS},
364 {NULL, NULL}
367 static PyObject *PySSL_getattr(PySSLObject *self, char *name)
369 return Py_FindMethod(PySSLMethods, (PyObject *)self, name);
372 static PyTypeObject PySSL_Type = {
373 PyObject_HEAD_INIT(NULL)
374 0, /*ob_size*/
375 "socket.SSL", /*tp_name*/
376 sizeof(PySSLObject), /*tp_basicsize*/
377 0, /*tp_itemsize*/
378 /* methods */
379 (destructor)PySSL_dealloc, /*tp_dealloc*/
380 0, /*tp_print*/
381 (getattrfunc)PySSL_getattr, /*tp_getattr*/
382 0, /*tp_setattr*/
383 0, /*tp_compare*/
384 0, /*tp_repr*/
385 0, /*tp_as_number*/
386 0, /*tp_as_sequence*/
387 0, /*tp_as_mapping*/
388 0, /*tp_hash*/
391 #ifdef HAVE_OPENSSL_RAND
393 /* helper routines for seeding the SSL PRNG */
394 static PyObject *
395 PySSL_RAND_add(PyObject *self, PyObject *args)
397 char *buf;
398 int len;
399 double entropy;
401 if (!PyArg_ParseTuple(args, "s#d:RAND_add", &buf, &len, &entropy))
402 return NULL;
403 RAND_add(buf, len, entropy);
404 Py_INCREF(Py_None);
405 return Py_None;
408 PyDoc_STRVAR(PySSL_RAND_add_doc,
409 "RAND_add(string, entropy)\n\
411 Mix string into the OpenSSL PRNG state. entropy (a float) is a lower\n\
412 bound on the entropy contained in string.");
414 static PyObject *
415 PySSL_RAND_status(PyObject *self)
417 return PyInt_FromLong(RAND_status());
420 PyDoc_STRVAR(PySSL_RAND_status_doc,
421 "RAND_status() -> 0 or 1\n\
423 Returns 1 if the OpenSSL PRNG has been seeded with enough data and 0 if not.\n\
424 It is necessary to seed the PRNG with RAND_add() on some platforms before\n\
425 using the ssl() function.");
427 static PyObject *
428 PySSL_RAND_egd(PyObject *self, PyObject *arg)
430 int bytes;
432 if (!PyString_Check(arg))
433 return PyErr_Format(PyExc_TypeError,
434 "RAND_egd() expected string, found %s",
435 arg->ob_type->tp_name);
436 bytes = RAND_egd(PyString_AS_STRING(arg));
437 if (bytes == -1) {
438 PyErr_SetString(PySSLErrorObject,
439 "EGD connection failed or EGD did not return "
440 "enough data to seed the PRNG");
441 return NULL;
443 return PyInt_FromLong(bytes);
446 PyDoc_STRVAR(PySSL_RAND_egd_doc,
447 "RAND_egd(path) -> bytes\n\
449 Queries the entropy gather daemon (EGD) on socket path. Returns number\n\
450 of bytes read. Raises socket.sslerror if connection to EGD fails or\n\
451 if it does provide enough data to seed PRNG.");
453 #endif
455 /* List of functions exported by this module. */
457 static PyMethodDef PySSL_methods[] = {
458 {"ssl", PySocket_ssl,
459 METH_VARARGS, ssl_doc},
460 #ifdef HAVE_OPENSSL_RAND
461 {"RAND_add", PySSL_RAND_add, METH_VARARGS,
462 PySSL_RAND_add_doc},
463 {"RAND_egd", PySSL_RAND_egd, METH_O,
464 PySSL_RAND_egd_doc},
465 {"RAND_status", (PyCFunction)PySSL_RAND_status, METH_NOARGS,
466 PySSL_RAND_status_doc},
467 #endif
468 {NULL, NULL} /* Sentinel */
472 PyDoc_STRVAR(module_doc,
473 "Implementation module for SSL socket operations. See the socket module\n\
474 for documentation.");
476 PyMODINIT_FUNC
477 init_ssl(void)
479 PyObject *m, *d;
481 PySSL_Type.ob_type = &PyType_Type;
483 m = Py_InitModule3("_ssl", PySSL_methods, module_doc);
484 d = PyModule_GetDict(m);
486 /* Load _socket module and its C API */
487 if (PySocketModule_ImportModuleAndAPI())
488 return;
490 /* Init OpenSSL */
491 SSL_load_error_strings();
492 SSLeay_add_ssl_algorithms();
494 /* Add symbols to module dict */
495 PySSLErrorObject = PyErr_NewException("socket.sslerror", NULL, NULL);
496 if (PySSLErrorObject == NULL)
497 return;
498 PyDict_SetItemString(d, "sslerror", PySSLErrorObject);
499 if (PyDict_SetItemString(d, "SSLType",
500 (PyObject *)&PySSL_Type) != 0)
501 return;
502 PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
503 PY_SSL_ERROR_ZERO_RETURN);
504 PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
505 PY_SSL_ERROR_WANT_READ);
506 PyModule_AddIntConstant(m, "SSL_ERROR_WANT_WRITE",
507 PY_SSL_ERROR_WANT_WRITE);
508 PyModule_AddIntConstant(m, "SSL_ERROR_WANT_X509_LOOKUP",
509 PY_SSL_ERROR_WANT_X509_LOOKUP);
510 PyModule_AddIntConstant(m, "SSL_ERROR_SYSCALL",
511 PY_SSL_ERROR_SYSCALL);
512 PyModule_AddIntConstant(m, "SSL_ERROR_SSL",
513 PY_SSL_ERROR_SSL);
514 PyModule_AddIntConstant(m, "SSL_ERROR_WANT_CONNECT",
515 PY_SSL_ERROR_WANT_CONNECT);
516 /* non ssl.h errorcodes */
517 PyModule_AddIntConstant(m, "SSL_ERROR_EOF",
518 PY_SSL_ERROR_EOF);
519 PyModule_AddIntConstant(m, "SSL_ERROR_INVALID_ERROR_CODE",
520 PY_SSL_ERROR_INVALID_ERROR_CODE);