blob: 93d597b46249b135510d5e5a75b309f24e9bfcc7 [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001/*
2 * ssl.c
3 *
4 * Copyright (C) AB Strakt 2001, All rights reserved
5 *
6 * Main file of the SSL sub module.
7 * See the file RATIONALE for a short explanation of why this module was written.
8 *
9 * Reviewed 2001-07-23
10 */
11#include <Python.h>
Jean-Paul Calderone12ea9a02008-02-22 12:24:39 -050012
13
14
15#ifndef MS_WINDOWS
16# include <sys/socket.h>
17# include <netinet/in.h>
18# if !(defined(__BEOS__) || defined(__CYGWIN__))
19# include <netinet/tcp.h>
20# endif
21#else
22# include <winsock.h>
23# include <wincrypt.h>
24#endif
25
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050026#define SSL_MODULE
27#include "ssl.h"
28
29static char ssl_doc[] = "\n\
30Main file of the SSL sub module.\n\
31See the file RATIONALE for a short explanation of hy this module was written.\n\
32";
33
34static char *CVSid = "@(#) $Id: ssl.c,v 1.12 2004/08/10 21:42:51 martin Exp $";
35
36void **crypto_API;
37
38/* Exceptions defined by the SSL submodule */
39PyObject *ssl_Error, /* Base class */
40 *ssl_ZeroReturnError, /* Used with SSL_get_error */
41 *ssl_WantReadError, /* ... */
42 *ssl_WantWriteError, /* ... */
43 *ssl_WantX509LookupError, /* ... */
44 *ssl_SysCallError; /* Uses (errno,errstr) */
45
46static char ssl_Context_doc[] = "\n\
47The factory function inserted in the module dictionary to create Context\n\
48objects\n\
49\n\
50Arguments: spam - Always NULL\n\
51 args - The Python argument tuple, should be:\n\
52 method - The SSL method to use\n\
53Returns: The Context object\n\
54";
55
56static PyObject *
57ssl_Context(PyObject *spam, PyObject *args)
58{
59 int method;
60
61 if (!PyArg_ParseTuple(args, "i:Context", &method))
62 return NULL;
63
64 return (PyObject *)ssl_Context_New(method);
65}
66
67static char ssl_Connection_doc[] = "\n\
68The factory function inserted in the module dictionary to create Connection\n\
69objects\n\
70\n\
71Arguments: spam - Always NULL\n\
72 args - The Python argument tuple, should be:\n\
73 ctx - An SSL Context to use for this connection\n\
74 sock - The socket to use for transport layer\n\
75Returns: The Connection object\n\
76";
77
78static PyObject *
79ssl_Connection(PyObject *spam, PyObject *args)
80{
81 ssl_ContextObj *ctx;
82 PyObject *sock;
83
84 if (!PyArg_ParseTuple(args, "O!O:Connection", &ssl_Context_Type, &ctx, &sock))
85 return NULL;
86
87 return (PyObject *)ssl_Connection_New(ctx, sock);
88}
89
90
91/* Methods in the OpenSSL.SSL module */
92static PyMethodDef ssl_methods[] = {
93 { "Context", ssl_Context, METH_VARARGS, ssl_Context_doc },
94 { "Connection", ssl_Connection, METH_VARARGS, ssl_Connection_doc },
95 { NULL, NULL }
96};
97
98/*
99 * Initialize SSL sub module
100 *
101 * Arguments: None
102 * Returns: None
103 */
104void
105initSSL(void)
106{
107 static void *ssl_API[ssl_API_pointers];
108 PyObject *ssl_api_object;
109 PyObject *module, *dict;
110
111 SSL_library_init();
112 ERR_load_SSL_strings();
113
114 import_crypto();
115
116 if ((module = Py_InitModule3("SSL", ssl_methods, ssl_doc)) == NULL)
117 return;
118
119 /* Initialize the C API pointer array */
120 ssl_API[ssl_Context_New_NUM] = (void *)ssl_Context_New;
121 ssl_API[ssl_Connection_New_NUM] = (void *)ssl_Connection_New;
122 ssl_api_object = PyCObject_FromVoidPtr((void *)ssl_API, NULL);
123 if (ssl_api_object != NULL)
124 PyModule_AddObject(module, "_C_API", ssl_api_object);
125
126 /* Exceptions */
127/*
128 * ADD_EXCEPTION(dict,name,base) expands to a correct Exception declaration,
129 * inserting OpenSSL.SSL.name into dict, derviving the exception from base.
130 */
131#define ADD_EXCEPTION(_name, _base) \
132do { \
133 ssl_##_name = PyErr_NewException("OpenSSL.SSL."#_name, _base, NULL);\
134 if (ssl_##_name == NULL) \
135 goto error; \
136 if (PyModule_AddObject(module, #_name, ssl_##_name) != 0) \
137 goto error; \
138} while (0)
139
140 ssl_Error = PyErr_NewException("OpenSSL.SSL.Error", NULL, NULL);
141 if (ssl_Error == NULL)
142 goto error;
143 if (PyModule_AddObject(module, "Error", ssl_Error) != 0)
144 goto error;
145
146 ADD_EXCEPTION(ZeroReturnError, ssl_Error);
147 ADD_EXCEPTION(WantReadError, ssl_Error);
148 ADD_EXCEPTION(WantWriteError, ssl_Error);
149 ADD_EXCEPTION(WantX509LookupError, ssl_Error);
150 ADD_EXCEPTION(SysCallError, ssl_Error);
151#undef ADD_EXCEPTION
152
153 /* Method constants */
154 PyModule_AddIntConstant(module, "SSLv2_METHOD", ssl_SSLv2_METHOD);
155 PyModule_AddIntConstant(module, "SSLv3_METHOD", ssl_SSLv3_METHOD);
156 PyModule_AddIntConstant(module, "SSLv23_METHOD", ssl_SSLv23_METHOD);
157 PyModule_AddIntConstant(module, "TLSv1_METHOD", ssl_TLSv1_METHOD);
158
159 /* Verify constants */
160 PyModule_AddIntConstant(module, "VERIFY_NONE", SSL_VERIFY_NONE);
161 PyModule_AddIntConstant(module, "VERIFY_PEER", SSL_VERIFY_PEER);
162 PyModule_AddIntConstant(module, "VERIFY_FAIL_IF_NO_PEER_CERT",
163 SSL_VERIFY_FAIL_IF_NO_PEER_CERT);
164 PyModule_AddIntConstant(module, "VERIFY_CLIENT_ONCE",
165 SSL_VERIFY_CLIENT_ONCE);
166
167 /* File type constants */
168 PyModule_AddIntConstant(module, "FILETYPE_PEM", SSL_FILETYPE_PEM);
169 PyModule_AddIntConstant(module, "FILETYPE_ASN1", SSL_FILETYPE_ASN1);
170
171 /* SSL option constants */
172 PyModule_AddIntConstant(module, "OP_SINGLE_DH_USE", SSL_OP_SINGLE_DH_USE);
173 PyModule_AddIntConstant(module, "OP_EPHEMERAL_RSA", SSL_OP_EPHEMERAL_RSA);
174 PyModule_AddIntConstant(module, "OP_NO_SSLv2", SSL_OP_NO_SSLv2);
175 PyModule_AddIntConstant(module, "OP_NO_SSLv3", SSL_OP_NO_SSLv3);
176 PyModule_AddIntConstant(module, "OP_NO_TLSv1", SSL_OP_NO_TLSv1);
177
178 /* More SSL option constants */
179 PyModule_AddIntConstant(module, "OP_MICROSOFT_SESS_ID_BUG", SSL_OP_MICROSOFT_SESS_ID_BUG);
180 PyModule_AddIntConstant(module, "OP_NETSCAPE_CHALLENGE_BUG", SSL_OP_NETSCAPE_CHALLENGE_BUG);
181 PyModule_AddIntConstant(module, "OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG);
182 PyModule_AddIntConstant(module, "OP_SSLREF2_REUSE_CERT_TYPE_BUG", SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG);
183 PyModule_AddIntConstant(module, "OP_MICROSOFT_BIG_SSLV3_BUFFER", SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
184 PyModule_AddIntConstant(module, "OP_MSIE_SSLV2_RSA_PADDING", SSL_OP_MSIE_SSLV2_RSA_PADDING);
185 PyModule_AddIntConstant(module, "OP_SSLEAY_080_CLIENT_DH_BUG", SSL_OP_SSLEAY_080_CLIENT_DH_BUG);
186 PyModule_AddIntConstant(module, "OP_TLS_D5_BUG", SSL_OP_TLS_D5_BUG);
187 PyModule_AddIntConstant(module, "OP_TLS_BLOCK_PADDING_BUG", SSL_OP_TLS_BLOCK_PADDING_BUG);
188 PyModule_AddIntConstant(module, "OP_DONT_INSERT_EMPTY_FRAGMENTS", SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
189 PyModule_AddIntConstant(module, "OP_ALL", SSL_OP_ALL);
190 PyModule_AddIntConstant(module, "OP_CIPHER_SERVER_PREFERENCE", SSL_OP_CIPHER_SERVER_PREFERENCE);
191 PyModule_AddIntConstant(module, "OP_TLS_ROLLBACK_BUG", SSL_OP_TLS_ROLLBACK_BUG);
192 PyModule_AddIntConstant(module, "OP_PKCS1_CHECK_1", SSL_OP_PKCS1_CHECK_1);
193 PyModule_AddIntConstant(module, "OP_PKCS1_CHECK_2", SSL_OP_PKCS1_CHECK_2);
194 PyModule_AddIntConstant(module, "OP_NETSCAPE_CA_DN_BUG", SSL_OP_NETSCAPE_CA_DN_BUG);
195 PyModule_AddIntConstant(module, "OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG", SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG);
196
Jean-Paul Calderone72b8f0f2008-02-21 23:57:40 -0500197 /* For SSL_set_shutdown */
198 PyModule_AddIntConstant(module, "SENT_SHUTDOWN", SSL_SENT_SHUTDOWN);
199 PyModule_AddIntConstant(module, "RECEIVED_SHUTDOWN", SSL_RECEIVED_SHUTDOWN);
200
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500201 dict = PyModule_GetDict(module);
202 if (!init_ssl_context(dict))
203 goto error;
204 if (!init_ssl_connection(dict))
205 goto error;
206
207error:
208 ;
209}