├── .boring ├── ChangeLog ├── INSTALL ├── LICENSE ├── MANIFEST.in ├── README ├── TODO ├── debian ├── changelog ├── compat ├── control ├── copyright ├── docs ├── examples ├── rules └── source │ └── format ├── examples ├── README ├── certs │ ├── ca.pem │ ├── crl.pem │ ├── expired.crt │ ├── expired.key │ ├── revoked.crt │ ├── revoked.key │ ├── valid.crt │ └── valid.key ├── client.py ├── crypto.py ├── server.py ├── twisted-client.py └── twisted-server.py ├── gnutls ├── __info__.py ├── __init__.py ├── connection.py ├── constants.py ├── crypto.py ├── errors.py ├── interfaces │ ├── __init__.py │ └── twisted │ │ └── __init__.py ├── library │ ├── __init__.py │ ├── constants.py │ ├── errors.py │ ├── functions.py │ └── types.py └── validators.py ├── setup.py └── test ├── Makefile ├── gnutls-client.c ├── gnutls-server ├── openssl-server ├── tc-gnutls.py ├── tc-openssl.py ├── ts-gnutls.py └── ts-openssl.py /.boring: -------------------------------------------------------------------------------- 1 | # Boring file regexps: 2 | (^|/)_darcs($|/) 3 | (^|/)CVS($|/) 4 | (^|/)\.svn($|/) 5 | (^|/)\.DS_Store$ 6 | (^|/)Thumbs\.db$ 7 | \# 8 | ~$ 9 | (^|/)core(\.[0-9]+)?$ 10 | \.(pyc|pyo|o|so|orig|bak|BAK|prof|wpu|cvsignore)$ 11 | (^|/)build($|/) 12 | (^|/)dist($|/) 13 | (^|/)\.idea($|/) 14 | ^MANIFEST$ 15 | ^gnutls.xml$ 16 | ^test/gnutls-client$ 17 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | Changes in version 3.1.3 2 | ------------------------ 3 | 4 | * Removed unnecessary code 5 | * Fixed blocking client example 6 | * Updated TLS certificates 7 | * Fixed X509Credentials for client examples 8 | * Simplified and made MANIFEST.in more explicit 9 | * Explicitly use python2 in shebang lines 10 | * Preserve quoted arguments when passing them along in shell scripts 11 | * Updated copyright years 12 | * Updated license 13 | 14 | Changes in version 3.1.2 15 | ------------------------ 16 | 17 | * Fixed truncated data for DER exported certificates/keys 18 | * Removed obsolete pycompat/pyversions files 19 | 20 | Changes in version 3.1.0 21 | ------------------------ 22 | 23 | * Add ability to set the client certificate request option for servers 24 | 25 | Changes in version 3.0.0 26 | ------------------------ 27 | 28 | * Fixed check for OpenPGP support 29 | * Don't force the reactor type in test scripts 30 | * Support GnuTLS 3.4 31 | * Refactor passing parameters to Session objects 32 | * Added __info__ module with package details 33 | * Minor improvements to the Debian packaging 34 | * Updated installation instructions 35 | * Fix tests with latest python-application 36 | 37 | Changes in version 2.0.1 38 | ------------------------ 39 | 40 | * Initialize default cipher priorities on Session 41 | 42 | Changes in version 2.0.0 43 | ------------------------ 44 | 45 | * Swtich to GnuTLS 3 (>= 3.1.4) 46 | * Added gnutls_certificate_verify_peers3 47 | * Add dependency on libgnutls 48 | * Remove no longer needed workaround for ctypes 49 | * Avoid sending empty data to peer 50 | * Add count command line option to tc-openssl 51 | * Bumped Debian Standards-Version 52 | * Only build Debian package for Python >= 2.7 53 | 54 | Changes in version 1.2.5 55 | ------------------------ 56 | 57 | * Fixed initializing libgcrypt 58 | * Enhanced logging in example scripts 59 | 60 | Changes in version 1.2.4 61 | ------------------------ 62 | 63 | * Fixed compatibility with twisted 11.1.0 for TLSServer as well 64 | 65 | Changes in version 1.2.3 66 | ------------------------ 67 | 68 | * Always use the gnutls library with the requested version 69 | * Fixed issue with dlopen ignoring changes to LD_LIBRARY_PATH after launch 70 | * Fixed the twisted interface to work with changes in twisted 11.1.0 71 | * Removed unused imports and variables 72 | * Allow specifying the server session class in TLSPort and reactor.listenTLS 73 | 74 | Changes in version 1.2.2 75 | ------------------------ 76 | 77 | * Fixed compatibility with libgnutls 2.11 78 | * Bumped debian standards version to 3.9.2 79 | * Reworked debian packaging 80 | 81 | Changes in version 1.2.1 82 | ------------------------ 83 | 84 | * Removed no longer needed dependencies from Build-Depends 85 | * Add the current directory to the Windows search path 86 | * Refactored error handling code to improve robustness 87 | * Allow extension to be build with mingw on windows 88 | * Use the system path separator when building the list of packages 89 | * Only load SRP functions from libgnutls if available 90 | * Fixed compatibility with Twisted 11.0 91 | * Included support for more protocols, ciphers and MAC algorithms 92 | * Added export methods on X509Certificate, X509PrivateKey and X509CRL 93 | * Bumped Debian standards version to 3.9.1 94 | * Added debian source format file 95 | 96 | Changes in version 1.2.0 97 | ------------------------ 98 | 99 | * Fixed threading issue with ctypes older than 1.0.3 100 | * Removed compile time dependency on gnutls and reorganized library code 101 | * Improved finding the gnutls library at runtime 102 | * Fixed the shutdown procedure in examples/server.py 103 | * Remove unneeded shutdown call from examples/client.py 104 | * Made examples/server.py threaded 105 | * Simplified windows build procedure 106 | * Added support for cygwin 107 | * Improved error handling 108 | * Added INSTALL file 109 | * Bumped debian standards version to 3.8.3 110 | 111 | Changes in version 1.1.9 112 | ------------------------ 113 | 114 | * Made loseConnection signature match the corresponding one from twisted 115 | * Bumped debian standards version to 3.8.2 116 | * Fixed lintian warning about missing misc:Depends dependency 117 | 118 | Changes in version 1.1.8 119 | ------------------------ 120 | 121 | * Workaround for changed tcp.Server.__init__ signature in twisted 8.2.0 122 | * Fixed DeprecationWarning when running with python2.6 or newer 123 | 124 | Changes in version 1.1.7 125 | ------------------------ 126 | 127 | * Updated debian build dependency to libgnutls-dev 2.4.1 or newer 128 | * Use the default python interpreter instead of /usr/bin/python in 129 | example, test and setup scripts 130 | * Improved detection of gnutls libraries by using libgnutls-config 131 | * Fixed gnutls library location for Mac OSX installations 132 | 133 | Changes in version 1.1.6 134 | ------------------------ 135 | 136 | * Require libgnutls version 2.4.1 or higher. 137 | 138 | Changes in version 1.1.5 139 | ------------------------ 140 | 141 | * Added server name extension support. 142 | * Fixed 64-bit issues with size_t and ssize_t. 143 | * Require libgnutls version 2.2.2 or higher. 144 | 145 | Changes in version 1.1.4 146 | ------------------------ 147 | 148 | * Better integration with twisted. The TLSClient and TLSServer 149 | classes now declare that they implement ISSLTransport. 150 | 151 | Changes in version 1.1.3 152 | ------------------------ 153 | 154 | * Better version headers for changelog entries. 155 | * Check if C module initialization failed. 156 | 157 | Changes in version 1.1.2 158 | ------------------------ 159 | 160 | * Added LICENSE file and updated copyright notices to reference it. 161 | * Only included the relevant examples in the source distribution. 162 | * Avoid multiple splits on name/value pairs in X509Name. 163 | 164 | Changes in version 1.1.1 165 | ------------------------ 166 | 167 | * Removed a circular reference manifesting on handshake failures. 168 | 169 | Changes in version 1.1.0 170 | ------------------------ 171 | 172 | * Send TLS bye if the client session peer certificate verification fails 173 | * Based CertificateError on GNUTLSError and added 4 new certificate related 174 | exceptions derived from it. 175 | * Added the ability to send TLS alerts based on certain error conditions 176 | Using this mechanism a python exception related to GNUTLS can be mapped 177 | to a TLS alert and sent to the peer which will map it back to the original 178 | python exception, making it possible to transfer error conditions and 179 | raise their corresponding exception on the other side that becomes this 180 | way aware of the errors that occured in the peer. Currently this is used 181 | to map certificate related exceptions into TLS alerts and back to python 182 | exceptions on the other side. 183 | * Send a TLS alert before closing a connection as a result of an error in 184 | the twisted interface. 185 | * Preserve closing reason while sending the close alerts. 186 | * Pass the proper exception when a client connection fails. 187 | * Improved some exception messages related to certificate errors. 188 | * Added the ability to specify the certificate name to use in exceptions 189 | raised by certificate checking methods, which helps improve the clarity 190 | of the error messages. 191 | * Set transport on protocol after the TCP connection is made, because we 192 | may call connectionLost without calling connectionMade if TLS negociation 193 | fails (which in turn will call connectionLost on the protocol). 194 | * Added _closeWriteConnection to handle half closed connections. 195 | 196 | Changes in version 1.0.2 197 | ------------------------ 198 | 199 | * Avoid the need to handle bye timeouts in the twisted interface by not 200 | waiting for the bye notification acknowledgement as we do not use the 201 | TCP connection anymore after closing the TLS session. 202 | 203 | Changes in version 1.0.1 204 | ------------------------ 205 | 206 | * Fixed typo in internal class name in the twisted interface 207 | 208 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | 2 | Installation procedure 3 | ---------------------- 4 | 5 | 1. Linux / UNIX 6 | 7 | Build dependencies: 8 | - gcc 9 | - python and python-dev (>= 2.7) 10 | 11 | Runtime dependencies: 12 | - libgnutls (>= 3.2.0) 13 | - libgnutls dependencies 14 | - python (>= 2.7) 15 | 16 | To build and install python-gnutls run: 17 | 18 | python setup.py install 19 | 20 | 21 | 2. Mac OS X 22 | 23 | Build dependencies: 24 | - Mac OS X Leopard (10.5) or Snow Leopard (10.6) 25 | - Apple Developer Tools (XCode) 26 | 27 | Runtime dependencies: 28 | - libgnutls (>= 3.2.0) 29 | - libgnutls dependencies 30 | - python (this is already preinstalled on every OS X) 31 | 32 | Note: libgnutls and its dependencies can be installed from Homebre, MacPorts, Fink or 33 | by compiling and installing them from source. 34 | 35 | To build and install python-gnutls run: 36 | 37 | python setup.py install 38 | 39 | 40 | 3. Windows 41 | 42 | This was only tested on Windows XP. Other Windows versions may work, but 43 | they were not tested. 44 | 45 | Build dependencies: 46 | - Visual Studio (the version must match the one used to build the python 47 | interpreter that will be used. For example the python-2.7 windows 48 | binaries from python.org were built with Visual Studio 9) 49 | - libpthreads (http://sourceware.org/pthreads-win32) 50 | - python and python-dev (>= 2.7) (select to include the development files 51 | when installing python) 52 | 53 | Runtime dependencies: 54 | - libgnutls (>= 3.2) 55 | - libgnutls dependencies 56 | - libpthreads 57 | - python (>= 2.7) 58 | 59 | Before building python-gnutls, copy the pthread header files (pthread.h, 60 | sched.h, semaphore.h) to C:\Developer\include\ and the pthread developer 61 | libraries (libpthread*.a and pthread*.lib) to C:\Developer\lib\ (create 62 | these directories first). 63 | 64 | To build and install python-gnutls run: 65 | 66 | python setup.py install 67 | 68 | In order to run an application based on python-gnutls, make sure that the 69 | DLLs mentioned in the runtime dependencies (pthread*.dll, libgnutls*.dll, 70 | etc) are somewhere in %PATH% 71 | 72 | 73 | 4. Cygwin 74 | 75 | Build dependencies: 76 | - cygwin (>= 1.7.1) 77 | - gcc 78 | - python and python-dev (>= 2.7) 79 | 80 | Runtime dependencies: 81 | - libgnutls (>= 3.2.0) 82 | - libgnutls dependencies 83 | - python (>= 2.7) 84 | 85 | To build and install python-gnutls run: 86 | 87 | python setup.py install 88 | 89 | 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2006-2020 Dan Pascu 2 | 3 | License: LGPL-2.1+ 4 | 5 | This program is free software; you can redistribute it and/or modify it 6 | under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | For a copy of the license see https://www.gnu.org/licenses/lgpl-2.1.html 16 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include ChangeLog 2 | include INSTALL 3 | include README 4 | include LICENSE 5 | include MANIFEST.in 6 | 7 | graft examples 8 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | Python wrapper for the GnuTLS library 3 | 4 | This package provides a high level object oriented wrapper around libgnutls, 5 | as well as low level bindings to the GnuTLS types and functions via ctypes. 6 | The high level wrapper hides the details of accessing the GnuTLS library via 7 | ctypes behind a set of classes that encapsulate GnuTLS sessions, certificates 8 | and credentials and expose them to python applications using a simple API. 9 | 10 | The package also includes a Twisted interface that has seamless intergration 11 | with Twisted, providing connectTLS and listenTLS methods on the Twisted 12 | reactor once imported (the methods are automatically attached to the reactor 13 | by simply importing the GnuTLS Twisted interface module). 14 | 15 | The high level wrapper is written using the GnuTLS library bindings that are 16 | made available via ctypes. This makes the wrapper very powerful and flexible 17 | as it has direct access to all the GnuTLS internals and is also very easy to 18 | extend without any need to write C code or recompile anything. 19 | 20 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AGProjects/python-gnutls/aad5b755ea943ebe6e1f782fd1d17b584c4977bf/TODO -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | python-gnutls (3.1.3) unstable; urgency=medium 2 | 3 | * Removed unnecessary code 4 | * Fixed blocking client example 5 | * Updated TLS certificates 6 | * Fixed X509Credentials for client examples 7 | * Simplified and made MANIFEST.in more explicit 8 | * Increased debian compatibility level to 11 and updated dependencies 9 | * Use the pybuild build system for the debian package 10 | * Make sure not to compress the examples in the debian package 11 | * Install README in the debian package docs directory 12 | * Explicitly use python2 in shebang lines 13 | * Preserve quoted arguments when passing them along in shell scripts 14 | * Increased debian standards version to 4.5.0 15 | * Updated copyright years 16 | * Updated license 17 | 18 | -- Dan Pascu Fri, 14 Feb 2020 14:39:31 +0200 19 | 20 | python-gnutls (3.1.2) unstable; urgency=medium 21 | 22 | * Fixed truncated data for DER exported certificates/keys 23 | * Removed obsolete pycompat/pyversions files 24 | 25 | -- Dan Pascu Wed, 03 Oct 2018 14:02:33 +0300 26 | 27 | python-gnutls (3.1.1) unstable; urgency=medium 28 | 29 | * Increased debian compatibility level to 9 30 | * Updated debian standards version 31 | * Updated debian uploaders 32 | 33 | -- Dan Pascu Wed, 01 Feb 2017 15:50:32 +0200 34 | 35 | python-gnutls (3.1.0) unstable; urgency=medium 36 | 37 | * Add ability to set the client certificate request option for servers 38 | * Don't depend on Python development libraries for building 39 | 40 | -- Saul Ibarra Wed, 12 Oct 2016 12:14:39 +0200 41 | 42 | python-gnutls (3.0.0) unstable; urgency=medium 43 | 44 | * Fixed check for OpenPGP support 45 | * Don't force the reactor type in test scripts 46 | * Support GnuTLS 3.4 47 | * Refactor passing parameters to Session objects 48 | * Added __info__ module with package details 49 | * Minor improvements to the Debian packaging 50 | * Updated installation instructions 51 | * Fix tests with latest python-application 52 | 53 | -- Saul Ibarra Tue, 08 Mar 2016 12:40:16 +0100 54 | 55 | python-gnutls (2.0.1) unstable; urgency=medium 56 | 57 | * Initialize default cipher priorities on Session 58 | 59 | -- Saul Ibarra Wed, 02 Jul 2014 13:02:49 +0200 60 | 61 | python-gnutls (2.0.0) unstable; urgency=medium 62 | 63 | * Swtich to GnuTLS 3 (>= 3.1.4) 64 | * Added gnutls_certificate_verify_peers3 65 | * Add dependency on libgnutls 66 | * Remove no longer needed workaround for ctypes 67 | * Avoid sending empty data to peer 68 | * Add count command line option to tc-openssl 69 | * Bumped Debian Standards-Version 70 | * Only build Debian package for Python >= 2.7 71 | 72 | -- Saul Ibarra Wed, 25 Jun 2014 15:54:26 +0200 73 | 74 | python-gnutls (1.2.5) unstable; urgency=medium 75 | 76 | * Fixed initializing libgcrypt 77 | * Enhanced logging in example scripts 78 | 79 | -- Saul Ibarra Thu, 12 Dec 2013 17:47:07 +0100 80 | 81 | python-gnutls (1.2.4) unstable; urgency=low 82 | 83 | * Fixed compatibility with twisted 11.1.0 for TLSServer as well 84 | 85 | -- Dan Pascu Mon, 30 Jan 2012 17:43:00 +0200 86 | 87 | python-gnutls (1.2.3) unstable; urgency=low 88 | 89 | * Always use the gnutls library with the requested version 90 | * Fixed issue with dlopen ignoring changes to LD_LIBRARY_PATH after launch 91 | * Fixed the twisted interface to work with changes in twisted 11.1.0 92 | * Removed unused imports and variables 93 | * Allow specifying the server session class in TLSPort and reactor.listenTLS 94 | 95 | -- Dan Pascu Tue, 10 Jan 2012 20:36:29 +0200 96 | 97 | python-gnutls (1.2.2) unstable; urgency=low 98 | 99 | * Fixed compatibility with libgnutls 2.11 100 | * Bumped debian standards version to 3.9.2 101 | * Reworked debian packaging 102 | 103 | -- Dan Pascu Fri, 19 Aug 2011 12:52:51 +0300 104 | 105 | python-gnutls (1.2.1) unstable; urgency=low 106 | 107 | * Removed no longer needed dependencies from Build-Depends 108 | * Add the current directory to the Windows search path 109 | * Refactored error handling code to improve robustness 110 | * Allow extension to be build with mingw on windows 111 | * Use the system path separator when building the list of packages 112 | * Only load SRP functions from libgnutls if available 113 | * Fixed compatibility with Twisted 11.0 114 | * Included support for more protocols, ciphers and MAC algorithms 115 | * Added export methods on X509Certificate, X509PrivateKey and X509CRL 116 | * Bumped Debian standards version to 3.9.1 117 | * Added debian source format file 118 | 119 | -- Dan Pascu Fri, 20 May 2011 16:24:38 +0300 120 | 121 | python-gnutls (1.2.0) unstable; urgency=low 122 | 123 | * Fixed threading issue with ctypes older than 1.0.3 124 | * Removed compile time dependency on gnutls and reorganized library code 125 | * Improved finding the gnutls library at runtime 126 | * Fixed the shutdown procedure in examples/server.py 127 | * Remove unneeded shutdown call from examples/client.py 128 | * Made examples/server.py threaded 129 | * Simplified windows build procedure 130 | * Added support for cygwin 131 | * Improved error handling 132 | * Added INSTALL file 133 | * Bumped debian standards version to 3.8.3 134 | 135 | -- Dan Pascu Mon, 01 Feb 2010 17:47:51 +0200 136 | 137 | python-gnutls (1.1.9) unstable; urgency=low 138 | 139 | * Made loseConnection signature match the corresponding one from twisted 140 | * Bumped debian standards version to 3.8.2 141 | * Fixed lintian warning about missing misc:Depends dependency 142 | 143 | -- Dan Pascu Wed, 15 Jul 2009 16:26:55 +0300 144 | 145 | python-gnutls (1.1.8) unstable; urgency=low 146 | 147 | * Workaround for changed tcp.Server.__init__ signature in twisted 8.2.0 148 | * Fixed DeprecationWarning when running with python2.6 or newer 149 | 150 | -- Dan Pascu Tue, 13 Jan 2009 14:59:43 +0200 151 | 152 | python-gnutls (1.1.7) unstable; urgency=low 153 | 154 | * Updated debian build dependency to libgnutls-dev 2.4.1 or newer 155 | * Use the default python interpreter instead of /usr/bin/python in 156 | example, test and setup scripts 157 | * Improved detection of gnutls libraries by using libgnutls-config 158 | * Fixed gnutls library location for Mac OSX installations 159 | 160 | -- Dan Pascu Fri, 09 Jan 2009 18:49:02 +0200 161 | 162 | python-gnutls (1.1.6) unstable; urgency=low 163 | 164 | * Require libgnutls version 2.4.1 or higher. 165 | * Updated standards version to 3.8.0 166 | 167 | -- Dan Pascu Tue, 22 Jul 2008 12:38:12 +0300 168 | 169 | python-gnutls (1.1.5) unstable; urgency=low 170 | 171 | * Added server name extension support. 172 | * Fixed 64-bit issues with size_t and ssize_t. 173 | * Require libgnutls version 2.2.2 or higher. 174 | 175 | -- Dan Pascu Tue, 29 Apr 2008 15:09:23 +0300 176 | 177 | python-gnutls (1.1.4) unstable; urgency=low 178 | 179 | * Better integration with twisted. The TLSClient and TLSServer 180 | classes now declare that they implement ISSLTransport. 181 | * Added python-ctypes as dependency. 182 | * Moved python-twisted-core to Recommends. 183 | * Rephrased debian package description. 184 | * Do not compress .py files in the examples from the debian package. 185 | * Switched to python-support. 186 | 187 | -- Dan Pascu Mon, 17 Sep 2007 16:49:00 +0300 188 | 189 | python-gnutls (1.1.3) unstable; urgency=low 190 | 191 | * Better version headers for changelog entries. 192 | * Check if C module initialization failed. 193 | 194 | -- Dan Pascu Fri, 24 Aug 2007 15:21:16 +0300 195 | 196 | python-gnutls (1.1.2) unstable; urgency=low 197 | 198 | * Added LICENSE and updated copyright notices to reference it. 199 | * Only included the relevant examples in the source distribution. 200 | * Avoid multiple splits on name/value pairs in X509Name. 201 | 202 | -- Dan Pascu Fri, 13 Jul 2007 14:21:12 +0300 203 | 204 | python-gnutls (1.1.1) unstable; urgency=low 205 | 206 | * Removed a circular reference manifesting on handshake failures. 207 | 208 | -- Dan Pascu Mon, 14 May 2007 15:57:06 +0300 209 | 210 | python-gnutls (1.1.0) unstable; urgency=low 211 | 212 | * Send TLS bye if the client session peer certificate verification fails 213 | * Based CertificateError on GNUTLSError and added 4 new certificate related 214 | exceptions derived from it. 215 | * Added the ability to send TLS alerts based on certain error conditions 216 | Using this mechanism a python exception related to GNUTLS can be mapped 217 | to a TLS alert and sent to the peer which will map it back to the original 218 | python exception, making it possible to transfer error conditions and 219 | raise their corresponding exception on the other side that becomes this 220 | way aware of the errors that occured in the peer. Currently this is used 221 | to map certificate related exceptions into TLS alerts and back to python 222 | exceptions on the other side. 223 | * Send a TLS alert before closing a connection as a result of an error in 224 | the twisted interface. 225 | * Preserve closing reason while sending the close alerts. 226 | * Pass the proper exception when a client connection fails. 227 | * Improved some exception messages related to certificate errors. 228 | * Added the ability to specify the certificate name to use in exceptions 229 | raised by certificate checking methods, which helps improve the clarity 230 | of the error messages. 231 | * Set transport on protocol after the TCP connection is made, because we 232 | may call connectionLost without calling connectionMade if TLS negociation 233 | fails (which in turn will call connectionLost on the protocol). 234 | * Added _closeWriteConnection to handle half closed connections. 235 | 236 | -- Dan Pascu Thu, 10 May 2007 20:20:11 +0300 237 | 238 | python-gnutls (1.0.2) unstable; urgency=low 239 | 240 | * Avoid the need to handle bye timeouts in the twisted interface by not 241 | waiting for the bye notification acknowledgement as we do not use the 242 | TCP connection anymore after closing the TLS session. 243 | 244 | -- Dan Pascu Wed, 11 Apr 2007 18:00:30 +0300 245 | 246 | python-gnutls (1.0.1) unstable; urgency=low 247 | 248 | * Fixed typo in internal class name in the twisted interface 249 | 250 | -- Dan Pascu Tue, 10 Apr 2007 12:06:07 +0300 251 | 252 | python-gnutls (1.0.0) unstable; urgency=medium 253 | 254 | * Initial release. 255 | 256 | -- Dan Pascu Thu, 29 Mar 2007 09:22:44 +0300 257 | 258 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 11 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: python-gnutls 2 | Section: python 3 | Priority: optional 4 | Maintainer: Dan Pascu 5 | Build-Depends: debhelper (>= 11), dh-python, python 6 | Standards-Version: 4.5.0 7 | 8 | Package: python-gnutls 9 | Architecture: all 10 | Depends: ${python:Depends}, ${misc:Depends}, libgnutls30 11 | Recommends: python-twisted-core 12 | Provides: ${python:Provides} 13 | Description: Python wrapper for the GnuTLS library 14 | This package provides a high level object oriented wrapper around 15 | libgnutls, as well as low level bindings to the GnuTLS types and 16 | functions via ctypes. The high level wrapper hides the details of 17 | accessing the GnuTLS library via ctypes behind a set of classes 18 | that encapsulate GnuTLS sessions, certificates and credentials and 19 | expose them to Python applications using a simple API. 20 | . 21 | The package also includes a Twisted interface that has seamless 22 | intergration with Twisted, providing connectTLS and listenTLS 23 | methods on the Twisted reactor once imported (the methods are 24 | automatically attached to the reactor by simply importing the 25 | GnuTLS Twisted interface module). 26 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Copyright 2006-2020 Dan Pascu 2 | 3 | License: LGPL-2.1+ 4 | 5 | This program is free software; you can redistribute it and/or modify it 6 | under the terms of the GNU Lesser General Public License as published 7 | by the Free Software Foundation; either version 2.1 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | For a copy of the license see /usr/share/common-licenses/LGPL-2.1 16 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | README 2 | -------------------------------------------------------------------------------- /debian/examples: -------------------------------------------------------------------------------- 1 | examples/* 2 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | %: 4 | dh $@ --with python2 --buildsystem=pybuild 5 | 6 | override_dh_clean: 7 | dh_clean 8 | rm -rf dist MANIFEST 9 | 10 | override_dh_compress: 11 | dh_compress -Xexamples 12 | 13 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /examples/README: -------------------------------------------------------------------------------- 1 | 2 | This directory holds some examples of using python-gnutls. 3 | 4 | - An example of writing a synchronous client and server using the 5 | ClientSession and ServerSession classes from python-gnutls is 6 | given in client.py and server.py 7 | 8 | - An example of writing an asynchronous client and server using the 9 | python-gnutls twisted interface is given in twisted-client.py and 10 | twisted-server.py 11 | 12 | - An example of working with X509 certificates and their attributes 13 | as well as using a CRL to check their revocation is in crypto.py 14 | 15 | 16 | 17 | To run the examples without installing python-gnutls, run the following 18 | command prior to trying the examples (after python-gnutls was built): 19 | 20 | export PYTHONPATH=/path/to/python-gnutls 21 | 22 | -------------------------------------------------------------------------------- /examples/certs/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIHiTCCBXGgAwIBAgIUDLCmTNeW2E3RkQqC7/ciSKRFwpIwDQYJKoZIhvcNAQEL 3 | BQAwgasxCzAJBgNVBAYTAk5MMRYwFAYDVQQIEw1Ob29yZC1Ib2xsYW5kMRAwDgYD 4 | VQQHEwdIYWFybGVtMRQwEgYDVQQKEwtBRyBQcm9qZWN0czEUMBIGA1UECxMLRGV2 5 | ZWxvcG1lbnQxIDAeBgNVBAMTF0FHIFByb2plY3RzIERldmVsb3BtZW50MSQwIgYJ 6 | KoZIhvcNAQkBFhVkZXZlbEBhZy1wcm9qZWN0cy5jb20wIBcNMTkwOTE5MDg0MTAx 7 | WhgPMjA2OTA5MDYwODQxMDFaMIGrMQswCQYDVQQGEwJOTDEWMBQGA1UECBMNTm9v 8 | cmQtSG9sbGFuZDEQMA4GA1UEBxMHSGFhcmxlbTEUMBIGA1UEChMLQUcgUHJvamVj 9 | dHMxFDASBgNVBAsTC0RldmVsb3BtZW50MSAwHgYDVQQDExdBRyBQcm9qZWN0cyBE 10 | ZXZlbG9wbWVudDEkMCIGCSqGSIb3DQEJARYVZGV2ZWxAYWctcHJvamVjdHMuY29t 11 | MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr09QLw0/c6ePwIN7MTXY 12 | +kC4QITeW6yaXMzjHVON+lZ8pBt1a7Yr/8v8NpaHTicopvsa6H93RQK2OQXL0yna 13 | HbyumPjhLTfqyuor9k4LYNQXSFDiZ92hEeFQT6mN1bZ86C9UzTvbr626GzGZ2Gwr 14 | r4V8PrBzfIDGGr8nGZSrwr2qK9H97YCGB/sZ04LruDqPWCIQ73PhKPHm23dXp/rd 15 | s5ZM8FdVy70fRJaLb2XfRE/WAMXtEgFWJQSPn7PLpJh5pL9QVerl3fiPPxjRktCa 16 | gI+Qq41261OL7gBkRsONn6oWFLsWYglU8HyLM9Tp29eUmRBQyDDGbn1phwB86qnP 17 | PSBz4umtAqXT0nIeWuEtLKL1E0LuPvQVQA6+7CQdDUOlRw0oWr2aFXahjIGMhtWX 18 | F4KWhACHeHor0naP7i8alugBtMl9WyBNtyquk5IYDLEPjq2ui39BhsvRvKYWWhF9 19 | XlWUWwOh5Jlm0jFpEh2jgQ86Ecn/q5XK1lOrYjDtD8AOPCkK2noJ6Z5hEtb3ZrHu 20 | G/ADmkQ1B6NDE95lP/lZEulEACAjY4Uwn2YqPeu+3o/BPCI1AH/2OgxdSG5zvGjP 21 | ynplHqaOao+9JQ0eJgvk2SCeGtt4iIuOr4hpq/vEcauzNVQM6IXJlwkFQ9L90gdS 22 | 0cI80bDZ66WEEhg00/tfWgcCAwEAAaOCAZ8wggGbMB0GA1UdDgQWBBTvX2Y4W58m 23 | u6UZTSTYf5ya+4pALTCB6wYDVR0jBIHjMIHggBTvX2Y4W58mu6UZTSTYf5ya+4pA 24 | LaGBsaSBrjCBqzELMAkGA1UEBhMCTkwxFjAUBgNVBAgTDU5vb3JkLUhvbGxhbmQx 25 | EDAOBgNVBAcTB0hhYXJsZW0xFDASBgNVBAoTC0FHIFByb2plY3RzMRQwEgYDVQQL 26 | EwtEZXZlbG9wbWVudDEgMB4GA1UEAxMXQUcgUHJvamVjdHMgRGV2ZWxvcG1lbnQx 27 | JDAiBgkqhkiG9w0BCQEWFWRldmVsQGFnLXByb2plY3RzLmNvbYIUDLCmTNeW2E3R 28 | kQqC7/ciSKRFwpIwDwYDVR0TAQH/BAUwAwEB/zARBglghkgBhvhCAQEEBAMCAQYw 29 | CQYDVR0SBAIwADArBglghkgBhvhCAQ0EHhYcVGlueUNBIEdlbmVyYXRlZCBDZXJ0 30 | aWZpY2F0ZTAgBgNVHREEGTAXgRVkZXZlbEBhZy1wcm9qZWN0cy5jb20wDgYDVR0P 31 | AQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQBje4X4MNsmV1qQzAeJqBf7146e 32 | G4SPROtq+M34qFp+BLmMVO30w91nIu1p1nF0dD11lFS7PRZ0eNUbGzP4FvV8dzLx 33 | ealhzWGsDlQ9Pk2JB0lgM7aETaLb8GIHSyzBzdv4yi7GexRaq9oNiqMpTWpW9l9B 34 | jxwcaM/ZP9KidZiUyXjAQJDSzTUAs/B6YxbEKMlLE5ZDsM9Ma6eWmCtoDBQ17WUa 35 | Nx60bYJGGPMDE4B+1C4X0QGOIQh2EQUB8rzr++h6WYbm758QKEUK3cv9P/QCob1Y 36 | x5WJR0cBCfVKQyNGr/VDygEMVTYJPsGr0P0e1Z1tj8rRpPUYrILxsFfe4zpzxozT 37 | qZuEvl/tYi/e2HJ7xbGZ1OzGId+7MfgEvOALyX3HxEOgarNZo0FkvpojHHvWlb7P 38 | zx2pBgQL4nSnKd9m0aFGAc3Zc3qXMOnwvR/h02G8DsOYa8Bm8KHaWLhvcS/XwJUC 39 | utF+i2urmaUWqe8sBAad1vOxFejWh97LM+50qQhDRypOur+TjMn4bXR6J5Z4HKXd 40 | GpMfSoCeUFLTv6EJEtCXFujp3pKUK9mHqBSJtn03y6gkuLraFwPedk24UqueBNSr 41 | 8dcJK3JhyZesZfVFrN+AQ/v1GiRKOLJMIe1zJAe02mbLYRIuiNEtapVedLavZvg8 42 | 0CbxFZJYo9w/MhPQYw== 43 | -----END CERTIFICATE----- 44 | -------------------------------------------------------------------------------- /examples/certs/crl.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN X509 CRL----- 2 | MIIDGjCCAQICAQEwDQYJKoZIhvcNAQELBQAwgasxCzAJBgNVBAYTAk5MMRYwFAYD 3 | VQQIEw1Ob29yZC1Ib2xsYW5kMRAwDgYDVQQHEwdIYWFybGVtMRQwEgYDVQQKEwtB 4 | RyBQcm9qZWN0czEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxIDAeBgNVBAMTF0FHIFBy 5 | b2plY3RzIERldmVsb3BtZW50MSQwIgYJKoZIhvcNAQkBFhVkZXZlbEBhZy1wcm9q 6 | ZWN0cy5jb20XDTE5MDkxOTA5MzczNFoXDTM5MDkxNDA5MzczNFowIjAgAgEDFw0x 7 | OTA5MTkwOTM3MTNaMAwwCgYDVR0VBAMKAQEwDQYJKoZIhvcNAQELBQADggIBAGd1 8 | r8BEdd3wFq5Oy2z0wqO+7jaO3z35QgBLkW7bvyrXWY1kULSRUV8/9jfn1MruxGp0 9 | heyA/noRatUJbC7AGlzoty03n22Tym6MLs05lJauf6+DBLBTpQEwjwkXCGEBTsfz 10 | 151Y1SdV3iYBIkHZOgVxetOS9zhRZd/vi29t3WXEltpsxm2jCfky/GJQKrVhNzOj 11 | Mk6Aln3iTI/Ux+2DuEc8VJUVxZZQ9/TcSxDXSrF4Mj5PgtvoW9Iv5AucvAcUrJ0k 12 | VNNtYdMOwKda7NyC4PpWPXWYje2tiW8Nw5Kz5tpXAqRmjnAYO7Mc0qIt3r0EcGTg 13 | zHrhXFCc4TJZtStA2ynjjcU/0oiPXqigs1InvwwlivFGd5lMg1Cjq1uSYoXDj2L5 14 | jy/NIAKtPphT7anA+3Day5vDTgzd8iJhBOkWcoM/CQvExBbZRWJV8vrzenKxrmFM 15 | O5H9SueKnHmS3wgxG0u5Ct5GgfuOs70v6CUhJydyrTm7HhtCdlMnxi6ySWO2/zcB 16 | HLHP/DK247xgZAiiei6QHFRQekmHYNFGJHox/r/C/VCX2VOyabDEEIQb6dH4Z6Mu 17 | yGGaYWSMnnsywlfa61dBWpkK/O4mxy5590rcdmvXH1Ih5cH4wABAqbTE+jetLR9Z 18 | zrn7faAF8rdsbyX6w1U+NjcXpTSyXjlNtu9s7ztN 19 | -----END X509 CRL----- 20 | -------------------------------------------------------------------------------- /examples/certs/expired.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | 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 42 | -----END CERTIFICATE----- 43 | -------------------------------------------------------------------------------- /examples/certs/expired.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | 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 51 | -----END RSA PRIVATE KEY----- 52 | -------------------------------------------------------------------------------- /examples/certs/revoked.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | 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 42 | -----END CERTIFICATE----- 43 | -------------------------------------------------------------------------------- /examples/certs/revoked.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | 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 51 | -----END RSA PRIVATE KEY----- 52 | -------------------------------------------------------------------------------- /examples/certs/valid.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | 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 42 | -----END CERTIFICATE----- 43 | -------------------------------------------------------------------------------- /examples/certs/valid.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | 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 51 | -----END RSA PRIVATE KEY----- 52 | -------------------------------------------------------------------------------- /examples/client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | """Synchronous client using python-gnutls""" 4 | 5 | import sys 6 | import os 7 | import socket 8 | 9 | from gnutls.crypto import * 10 | from gnutls.connection import * 11 | from gnutls.errors import GNUTLSError 12 | 13 | script_path = os.path.realpath(os.path.dirname(sys.argv[0])) 14 | certs_path = os.path.join(script_path, 'certs') 15 | 16 | cert = X509Certificate(open(certs_path + '/valid.crt').read()) 17 | key = X509PrivateKey(open(certs_path + '/valid.key').read()) 18 | ca = X509Certificate(open(certs_path + '/ca.pem').read()) 19 | crl = X509CRL(open(certs_path + '/crl.pem').read()) 20 | cred = X509Credentials(cert, key, [ca], [crl]) 21 | context = TLSContext(cred) 22 | 23 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 24 | session = ClientSession(sock, context) 25 | 26 | try: 27 | session.connect(('localhost', 10000)) 28 | session.handshake() 29 | session.verify_peer() 30 | session.send("test\r\n") 31 | buf = session.recv(1024) 32 | print 'Received: ', buf.rstrip() 33 | session.bye() 34 | session.close() 35 | except GNUTLSError as e: 36 | print('Connection failed: {}'.format(e)) 37 | sys.exit(1) 38 | -------------------------------------------------------------------------------- /examples/crypto.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | """Cryptographic examples using python-gnutls""" 4 | 5 | import sys 6 | import os 7 | import time 8 | 9 | from gnutls.crypto import * 10 | 11 | script_path = os.path.realpath(os.path.dirname(sys.argv[0])) 12 | certs_path = os.path.join(script_path, 'certs') 13 | 14 | cert = X509Certificate(open(certs_path + '/valid.crt').read()) 15 | crl = X509CRL(open(certs_path + '/crl.pem').read()) 16 | 17 | print '' 18 | 19 | print 'CRL certs/crl.pem:' 20 | print '------------------' 21 | print 'CRL issuer:' 22 | print ' CN = %s' % crl.issuer.CN # or crl.issuer.common_name 23 | print ' O = %s' % crl.issuer.O # or crl.issuer.organization 24 | print ' OU = %s' % crl.issuer.OU # or crl.issuer.organization_unit 25 | print ' C = %s' % crl.issuer.C # or crl.issuer.country 26 | print ' ST = %s' % crl.issuer.ST # or crl.issuer.state 27 | print ' L = %s' % crl.issuer.L # or crl.issuer.locality 28 | print ' EMAIL = %s' % crl.issuer.EMAIL # or crl.issuer.email 29 | print 'CRL version:', crl.version 30 | print 'CRL count: ', crl.count 31 | print '' 32 | 33 | print 'Certificate certs/valid.crt:' 34 | print '----------------------------' 35 | print 'Cert subject:' 36 | print ' CN = %s' % cert.subject.CN # or cert.subject.common_name 37 | print ' O = %s' % cert.subject.O # or cert.subject.organization 38 | print ' OU = %s' % cert.subject.OU # or cert.subject.organization_unit 39 | print ' C = %s' % cert.subject.C # or cert.subject.country 40 | print ' ST = %s' % cert.subject.ST # or cert.subject.state 41 | print ' L = %s' % cert.subject.L # or cert.subject.locality 42 | print ' EMAIL = %s' % cert.subject.EMAIL # or cert.subject.email 43 | print 'Cert issuer:' 44 | print ' CN = %s' % cert.issuer.CN # or cert.issuer.common_name 45 | print ' O = %s' % cert.issuer.O # or cert.issuer.organization 46 | print ' OU = %s' % cert.issuer.OU # or cert.issuer.organization_unit 47 | print ' C = %s' % cert.issuer.C # or cert.issuer.country 48 | print ' ST = %s' % cert.issuer.ST # or cert.issuer.state 49 | print ' L = %s' % cert.issuer.L # or cert.issuer.locality 50 | print ' EMAIL = %s' % cert.issuer.EMAIL # or cert.issuer.email 51 | print 'Cert serial: ', cert.serial_number 52 | print 'Cert version: ', cert.version 53 | print 'Cert activation:', time.ctime(cert.activation_time) 54 | print 'Cert expiration:', time.ctime(cert.expiration_time) 55 | print 'Cert is revoked:', crl.is_revoked(cert) 56 | print '' 57 | 58 | cert = X509Certificate(open(certs_path + '/revoked.crt').read()) 59 | 60 | print 'Certificate certs/revoked.crt:' 61 | print '------------------------------' 62 | print 'Cert subject:' 63 | print ' CN = %s' % cert.subject.common_name # here we use long names 64 | print ' O = %s' % cert.subject.organization 65 | print ' OU = %s' % cert.subject.organization_unit 66 | print ' C = %s' % cert.subject.country 67 | print ' ST = %s' % cert.subject.state 68 | print ' L = %s' % cert.subject.locality 69 | print ' EMAIL = %s' % cert.subject.email 70 | print 'Cert issuer:' 71 | print ' CN = %s' % cert.issuer.common_name 72 | print ' O = %s' % cert.issuer.organization 73 | print ' OU = %s' % cert.issuer.organization_unit 74 | print ' C = %s' % cert.issuer.country 75 | print ' ST = %s' % cert.issuer.state 76 | print ' L = %s' % cert.issuer.locality 77 | print ' EMAIL = %s' % cert.issuer.email 78 | print 'Cert serial: ', cert.serial_number 79 | print 'Cert version: ', cert.version 80 | print 'Cert activation:', time.ctime(cert.activation_time) 81 | print 'Cert expiration:', time.ctime(cert.expiration_time) 82 | print 'Cert is revoked:', crl.is_revoked(cert) 83 | print '' 84 | -------------------------------------------------------------------------------- /examples/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | """Synchronous server that handles each connection in a thread""" 4 | 5 | import sys 6 | import os 7 | import socket 8 | from threading import Thread 9 | 10 | from gnutls.crypto import * 11 | from gnutls.connection import * 12 | 13 | script_path = os.path.realpath(os.path.dirname(sys.argv[0])) 14 | certs_path = os.path.join(script_path, 'certs') 15 | 16 | cert = X509Certificate(open(certs_path + '/valid.crt').read()) 17 | key = X509PrivateKey(open(certs_path + '/valid.key').read()) 18 | ca = X509Certificate(open(certs_path + '/ca.pem').read()) 19 | crl = X509CRL(open(certs_path + '/crl.pem').read()) 20 | cred = X509Credentials(cert, key, [ca], [crl]) 21 | context = TLSContext(cred) 22 | 23 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 24 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 25 | ssf = ServerSessionFactory(sock, context) 26 | ssf.bind(('0.0.0.0', 10000)) 27 | ssf.listen(100) 28 | 29 | 30 | class SessionHandler(Thread): 31 | def __init__(self, session, address): 32 | Thread.__init__(self, name='SessionHandler') 33 | self.setDaemon(True) 34 | self.session = session 35 | self.address = address 36 | 37 | def run(self): 38 | session = self.session 39 | try: 40 | session.handshake() 41 | peer_cert = session.peer_certificate 42 | try: 43 | peer_name = peer_cert.subject 44 | except AttributeError: 45 | peer_name = 'Unknown' 46 | print '\nNew connection from:', peer_name 47 | print 'Protocol: ', session.protocol 48 | print 'KX algorithm: ', session.kx_algorithm 49 | print 'Cipher: ', session.cipher 50 | print 'MAC algorithm:', session.mac_algorithm 51 | print 'Compression: ', session.compression 52 | session.verify_peer() 53 | cred.check_certificate(peer_cert, cert_name='peer certificate') 54 | except Exception, e: 55 | print 'Handshake failed:', e 56 | else: 57 | while True: 58 | try: 59 | buf = session.recv(1024) 60 | if not buf: 61 | print "Peer has closed the session" 62 | break 63 | else: 64 | if buf.strip().lower() == 'quit': 65 | print "Got quit command, closing connection" 66 | session.bye() 67 | break 68 | session.send(buf) 69 | except Exception, e: 70 | print "Error in reception: ", e 71 | break 72 | try: 73 | session.shutdown() 74 | except: 75 | pass 76 | session.close() 77 | 78 | while True: 79 | session, address = ssf.accept() 80 | handler = SessionHandler(session, address) 81 | handler.start() 82 | -------------------------------------------------------------------------------- /examples/twisted-client.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | """Asynchronous client using Twisted with GNUTLS""" 4 | 5 | import sys 6 | import os 7 | 8 | from twisted.internet.error import ConnectionDone 9 | from twisted.internet.protocol import ClientFactory 10 | from twisted.protocols.basic import LineOnlyReceiver 11 | from twisted.internet import reactor 12 | 13 | from gnutls.constants import * 14 | from gnutls.crypto import * 15 | from gnutls.errors import * 16 | from gnutls.interfaces.twisted import TLSContext, X509Credentials 17 | 18 | class EchoProtocol(LineOnlyReceiver): 19 | 20 | def connectionMade(self): 21 | self.sendLine('echo') 22 | 23 | def lineReceived(self, line): 24 | print 'received: %s' % line 25 | self.transport.loseConnection() 26 | 27 | def connectionLost(self, reason): 28 | if reason.type != ConnectionDone: 29 | print "connection was lost: %s" % reason.value 30 | reactor.stop() 31 | 32 | class EchoFactory(ClientFactory): 33 | protocol = EchoProtocol 34 | 35 | def clientConnectionFailed(self, connector, err): 36 | print "connection failed: %s" % err.value 37 | reactor.stop() 38 | 39 | 40 | script_path = os.path.realpath(os.path.dirname(sys.argv[0])) 41 | certs_path = os.path.join(script_path, 'certs') 42 | 43 | cert = X509Certificate(open(certs_path + '/valid.crt').read()) 44 | key = X509PrivateKey(open(certs_path + '/valid.key').read()) 45 | ca = X509Certificate(open(certs_path + '/ca.pem').read()) 46 | crl = X509CRL(open(certs_path + '/crl.pem').read()) 47 | cred = X509Credentials(cert, key, [ca], [crl]) 48 | cred.verify_peer = True 49 | context = TLSContext(cred, session_parameters="NORMAL:-COMP-ALL:+COMP-DEFLATE:+COMP-NULL") 50 | 51 | reactor.connectTLS('localhost', 10000, EchoFactory(), context) 52 | reactor.run() 53 | -------------------------------------------------------------------------------- /examples/twisted-server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | """Asynchronous server using Twisted with GNUTLS""" 4 | 5 | import sys 6 | import os 7 | 8 | from twisted.internet.protocol import Factory 9 | from twisted.protocols.basic import LineOnlyReceiver 10 | from twisted.internet.error import CannotListenError, ConnectionDone 11 | from twisted.internet import reactor 12 | 13 | from gnutls.constants import * 14 | from gnutls.crypto import * 15 | from gnutls.errors import * 16 | from gnutls.interfaces.twisted import TLSContext, X509Credentials 17 | 18 | class EchoProtocol(LineOnlyReceiver): 19 | 20 | def connectionMade(self): 21 | session = self.transport.socket 22 | try: 23 | peer_name = session.peer_certificate.subject 24 | except AttributeError: 25 | peer_name = 'Unknown' 26 | print '\nNew connection from: %s' % peer_name 27 | print 'Protocol: %s' % session.protocol 28 | print 'KX algorithm: %s' % session.kx_algorithm 29 | print 'Cipher: %s' % session.cipher 30 | print 'MAC algorithm: %s' % session.mac_algorithm 31 | print 'Compression: %s' % session.compression 32 | 33 | def lineReceived(self, line): 34 | if line == 'quit': 35 | self.transport.loseConnection() 36 | return 37 | self.sendLine(line) 38 | 39 | def connectionLost(self, reason): 40 | if reason.type != ConnectionDone: 41 | print "Connection was lost: %s" % reason.value 42 | 43 | class EchoFactory(Factory): 44 | protocol = EchoProtocol 45 | 46 | script_path = os.path.realpath(os.path.dirname(sys.argv[0])) 47 | certs_path = os.path.join(script_path, 'certs') 48 | 49 | cert = X509Certificate(open(certs_path + '/valid.crt').read()) 50 | key = X509PrivateKey(open(certs_path + '/valid.key').read()) 51 | ca = X509Certificate(open(certs_path + '/ca.pem').read()) 52 | crl = X509CRL(open(certs_path + '/crl.pem').read()) 53 | cred = X509Credentials(cert, key, [ca], [crl]) 54 | cred.verify_peer = True 55 | context = TLSContext(cred, session_parameters="NORMAL:+COMP-DEFLATE") 56 | 57 | reactor.listenTLS(10000, EchoFactory(), context) 58 | reactor.run() 59 | -------------------------------------------------------------------------------- /gnutls/__info__.py: -------------------------------------------------------------------------------- 1 | 2 | """Package information""" 3 | 4 | __project__ = "python-gnutls" 5 | __summary__ = "Python wrapper for the GnuTLS library" 6 | __webpage__ = "https://github.com/AGProjects/python-gnutls" 7 | 8 | __version__ = "3.1.3" 9 | 10 | __author__ = "Dan Pascu" 11 | __email__ = "dan@ag-projects.com" 12 | 13 | __license__ = "LGPL" 14 | __copyright__ = "Copyright 2006-2020 {}".format(__author__) 15 | -------------------------------------------------------------------------------- /gnutls/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | """Python wrapper for the GnuTLS library""" 3 | 4 | from gnutls.__info__ import __project__, __summary__, __webpage__, __version__, __author__, __email__, __license__, __copyright__ 5 | -------------------------------------------------------------------------------- /gnutls/connection.py: -------------------------------------------------------------------------------- 1 | 2 | """GNUTLS connection support""" 3 | 4 | __all__ = ['X509Credentials', 'TLSContext', 'TLSContextServerOptions', 'ClientSession', 'ServerSession', 'ServerSessionFactory'] 5 | 6 | from time import time 7 | from socket import SHUT_RDWR as SOCKET_SHUT_RDWR 8 | 9 | from _ctypes import PyObj_FromPtr 10 | from ctypes import * 11 | 12 | from gnutls.validators import * 13 | from gnutls.constants import * 14 | from gnutls.crypto import * 15 | from gnutls.errors import * 16 | 17 | from gnutls.library.constants import GNUTLS_SERVER, GNUTLS_CLIENT, GNUTLS_CRT_X509 18 | from gnutls.library.constants import GNUTLS_CERT_INVALID, GNUTLS_CERT_REVOKED, GNUTLS_CERT_INSECURE_ALGORITHM 19 | from gnutls.library.constants import GNUTLS_CERT_SIGNER_NOT_FOUND, GNUTLS_CERT_SIGNER_NOT_CA 20 | from gnutls.library.constants import GNUTLS_AL_FATAL, GNUTLS_A_BAD_CERTIFICATE 21 | from gnutls.library.constants import GNUTLS_A_UNKNOWN_CA, GNUTLS_A_INSUFFICIENT_SECURITY 22 | from gnutls.library.constants import GNUTLS_A_CERTIFICATE_EXPIRED, GNUTLS_A_CERTIFICATE_REVOKED 23 | from gnutls.library.constants import GNUTLS_NAME_DNS 24 | from gnutls.library.types import gnutls_certificate_credentials_t, gnutls_session_t, gnutls_x509_crt_t 25 | from gnutls.library.types import gnutls_certificate_retrieve_function 26 | from gnutls.library.types import gnutls_priority_t 27 | from gnutls.library.functions import * 28 | 29 | 30 | @gnutls_certificate_retrieve_function 31 | def _retrieve_certificate(c_session, req_ca_dn, nreqs, pk_algos, pk_algos_length, retr_st): 32 | session = PyObj_FromPtr(gnutls_session_get_ptr(c_session)) 33 | identity = session.credentials.select_server_identity(session) 34 | retr_st.contents.deinit_all = 0 35 | if identity is None: 36 | retr_st.contents.ncerts = 0 37 | else: 38 | retr_st.contents.ncerts = 1 39 | retr_st.contents.cert_type = GNUTLS_CRT_X509 40 | retr_st.contents.cert.x509.contents = identity.cert._c_object 41 | retr_st.contents.key.x509 = identity.key._c_object 42 | return 0 43 | 44 | 45 | class _ServerNameIdentities(dict): 46 | """Used internally by X509Credentials to map server names to X509 identities for the server name extension""" 47 | def __init__(self, identities): 48 | dict.__init__(self) 49 | for identity in identities: 50 | self.add(identity) 51 | def add(self, identity): 52 | for name in identity.cert.alternative_names.dns: 53 | self[name.lower()] = identity 54 | for ip in identity.cert.alternative_names.ip: 55 | self[ip] = identity 56 | subject = identity.cert.subject 57 | if subject.CN is not None: 58 | self[subject.CN.lower()] = identity 59 | def get(self, server_name, default=None): 60 | server_name = server_name.lower() 61 | if server_name in self: 62 | return self[server_name] 63 | for name in (n for n in self if n.startswith('*.')): 64 | suffix = name[1:] 65 | if server_name.endswith(suffix) and '.' not in server_name[:-len(suffix)]: 66 | return self[name] 67 | return default 68 | 69 | 70 | class X509Credentials(object): 71 | def __new__(cls, *args, **kwargs): 72 | c_object = gnutls_certificate_credentials_t() 73 | gnutls_certificate_allocate_credentials(byref(c_object)) 74 | instance = object.__new__(cls) 75 | instance.__deinit = gnutls_certificate_free_credentials 76 | instance._c_object = c_object 77 | return instance 78 | 79 | @method_args((X509Certificate, none), (X509PrivateKey, none), list_of(X509Certificate), list_of(X509CRL), list_of(X509Identity)) 80 | def __init__(self, cert=None, key=None, trusted=[], crl_list=[], identities=[]): 81 | """Credentials contain a X509 certificate, a private key, a list of trusted CAs and a list of CRLs (all optional). 82 | An optional list of additional X509 identities can be specified for applications that need more that one identity""" 83 | if cert and key: 84 | gnutls_certificate_set_x509_key(self._c_object, byref(cert._c_object), 1, key._c_object) 85 | elif (cert, key) != (None, None): 86 | raise ValueError("Specify neither or both the certificate and private key") 87 | gnutls_certificate_set_retrieve_function(self._c_object, _retrieve_certificate) 88 | self._max_depth = 5 89 | self._max_bits = 8200 90 | self._type = CRED_CERTIFICATE 91 | self._cert = cert 92 | self._key = key 93 | self._identities = tuple(identities) 94 | self._trusted = () 95 | self.add_trusted(trusted) 96 | self.crl_list = crl_list 97 | self.server_name_identities = _ServerNameIdentities(identities) 98 | if cert and key: 99 | self.server_name_identities.add(X509Identity(cert, key)) 100 | 101 | def __del__(self): 102 | self.__deinit(self._c_object) 103 | 104 | # Methods to alter the credentials at runtime 105 | 106 | @method_args(list_of(X509Certificate)) 107 | def add_trusted(self, trusted): 108 | size = len(trusted) 109 | if size > 0: 110 | ca_list = (gnutls_x509_crt_t * size)(*[cert._c_object for cert in trusted]) 111 | gnutls_certificate_set_x509_trust(self._c_object, cast(byref(ca_list), POINTER(gnutls_x509_crt_t)), size) 112 | self._trusted = self._trusted + tuple(trusted) 113 | 114 | # Properties 115 | 116 | @property 117 | def cert(self): 118 | return self._cert 119 | 120 | @property 121 | def key(self): 122 | return self._key 123 | 124 | @property 125 | def identities(self): 126 | return self._identities 127 | 128 | @property 129 | def trusted(self): 130 | return self._trusted 131 | 132 | def _get_crl_list(self): 133 | return self._crl_list 134 | @method_args(list_of(X509CRL)) 135 | def _set_crl_list(self, crl_list): 136 | self._crl_list = tuple(crl_list) 137 | crl_list = property(_get_crl_list, _set_crl_list) 138 | del _get_crl_list, _set_crl_list 139 | 140 | def _get_max_verify_length(self): 141 | return self._max_depth 142 | @method_args(int) 143 | def _set_max_verify_length(self, max_depth): 144 | gnutls_certificate_set_verify_limits(self._c_object, self._max_bits, max_depth) 145 | self._max_depth = max_depth 146 | max_verify_length = property(_get_max_verify_length, _set_max_verify_length) 147 | del _get_max_verify_length, _set_max_verify_length 148 | 149 | def _get_max_verify_bits(self): 150 | return self._max_bits 151 | @method_args(int) 152 | def _set_max_verify_bits(self, max_bits): 153 | gnutls_certificate_set_verify_limits(self._c_object, max_bits, self._max_depth) 154 | self._max_bits = max_bits 155 | max_verify_bits = property(_get_max_verify_bits, _set_max_verify_bits) 156 | del _get_max_verify_bits, _set_max_verify_bits 157 | 158 | # Methods to select and validate certificates 159 | 160 | def check_certificate(self, cert, cert_name='certificate'): 161 | """Verify activation, expiration and revocation for the given certificate""" 162 | now = time() 163 | if cert.activation_time > now: 164 | raise CertificateExpiredError("%s is not yet activated" % cert_name) 165 | if cert.expiration_time < now: 166 | raise CertificateExpiredError("%s has expired" % cert_name) 167 | for crl in self.crl_list: 168 | crl.check_revocation(cert, cert_name=cert_name) 169 | 170 | def select_server_identity(self, session): 171 | """Select which identity the server will use for a given session. The default selection algorithm uses 172 | the server name extension. A subclass can overwrite it if a different selection algorithm is desired.""" 173 | server_name = session.server_name 174 | if server_name is not None: 175 | return self.server_name_identities.get(server_name) 176 | elif self.cert and self.key: 177 | return self ## since we have the cert and key attributes we can behave like a X509Identity 178 | else: 179 | return None 180 | 181 | 182 | class TLSContextServerOptions(object): 183 | def __init__(self, certificate_request=CERT_REQUEST): 184 | self.certificate_request = certificate_request 185 | 186 | 187 | class TLSContext(object): 188 | def __init__(self, credentials, session_parameters=None, server_options=None): 189 | self.credentials = credentials 190 | self.session_parameters = session_parameters 191 | self.server_options = server_options or TLSContextServerOptions() 192 | 193 | @property 194 | def session_parameters(self): 195 | return self.__dict__.get('session_parameters') 196 | 197 | @session_parameters.setter 198 | def session_parameters(self, value): 199 | priority = gnutls_priority_t() 200 | try: 201 | gnutls_priority_init(byref(priority), value, None) 202 | except GNUTLSError: 203 | raise ValueError("invalid session parameters: %s" % value) 204 | else: 205 | gnutls_priority_deinit(priority) 206 | self.__dict__['session_parameters'] = value 207 | 208 | 209 | class Session(object): 210 | """Abstract class representing a TLS session created from a TCP socket 211 | and a Credentials object.""" 212 | 213 | session_type = None ## placeholder for GNUTLS_SERVER or GNUTLS_CLIENT as defined by subclass 214 | 215 | def __new__(cls, *args, **kwargs): 216 | if cls is Session: 217 | raise RuntimeError("Session cannot be instantiated directly") 218 | instance = object.__new__(cls) 219 | instance.__deinit = gnutls_deinit 220 | instance._c_object = gnutls_session_t() 221 | return instance 222 | 223 | def __init__(self, socket, context): 224 | gnutls_init(byref(self._c_object), self.session_type) 225 | ## Store a pointer to self on the C session 226 | gnutls_session_set_ptr(self._c_object, id(self)) 227 | gnutls_set_default_priority(self._c_object) 228 | gnutls_priority_set_direct(self._c_object, context.session_parameters, None) 229 | gnutls_transport_set_ptr(self._c_object, socket.fileno()) 230 | gnutls_handshake_set_private_extensions(self._c_object, 1) 231 | self.socket = socket 232 | self.credentials = context.credentials 233 | 234 | def __del__(self): 235 | self.__deinit(self._c_object) 236 | 237 | def __getattr__(self, name): 238 | ## Generic wrapper for the underlying socket methods and attributes. 239 | return getattr(self.socket, name) 240 | 241 | # Session properties 242 | 243 | def _get_credentials(self): 244 | return self._credentials 245 | @method_args(X509Credentials) 246 | def _set_credentials(self, credentials): 247 | ## Release all credentials, otherwise gnutls will only release an existing credential of 248 | ## the same type as the one being set and we can end up with multiple credentials in C. 249 | gnutls_credentials_clear(self._c_object) 250 | gnutls_credentials_set(self._c_object, credentials._type, cast(credentials._c_object, c_void_p)) 251 | self._credentials = credentials 252 | credentials = property(_get_credentials, _set_credentials) 253 | del _get_credentials, _set_credentials 254 | 255 | @property 256 | def protocol(self): 257 | return gnutls_protocol_get_name(gnutls_protocol_get_version(self._c_object)) 258 | 259 | @property 260 | def kx_algorithm(self): 261 | return gnutls_kx_get_name(gnutls_kx_get(self._c_object)) 262 | 263 | @property 264 | def cipher(self): 265 | return gnutls_cipher_get_name(gnutls_cipher_get(self._c_object)) 266 | 267 | @property 268 | def mac_algorithm(self): 269 | return gnutls_mac_get_name(gnutls_mac_get(self._c_object)) 270 | 271 | @property 272 | def compression(self): 273 | return gnutls_compression_get_name(gnutls_compression_get(self._c_object)) 274 | 275 | @property 276 | def peer_certificate(self): 277 | if gnutls_certificate_type_get(self._c_object) != GNUTLS_CRT_X509: 278 | return None 279 | list_size = c_uint() 280 | cert_list = gnutls_certificate_get_peers(self._c_object, byref(list_size)) 281 | if list_size.value == 0: 282 | return None 283 | cert = cert_list[0] 284 | return X509Certificate(string_at(cert.data, cert.size), X509_FMT_DER) 285 | 286 | # Status checking after an operation was interrupted (these properties are 287 | # only useful to check after an operation was interrupted, otherwise their 288 | # value is meaningless). 289 | 290 | @property 291 | def interrupted_while_writing(self): 292 | """True if an operation was interrupted while writing""" 293 | return gnutls_record_get_direction(self._c_object)==1 294 | 295 | @property 296 | def interrupted_while_reading(self): 297 | """True if an operation was interrupted while reading""" 298 | return gnutls_record_get_direction(self._c_object)==0 299 | 300 | # Session methods 301 | 302 | def handshake(self): 303 | gnutls_handshake(self._c_object) 304 | 305 | def send(self, data): 306 | data = str(data) 307 | if not data: 308 | return 0 309 | return gnutls_record_send(self._c_object, data, len(data)) 310 | 311 | def sendall(self, data): 312 | size = len(data) 313 | while size > 0: 314 | sent = self.send(data[-size:]) 315 | size -= sent 316 | 317 | def recv(self, limit): 318 | data = create_string_buffer(limit) 319 | size = gnutls_record_recv(self._c_object, data, limit) 320 | return data[:size] 321 | 322 | def send_alert(self, exception): 323 | alertdict = { 324 | CertificateError: GNUTLS_A_BAD_CERTIFICATE, 325 | CertificateAuthorityError: GNUTLS_A_UNKNOWN_CA, 326 | CertificateSecurityError: GNUTLS_A_INSUFFICIENT_SECURITY, 327 | CertificateExpiredError: GNUTLS_A_CERTIFICATE_EXPIRED, 328 | CertificateRevokedError: GNUTLS_A_CERTIFICATE_REVOKED} 329 | alert = alertdict.get(exception.__class__) 330 | if alert: 331 | gnutls_alert_send(self._c_object, GNUTLS_AL_FATAL, alert) 332 | 333 | @method_args(one_of(SHUT_RDWR, SHUT_WR)) 334 | def bye(self, how=SHUT_RDWR): 335 | gnutls_bye(self._c_object, how) 336 | 337 | def shutdown(self, how=SOCKET_SHUT_RDWR): 338 | self.socket.shutdown(how) 339 | 340 | def close(self): 341 | self.socket.close() 342 | 343 | def verify_peer(self): 344 | status = c_uint() 345 | gnutls_certificate_verify_peers2(self._c_object, byref(status)) 346 | status = status.value 347 | if status & GNUTLS_CERT_INVALID: 348 | raise CertificateError("peer certificate is invalid") 349 | elif status & GNUTLS_CERT_SIGNER_NOT_FOUND: 350 | raise CertificateAuthorityError("peer certificate signer not found") 351 | elif status & GNUTLS_CERT_SIGNER_NOT_CA: 352 | raise CertificateAuthorityError("peer certificate signer is not a CA") 353 | elif status & GNUTLS_CERT_INSECURE_ALGORITHM: 354 | raise CertificateSecurityError("peer certificate uses an insecure algorithm") 355 | elif status & GNUTLS_CERT_REVOKED: 356 | raise CertificateRevokedError("peer certificate was revoked") 357 | 358 | 359 | class ClientSession(Session): 360 | session_type = GNUTLS_CLIENT 361 | 362 | def __init__(self, socket, context, server_name=None): 363 | Session.__init__(self, socket, context) 364 | self._server_name = None 365 | if server_name is not None: 366 | self.server_name = server_name 367 | 368 | def _get_server_name(self): 369 | return self._server_name 370 | @method_args(str) 371 | def _set_server_name(self, server_name): 372 | gnutls_server_name_set(self._c_object, GNUTLS_NAME_DNS, c_char_p(server_name), len(server_name)) 373 | self._server_name = server_name 374 | server_name = property(_get_server_name, _set_server_name) 375 | del _get_server_name, _set_server_name 376 | 377 | 378 | class ServerSession(Session): 379 | session_type = GNUTLS_SERVER 380 | 381 | def __init__(self, socket, context): 382 | Session.__init__(self, socket, context) 383 | if context.server_options.certificate_request is not None: 384 | gnutls_certificate_server_set_request(self._c_object, context.server_options.certificate_request) 385 | 386 | @property 387 | def server_name(self): 388 | data_length = c_size_t(256) 389 | data = create_string_buffer(data_length.value) 390 | hostname_type = c_uint() 391 | for i in xrange(2**16): 392 | try: 393 | gnutls_server_name_get(self._c_object, data, byref(data_length), byref(hostname_type), i) 394 | except RequestedDataNotAvailable: 395 | break 396 | except MemoryError: 397 | data_length.value += 1 ## one extra byte for the terminating 0 398 | data = create_string_buffer(data_length.value) 399 | gnutls_server_name_get(self._c_object, data, byref(data_length), byref(hostname_type), i) 400 | if hostname_type.value != GNUTLS_NAME_DNS: 401 | continue 402 | return data.value 403 | return None 404 | 405 | 406 | class ServerSessionFactory(object): 407 | 408 | def __init__(self, socket, context, session_class=ServerSession): 409 | if not issubclass(session_class, ServerSession): 410 | raise TypeError, "session_class must be a subclass of ServerSession" 411 | self.socket = socket 412 | self.context = context 413 | self.session_class = session_class 414 | 415 | def __getattr__(self, name): 416 | ## Generic wrapper for the underlying socket methods and attributes 417 | return getattr(self.socket, name) 418 | 419 | def bind(self, address): 420 | self.socket.bind(address) 421 | 422 | def listen(self, backlog): 423 | self.socket.listen(backlog) 424 | 425 | def accept(self): 426 | new_sock, address = self.socket.accept() 427 | session = self.session_class(new_sock, self.context) 428 | return (session, address) 429 | 430 | def shutdown(self, how=SOCKET_SHUT_RDWR): 431 | self.socket.shutdown(how) 432 | 433 | def close(self): 434 | self.socket.close() 435 | 436 | -------------------------------------------------------------------------------- /gnutls/constants.py: -------------------------------------------------------------------------------- 1 | 2 | """GNUTLS constants""" 3 | 4 | __all__ = [ 5 | ## Credential types 6 | 'CRED_CERTIFICATE', 'CRED_ANON', 7 | 8 | ## X509 certificate/private key formats 9 | 'X509_FMT_DER', 'X509_FMT_PEM', 10 | 11 | ## Miscellaneous 12 | 'CERT_REQUEST', 'CERT_REQUIRE', 'SHUT_RDWR', 'SHUT_WR' 13 | ] 14 | 15 | __name_map__ = { 16 | 'PROTO_TLS1_2': 'TLS1_2', 'PROTO_TLS1_1': 'TLS1_1', 'PROTO_TLS1_0': 'TLS1_0', 17 | 'PROTO_SSL3': 'SSL3', 'CRED_CERTIFICATE': 'CRD_CERTIFICATE', 'CRED_ANON': 'CRD_ANON' 18 | } 19 | 20 | 21 | from gnutls.library import constants 22 | 23 | class GNUTLSConstant(int): 24 | def __new__(cls, name): 25 | gnutls_name = 'GNUTLS_' + __name_map__.get(name, name) 26 | instance = int.__new__(cls, getattr(constants, gnutls_name)) 27 | instance.name = name 28 | return instance 29 | def __repr__(self): 30 | return self.name 31 | 32 | ## Generate all exported constants 33 | code = '\n'.join(["%s = GNUTLSConstant('%s')" % (name, name) for name in __all__]) 34 | exec code in locals(), globals() 35 | del code, name 36 | 37 | del constants 38 | -------------------------------------------------------------------------------- /gnutls/crypto.py: -------------------------------------------------------------------------------- 1 | 2 | """GNUTLS crypto support""" 3 | 4 | __all__ = ['X509Name', 'X509Certificate', 'X509PrivateKey', 'X509Identity', 'X509CRL', 'DHParams'] 5 | 6 | import re 7 | from ctypes import * 8 | 9 | from gnutls.validators import method_args, one_of 10 | from gnutls.constants import X509_FMT_DER, X509_FMT_PEM 11 | from gnutls.errors import * 12 | 13 | from gnutls.library.constants import GNUTLS_SAN_DNSNAME, GNUTLS_SAN_RFC822NAME, GNUTLS_SAN_URI 14 | from gnutls.library.constants import GNUTLS_SAN_IPADDRESS, GNUTLS_SAN_OTHERNAME, GNUTLS_SAN_DN 15 | from gnutls.library.constants import GNUTLS_E_SHORT_MEMORY_BUFFER 16 | from gnutls.library.types import * 17 | from gnutls.library.functions import * 18 | 19 | 20 | class X509NameMeta(type): 21 | long_names = {'country': 'C', 22 | 'state': 'ST', 23 | 'locality': 'L', 24 | 'common_name': 'CN', 25 | 'organization': 'O', 26 | 'organization_unit': 'OU', 27 | 'email': 'EMAIL'} 28 | def __new__(cls, name, bases, dic): 29 | instance = type.__new__(cls, name, bases, dic) 30 | instance.ids = X509NameMeta.long_names.values() 31 | for long_name, short_name in X509NameMeta.long_names.items(): 32 | ## Map a long_name property to the short_name attribute 33 | cls.add_property(instance, long_name, short_name) 34 | return instance 35 | def add_property(instance, name, short_name): 36 | setattr(instance, name, property(lambda self: getattr(self, short_name, None))) 37 | 38 | 39 | class X509Name(str): 40 | __metaclass__ = X509NameMeta 41 | 42 | def __init__(self, dname): 43 | str.__init__(self) 44 | pairs = [x.replace('\,', ',') for x in re.split(r'(? 0: 177 | self.__watchdog = RecurrentCall(credentials.verify_period, self._recurrentVerify) 178 | 179 | def doHandshake(self): 180 | self.stopWriting() 181 | try: 182 | self.socket.handshake() 183 | except (OperationWouldBlock, OperationInterrupted): 184 | if self.socket.interrupted_while_writing: 185 | self.startWriting() 186 | return 187 | except GNUTLSError, e: 188 | del self.doRead 189 | self.failIfNotConnected(err = e) 190 | return 191 | 192 | ## reset any references to the old doRead 193 | del self.doRead 194 | self.stopReading() 195 | 196 | try: 197 | self._verifyPeer() 198 | except GNUTLSError, e: 199 | self.closeTLSSession(e) 200 | self.failIfNotConnected(err = e) 201 | return 202 | except Exception, e: 203 | self.closeTLSSession(e) 204 | self.failIfNotConnected(err = error.getConnectError(str(e))) 205 | return 206 | 207 | ## TLS handshake (including certificate verification) finished succesfully 208 | tcp.Client._connectDone(self) 209 | 210 | def startTLS(self): 211 | self.doRead = self.doHandshake 212 | self.startReading() 213 | self.doHandshake() 214 | 215 | def _connectDone(self): 216 | self.startTLS() 217 | 218 | def loseConnection(self, reason=failure.Failure(main.CONNECTION_DONE)): 219 | reason = failure.Failure(reason) # accept python exceptions too 220 | self._close_reason = reason.value 221 | abstract.FileDescriptor.loseConnection(self, reason) 222 | 223 | def connectionLost(self, reason): 224 | if self.__watchdog is not None: 225 | self.__watchdog.cancel() 226 | self.__watchdog = None 227 | tcp.Client.connectionLost(self, reason) 228 | 229 | 230 | class TLSConnector(base.BaseConnector): 231 | def __init__(self, host, port, factory, context, timeout, bindAddress, reactor=None, server_name=None): 232 | self.host = host 233 | self.port = port 234 | self.bindAddress = bindAddress 235 | self.context = context 236 | self.server_name = server_name 237 | base.BaseConnector.__init__(self, factory, timeout, reactor) 238 | 239 | def _makeTransport(self): 240 | return TLSClient(self.host, self.port, self.bindAddress, self.context, self, self.reactor, self.server_name) 241 | 242 | 243 | class TLSServer(TLSMixin, tcp.Server): 244 | """Add TLS capabilities to a TCP server""" 245 | 246 | implementsOnly(interfaces.ISSLTransport, *[i for i in implementedBy(tcp.Server) if i != interfaces.ITLSTransport]) 247 | 248 | def __init__(self, sock, protocol, client, server, sessionno, *args, **kw): 249 | self.__watchdog = None 250 | self.context = server.context 251 | tcp.Server.__init__(self, sock, protocol, client, server, sessionno, *args, **kw) 252 | self.protocol.makeConnection = lambda *args: None 253 | self.protocol.transport = self ## because we may call connectionLost without connectionMade 254 | self.startTLS() 255 | 256 | def _recurrentVerify(self): 257 | if not self.connected or self.disconnecting: 258 | return 259 | try: 260 | self.context.credentials.verify_callback(self.socket.peer_certificate) 261 | except Exception, e: 262 | self.loseConnection(e) 263 | return 264 | else: 265 | return KeepRunning 266 | 267 | def _verifyPeer(self): 268 | session = self.socket 269 | credentials = self.context.credentials 270 | if not credentials.verify_peer: 271 | return 272 | try: 273 | session.verify_peer() 274 | except Exception, e: 275 | preverify_status = e 276 | else: 277 | preverify_status = CertificateOK 278 | 279 | credentials.verify_callback(session.peer_certificate, preverify_status) 280 | 281 | if credentials.verify_period > 0: 282 | self.__watchdog = RecurrentCall(credentials.verify_period, self._recurrentVerify) 283 | 284 | def doHandshake(self): 285 | self.stopWriting() 286 | try: 287 | self.socket.handshake() 288 | except (OperationWouldBlock, OperationInterrupted): 289 | if self.socket.interrupted_while_writing: 290 | self.startWriting() 291 | return 292 | except GNUTLSError, e: 293 | del self.doRead 294 | return e 295 | 296 | ## reset any references to the old doRead 297 | del self.doRead 298 | self.stopReading() 299 | self.startReading() 300 | 301 | try: 302 | self._verifyPeer() 303 | except Exception, e: 304 | self.loseConnection(e) 305 | return 306 | 307 | ## TLS handshake (including certificate verification) finished succesfully 308 | 309 | del self.protocol.makeConnection 310 | self.protocol.makeConnection(self) 311 | 312 | def startTLS(self): 313 | self.doRead = self.doHandshake 314 | self.startReading() 315 | 316 | def loseConnection(self, reason=failure.Failure(main.CONNECTION_DONE)): 317 | reason = failure.Failure(reason) # accept python exceptions too 318 | self._close_reason = reason.value 319 | abstract.FileDescriptor.loseConnection(self, reason) 320 | 321 | def connectionLost(self, reason): 322 | if self.__watchdog is not None: 323 | self.__watchdog.cancel() 324 | self.__watchdog = None 325 | tcp.Server.connectionLost(self, reason) 326 | 327 | 328 | class TLSPort(tcp.Port): 329 | """Add TLS capabilities to a TCP port""" 330 | 331 | transport = TLSServer 332 | 333 | def __init__(self, port, factory, context, backlog=50, interface='', reactor=None, session_class=ServerSession): 334 | tcp.Port.__init__(self, port, factory, backlog, interface, reactor) 335 | self.context = context 336 | self.session_class = session_class 337 | 338 | def createInternetSocket(self): 339 | sock = tcp.Port.createInternetSocket(self) 340 | return ServerSessionFactory(sock, self.context, self.session_class) 341 | 342 | 343 | def connectTLS(reactor, host, port, factory, context, timeout=30, bindAddress=None, server_name=None): 344 | c = TLSConnector(host, port, factory, context, timeout, bindAddress, reactor, server_name) 345 | c.connect() 346 | return c 347 | 348 | 349 | def listenTLS(reactor, port, factory, context, backlog=50, interface='', session_class=ServerSession): 350 | p = TLSPort(port, factory, context, backlog, interface, reactor, session_class) 351 | p.startListening() 352 | return p 353 | 354 | ## Add the connectTLS and listenTLS methods to the reactor 355 | 356 | import new 357 | from twisted.internet.posixbase import PosixReactorBase 358 | 359 | method = new.instancemethod(connectTLS, None, PosixReactorBase) 360 | setattr(PosixReactorBase, 'connectTLS', method) 361 | 362 | method = new.instancemethod(listenTLS, None, PosixReactorBase) 363 | setattr(PosixReactorBase, 'listenTLS', method) 364 | 365 | -------------------------------------------------------------------------------- /gnutls/library/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from itertools import chain 3 | 4 | __all__ = ['constants', 'errors', 'functions', 'types'] 5 | 6 | 7 | def get_system_name(): 8 | import platform 9 | system = platform.system().lower() 10 | if system.startswith('cygwin'): 11 | system = 'cygwin' 12 | return system 13 | 14 | 15 | def library_locations(abi_version): 16 | import os 17 | 18 | system = get_system_name() 19 | if system == 'darwin': 20 | library_names = ['libgnutls.%d.dylib' % abi_version] 21 | dynamic_loader_env_vars = ['DYLD_LIBRARY_PATH', 'LD_LIBRARY_PATH'] 22 | additional_paths = ['/usr/local/lib', '/opt/local/lib', '/sw/lib'] 23 | elif system == 'windows': 24 | library_names = ['libgnutls-%d.dll' % abi_version] 25 | dynamic_loader_env_vars = ['PATH'] 26 | additional_paths = ['.'] 27 | elif system == 'cygwin': 28 | library_names = ['cyggnutls-%d.dll' % abi_version] 29 | dynamic_loader_env_vars = ['LD_LIBRARY_PATH'] 30 | additional_paths = ['/usr/bin'] 31 | else: 32 | # Debian uses libgnutls-deb0.so.28, go figure 33 | library_names = ['libgnutls.so.%d' % abi_version, 'libgnutls-deb0.so.%d' % abi_version] 34 | dynamic_loader_env_vars = ['LD_LIBRARY_PATH'] 35 | additional_paths = ['/usr/local/lib'] 36 | for library_name in library_names: 37 | for path in (path for env_var in dynamic_loader_env_vars for path in os.environ.get(env_var, '').split(':') if os.path.isdir(path)): 38 | yield os.path.join(path, library_name) 39 | yield library_name 40 | for path in additional_paths: 41 | yield os.path.join(path, library_name) 42 | 43 | 44 | def load_library(abi_versions): 45 | from ctypes import CDLL 46 | 47 | for library in chain.from_iterable(library_locations(abi_version) for abi_version in sorted(abi_versions, reverse=True)): 48 | try: 49 | return CDLL(library) 50 | except OSError: 51 | pass 52 | else: 53 | break 54 | else: 55 | raise RuntimeError('cannot find a supported version of libgnutls on this system') 56 | 57 | 58 | libgnutls = load_library(abi_versions=(28, 30)) # will use the highest of the available ABI versions 59 | 60 | 61 | from gnutls.library import constants 62 | from gnutls.library import errors 63 | from gnutls.library import functions 64 | from gnutls.library import types 65 | 66 | 67 | __need_version__ = '3.2.0' 68 | 69 | if functions.gnutls_check_version(__need_version__) is None: 70 | version = functions.gnutls_check_version(None) 71 | raise RuntimeError("Found GNUTLS library version %s, but at least version %s is required" % (version, __need_version__)) 72 | 73 | # calling gnutls_global_init is no longer required starting with gnutls 3.3 74 | if functions.gnutls_check_version('3.3') is None: 75 | libgnutls.gnutls_global_init() 76 | 77 | 78 | del get_system_name, library_locations, load_library 79 | 80 | -------------------------------------------------------------------------------- /gnutls/library/constants.py: -------------------------------------------------------------------------------- 1 | 2 | GNUTLS_AL_FATAL = 2 3 | GNUTLS_AL_WARNING = 1 4 | GNUTLS_A_ACCESS_DENIED = 49 5 | GNUTLS_A_BAD_CERTIFICATE = 42 6 | GNUTLS_A_BAD_RECORD_MAC = 20 7 | GNUTLS_A_CERTIFICATE_EXPIRED = 45 8 | GNUTLS_A_CERTIFICATE_REVOKED = 44 9 | GNUTLS_A_CERTIFICATE_UNKNOWN = 46 10 | GNUTLS_A_CERTIFICATE_UNOBTAINABLE = 111 11 | GNUTLS_A_CLOSE_NOTIFY = 0 12 | GNUTLS_A_DECODE_ERROR = 50 13 | GNUTLS_A_DECOMPRESSION_FAILURE = 30 14 | GNUTLS_A_DECRYPTION_FAILED = 21 15 | GNUTLS_A_DECRYPT_ERROR = 51 16 | GNUTLS_A_EXPORT_RESTRICTION = 60 17 | GNUTLS_A_HANDSHAKE_FAILURE = 40 18 | GNUTLS_A_ILLEGAL_PARAMETER = 47 19 | GNUTLS_A_INNER_APPLICATION_FAILURE = 208 20 | GNUTLS_A_INNER_APPLICATION_VERIFICATION = 209 21 | GNUTLS_A_INSUFFICIENT_SECURITY = 71 22 | GNUTLS_A_INTERNAL_ERROR = 80 23 | GNUTLS_A_NO_RENEGOTIATION = 100 24 | GNUTLS_A_PROTOCOL_VERSION = 70 25 | GNUTLS_A_RECORD_OVERFLOW = 22 26 | GNUTLS_A_SSL3_NO_CERTIFICATE = 41 27 | GNUTLS_A_UNEXPECTED_MESSAGE = 10 28 | GNUTLS_A_UNKNOWN_CA = 48 29 | GNUTLS_A_UNKNOWN_PSK_IDENTITY = 115 30 | GNUTLS_A_UNRECOGNIZED_NAME = 112 31 | GNUTLS_A_UNSUPPORTED_CERTIFICATE = 43 32 | GNUTLS_A_UNSUPPORTED_EXTENSION = 110 33 | GNUTLS_A_USER_CANCELED = 90 34 | GNUTLS_CERT_IGNORE = 0 35 | GNUTLS_CERT_INSECURE_ALGORITHM = 256 36 | GNUTLS_CERT_INVALID = 2 37 | GNUTLS_CERT_REQUEST = 1 38 | GNUTLS_CERT_REQUIRE = 2 39 | GNUTLS_CERT_REVOKED = 32 40 | GNUTLS_CERT_SIGNER_NOT_CA = 128 41 | GNUTLS_CERT_SIGNER_NOT_FOUND = 64 42 | GNUTLS_CIPHER_3DES_CBC = 3 43 | GNUTLS_CIPHER_AES_128_CBC = 4 44 | GNUTLS_CIPHER_AES_256_CBC = 5 45 | GNUTLS_CIPHER_ARCFOUR_128 = 2 46 | GNUTLS_CIPHER_ARCFOUR_40 = 6 47 | GNUTLS_CIPHER_CAMELLIA_128_CBC = 7 48 | GNUTLS_CIPHER_CAMELLIA_256_CBC = 8 49 | GNUTLS_CIPHER_DES_CBC = 91 50 | GNUTLS_CIPHER_NULL = 1 51 | GNUTLS_CIPHER_RC2_40_CBC = 90 52 | GNUTLS_CIPHER_UNKNOWN = 0 53 | GNUTLS_CLIENT = 2 54 | GNUTLS_COMP_DEFLATE = 2 55 | GNUTLS_COMP_NULL = 1 56 | GNUTLS_COMP_UNKNOWN = 0 57 | GNUTLS_CRD_ANON = 2 58 | GNUTLS_CRD_CERTIFICATE = 1 59 | GNUTLS_CRD_IA = 5 60 | GNUTLS_CRD_PSK = 4 61 | GNUTLS_CRD_SRP = 3 62 | GNUTLS_CRL_REASON_AA_COMPROMISE = 32768 # Variable c_int 63 | GNUTLS_CRL_REASON_AFFILIATION_CHANGED = 16 # Variable c_int 64 | GNUTLS_CRL_REASON_CA_COMPROMISE = 32 # Variable c_int 65 | GNUTLS_CRL_REASON_CERTIFICATE_HOLD = 2 # Variable c_int 66 | GNUTLS_CRL_REASON_CESSATION_OF_OPERATION = 4 # Variable c_int 67 | GNUTLS_CRL_REASON_KEY_COMPROMISE = 64 # Variable c_int 68 | GNUTLS_CRL_REASON_PRIVILEGE_WITHDRAWN = 1 # Variable c_int 69 | GNUTLS_CRL_REASON_SUPERSEEDED = 8 # Variable c_int 70 | GNUTLS_CRL_REASON_UNUSED = 128 # Variable c_int 71 | GNUTLS_CRT_OPENPGP = 2 72 | GNUTLS_CRT_PRINT_FULL = 0 73 | GNUTLS_CRT_PRINT_ONELINE = 1 74 | GNUTLS_CRT_PRINT_UNSIGNED_FULL = 2 75 | GNUTLS_CRT_UNKNOWN = 0 76 | GNUTLS_CRT_X509 = 1 77 | GNUTLS_DIG_MD2 = 5 78 | GNUTLS_DIG_MD5 = 2 79 | GNUTLS_DIG_NULL = 1 80 | GNUTLS_DIG_RMD160 = 4 81 | GNUTLS_DIG_SHA1 = 3 82 | GNUTLS_DIG_SHA224 = 9 83 | GNUTLS_DIG_SHA256 = 6 84 | GNUTLS_DIG_SHA384 = 7 85 | GNUTLS_DIG_SHA512 = 8 86 | GNUTLS_E_AGAIN = -28 # Variable c_int 87 | GNUTLS_E_APPLICATION_ERROR_MAX = -65000 # Variable c_int 88 | GNUTLS_E_APPLICATION_ERROR_MIN = -65500 # Variable c_int 89 | GNUTLS_E_ASN1_DER_ERROR = -69 # Variable c_int 90 | GNUTLS_E_ASN1_DER_OVERFLOW = -77 # Variable c_int 91 | GNUTLS_E_ASN1_ELEMENT_NOT_FOUND = -67 # Variable c_int 92 | GNUTLS_E_ASN1_GENERIC_ERROR = -71 # Variable c_int 93 | GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND = -68 # Variable c_int 94 | GNUTLS_E_ASN1_SYNTAX_ERROR = -76 # Variable c_int 95 | GNUTLS_E_ASN1_TAG_ERROR = -73 # Variable c_int 96 | GNUTLS_E_ASN1_TAG_IMPLICIT = -74 # Variable c_int 97 | GNUTLS_E_ASN1_TYPE_ANY_ERROR = -75 # Variable c_int 98 | GNUTLS_E_ASN1_VALUE_NOT_FOUND = -70 # Variable c_int 99 | GNUTLS_E_ASN1_VALUE_NOT_VALID = -72 # Variable c_int 100 | GNUTLS_E_BASE64_DECODING_ERROR = -34 # Variable c_int 101 | GNUTLS_E_BASE64_ENCODING_ERROR = -201 # Variable c_int 102 | GNUTLS_E_BASE64_UNEXPECTED_HEADER_ERROR = -207 # Variable c_int 103 | GNUTLS_E_CERTIFICATE_ERROR = -43 # Variable c_int 104 | GNUTLS_E_CERTIFICATE_KEY_MISMATCH = -60 # Variable c_int 105 | GNUTLS_E_COMPRESSION_FAILED = -27 # Variable c_int 106 | GNUTLS_E_CONSTRAINT_ERROR = -101 # Variable c_int 107 | GNUTLS_E_CRYPTO_ALREADY_REGISTERED = -209 # Variable c_int 108 | GNUTLS_E_DB_ERROR = -30 # Variable c_int 109 | GNUTLS_E_DECOMPRESSION_FAILED = -26 # Variable c_int 110 | GNUTLS_E_DECRYPTION_FAILED = -24 # Variable c_int 111 | GNUTLS_E_DH_PRIME_UNACCEPTABLE = -63 # Variable c_int 112 | GNUTLS_E_ENCRYPTION_FAILED = -40 # Variable c_int 113 | GNUTLS_E_ERROR_IN_FINISHED_PACKET = -18 # Variable c_int 114 | GNUTLS_E_EXPIRED = -29 # Variable c_int 115 | GNUTLS_E_FATAL_ALERT_RECEIVED = -12 # Variable c_int 116 | GNUTLS_E_FILE_ERROR = -64 # Variable c_int 117 | GNUTLS_E_GOT_APPLICATION_DATA = -38 # Variable c_int 118 | GNUTLS_E_HANDSHAKE_TOO_LARGE = -210 # Variable c_int 119 | GNUTLS_E_HASH_FAILED = -33 # Variable c_int 120 | GNUTLS_E_IA_VERIFY_FAILED = -104 # Variable c_int 121 | GNUTLS_E_ILLEGAL_SRP_USERNAME = -90 # Variable c_int 122 | GNUTLS_E_INCOMPATIBLE_CRYPTO_LIBRARY = -202 # Variable c_int 123 | GNUTLS_E_INCOMPATIBLE_GCRYPT_LIBRARY = -202 # Variable c_int 124 | GNUTLS_E_INCOMPATIBLE_LIBTASN1_LIBRARY = -203 # Variable c_int 125 | GNUTLS_E_INIT_LIBEXTRA = -82 # Variable c_int 126 | GNUTLS_E_INSUFFICIENT_CREDENTIALS = -32 # Variable c_int 127 | GNUTLS_E_INTERNAL_ERROR = -59 # Variable c_int 128 | GNUTLS_E_INTERRUPTED = -52 # Variable c_int 129 | GNUTLS_E_INVALID_PASSWORD = -99 # Variable c_int 130 | GNUTLS_E_INVALID_REQUEST = -50 # Variable c_int 131 | GNUTLS_E_INVALID_SESSION = -10 # Variable c_int 132 | GNUTLS_E_KEY_USAGE_VIOLATION = -48 # Variable c_int 133 | GNUTLS_E_LARGE_PACKET = -7 # Variable c_int 134 | GNUTLS_E_LIBRARY_VERSION_MISMATCH = -83 # Variable c_int 135 | GNUTLS_E_MAC_VERIFY_FAILED = -100 # Variable c_int 136 | GNUTLS_E_MEMORY_ERROR = -25 # Variable c_int 137 | GNUTLS_E_MPI_PRINT_FAILED = -35 # Variable c_int 138 | GNUTLS_E_MPI_SCAN_FAILED = -23 # Variable c_int 139 | GNUTLS_E_NO_CERTIFICATE_FOUND = -49 # Variable c_int 140 | GNUTLS_E_NO_CIPHER_SUITES = -87 # Variable c_int 141 | GNUTLS_E_NO_COMPRESSION_ALGORITHMS = -86 # Variable c_int 142 | GNUTLS_E_NO_TEMPORARY_DH_PARAMS = -93 # Variable c_int 143 | GNUTLS_E_NO_TEMPORARY_RSA_PARAMS = -84 # Variable c_int 144 | GNUTLS_E_OPENPGP_FINGERPRINT_UNSUPPORTED = -94 # Variable c_int 145 | GNUTLS_E_OPENPGP_GETKEY_FAILED = -88 # Variable c_int 146 | GNUTLS_E_OPENPGP_KEYRING_ERROR = -204 # Variable c_int 147 | GNUTLS_E_OPENPGP_SUBKEY_ERROR = -208 # Variable c_int 148 | GNUTLS_E_OPENPGP_UID_REVOKED = -79 # Variable c_int 149 | GNUTLS_E_PKCS1_WRONG_PAD = -57 # Variable c_int 150 | GNUTLS_E_PK_DECRYPTION_FAILED = -45 # Variable c_int 151 | GNUTLS_E_PK_ENCRYPTION_FAILED = -44 # Variable c_int 152 | GNUTLS_E_PK_SIGN_FAILED = -46 # Variable c_int 153 | GNUTLS_E_PK_SIG_VERIFY_FAILED = -89 # Variable c_int 154 | GNUTLS_E_PULL_ERROR = -54 # Variable c_int 155 | GNUTLS_E_PUSH_ERROR = -53 # Variable c_int 156 | GNUTLS_E_RANDOM_FAILED = -206 # Variable c_int 157 | GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION = -58 # Variable c_int 158 | GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER = -55 # Variable c_int 159 | GNUTLS_E_RECORD_LIMIT_REACHED = -39 # Variable c_int 160 | GNUTLS_E_REHANDSHAKE = -37 # Variable c_int 161 | GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE = -56 # Variable c_int 162 | GNUTLS_E_SHORT_MEMORY_BUFFER = -51 # Variable c_int 163 | GNUTLS_E_SRP_PWD_ERROR = -31 # Variable c_int 164 | GNUTLS_E_SRP_PWD_PARSING_ERROR = -91 # Variable c_int 165 | GNUTLS_E_SUCCESS = 0 # Variable c_int 166 | GNUTLS_E_TOO_MANY_EMPTY_PACKETS = -78 # Variable c_int 167 | GNUTLS_E_UNEXPECTED_HANDSHAKE_PACKET = -19 # Variable c_int 168 | GNUTLS_E_UNEXPECTED_PACKET = -15 # Variable c_int 169 | GNUTLS_E_UNEXPECTED_PACKET_LENGTH = -9 # Variable c_int 170 | GNUTLS_E_UNIMPLEMENTED_FEATURE = -1250 # Variable c_int 171 | GNUTLS_E_UNKNOWN_ALGORITHM = -105 # Variable c_int 172 | GNUTLS_E_UNKNOWN_CIPHER_SUITE = -21 # Variable c_int 173 | GNUTLS_E_UNKNOWN_CIPHER_TYPE = -6 # Variable c_int 174 | GNUTLS_E_UNKNOWN_COMPRESSION_ALGORITHM = -3 # Variable c_int 175 | GNUTLS_E_UNKNOWN_HASH_ALGORITHM = -96 # Variable c_int 176 | GNUTLS_E_UNKNOWN_PKCS_BAG_TYPE = -98 # Variable c_int 177 | GNUTLS_E_UNKNOWN_PKCS_CONTENT_TYPE = -97 # Variable c_int 178 | GNUTLS_E_UNKNOWN_PK_ALGORITHM = -80 # Variable c_int 179 | GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE = -61 # Variable c_int 180 | GNUTLS_E_UNSUPPORTED_VERSION_PACKET = -8 # Variable c_int 181 | GNUTLS_E_UNWANTED_ALGORITHM = -22 # Variable c_int 182 | GNUTLS_E_WARNING_ALERT_RECEIVED = -16 # Variable c_int 183 | GNUTLS_E_WARNING_IA_FPHF_RECEIVED = -103 # Variable c_int 184 | GNUTLS_E_WARNING_IA_IPHF_RECEIVED = -102 # Variable c_int 185 | GNUTLS_E_X509_UNKNOWN_SAN = -62 # Variable c_int 186 | GNUTLS_E_X509_UNSUPPORTED_ATTRIBUTE = -95 # Variable c_int 187 | GNUTLS_E_X509_UNSUPPORTED_CRITICAL_EXTENSION = -47 # Variable c_int 188 | GNUTLS_E_X509_UNSUPPORTED_OID = -205 # Variable c_int 189 | GNUTLS_HANDSHAKE_CERTIFICATE_PKT = 11 190 | GNUTLS_HANDSHAKE_CERTIFICATE_REQUEST = 13 191 | GNUTLS_HANDSHAKE_CERTIFICATE_VERIFY = 15 192 | GNUTLS_HANDSHAKE_CLIENT_HELLO = 1 193 | GNUTLS_HANDSHAKE_CLIENT_KEY_EXCHANGE = 16 194 | GNUTLS_HANDSHAKE_FINISHED = 20 195 | GNUTLS_HANDSHAKE_HELLO_REQUEST = 0 196 | GNUTLS_HANDSHAKE_SERVER_HELLO = 2 197 | GNUTLS_HANDSHAKE_SERVER_HELLO_DONE = 14 198 | GNUTLS_HANDSHAKE_SERVER_KEY_EXCHANGE = 12 199 | GNUTLS_HANDSHAKE_SUPPLEMENTAL = 23 200 | GNUTLS_IA_APPLICATION_PAYLOAD = 0 201 | GNUTLS_IA_FINAL_PHASE_FINISHED = 2 202 | GNUTLS_IA_INTERMEDIATE_PHASE_FINISHED = 1 203 | GNUTLS_KEY_CRL_SIGN = 2 # Variable c_int 204 | GNUTLS_KEY_DATA_ENCIPHERMENT = 16 # Variable c_int 205 | GNUTLS_KEY_DECIPHER_ONLY = 32768 # Variable c_int 206 | GNUTLS_KEY_DIGITAL_SIGNATURE = 128 # Variable c_int 207 | GNUTLS_KEY_ENCIPHER_ONLY = 1 # Variable c_int 208 | GNUTLS_KEY_KEY_AGREEMENT = 8 # Variable c_int 209 | GNUTLS_KEY_KEY_CERT_SIGN = 4 # Variable c_int 210 | GNUTLS_KEY_KEY_ENCIPHERMENT = 32 # Variable c_int 211 | GNUTLS_KEY_NON_REPUDIATION = 64 # Variable c_int 212 | GNUTLS_KP_ANY = '2.5.29.37.0' # Variable STRING 213 | GNUTLS_KP_CODE_SIGNING = '1.3.6.1.5.5.7.3.3' # Variable STRING 214 | GNUTLS_KP_EMAIL_PROTECTION = '1.3.6.1.5.5.7.3.4' # Variable STRING 215 | GNUTLS_KP_OCSP_SIGNING = '1.3.6.1.5.5.7.3.9' # Variable STRING 216 | GNUTLS_KP_TIME_STAMPING = '1.3.6.1.5.5.7.3.8' # Variable STRING 217 | GNUTLS_KP_TLS_WWW_CLIENT = '1.3.6.1.5.5.7.3.2' # Variable STRING 218 | GNUTLS_KP_TLS_WWW_SERVER = '1.3.6.1.5.5.7.3.1' # Variable STRING 219 | GNUTLS_KX_ANON_DH = 4 220 | GNUTLS_KX_DHE_DSS = 2 221 | GNUTLS_KX_DHE_PSK = 10 222 | GNUTLS_KX_DHE_RSA = 3 223 | GNUTLS_KX_PSK = 9 224 | GNUTLS_KX_RSA = 1 225 | GNUTLS_KX_RSA_EXPORT = 6 226 | GNUTLS_KX_SRP = 5 227 | GNUTLS_KX_SRP_DSS = 8 228 | GNUTLS_KX_SRP_RSA = 7 229 | GNUTLS_KX_UNKNOWN = 0 230 | GNUTLS_MAC_MD2 = 5 231 | GNUTLS_MAC_MD5 = 2 232 | GNUTLS_MAC_NULL = 1 233 | GNUTLS_MAC_RMD160 = 4 234 | GNUTLS_MAC_SHA1 = 3 235 | GNUTLS_MAC_SHA256 = 6 236 | GNUTLS_MAC_SHA384 = 7 237 | GNUTLS_MAC_SHA512 = 8 238 | GNUTLS_MAC_UNKNOWN = 0 239 | GNUTLS_MASTER_SIZE = 48 # Variable c_int 240 | GNUTLS_MAX_ALGORITHM_NUM = 16 # Variable c_int 241 | GNUTLS_MAX_SESSION_ID = 32 # Variable c_int 242 | GNUTLS_NAME_DNS = 1 243 | GNUTLS_OID_LDAP_DC = '0.9.2342.19200300.100.1.25' # Variable STRING 244 | GNUTLS_OID_LDAP_UID = '0.9.2342.19200300.100.1.1' # Variable STRING 245 | GNUTLS_OID_PKCS9_EMAIL = '1.2.840.113549.1.9.1' # Variable STRING 246 | GNUTLS_OID_PKIX_COUNTRY_OF_CITIZENSHIP = '1.3.6.1.5.5.7.9.4' # Variable STRING 247 | GNUTLS_OID_PKIX_COUNTRY_OF_RESIDENCE = '1.3.6.1.5.5.7.9.5' # Variable STRING 248 | GNUTLS_OID_PKIX_DATE_OF_BIRTH = '1.3.6.1.5.5.7.9.1' # Variable STRING 249 | GNUTLS_OID_PKIX_GENDER = '1.3.6.1.5.5.7.9.3' # Variable STRING 250 | GNUTLS_OID_PKIX_PLACE_OF_BIRTH = '1.3.6.1.5.5.7.9.2' # Variable STRING 251 | GNUTLS_OID_X520_COMMON_NAME = '2.5.4.3' # Variable STRING 252 | GNUTLS_OID_X520_COUNTRY_NAME = '2.5.4.6' # Variable STRING 253 | GNUTLS_OID_X520_DN_QUALIFIER = '2.5.4.46' # Variable STRING 254 | GNUTLS_OID_X520_GENERATION_QUALIFIER = '2.5.4.44' # Variable STRING 255 | GNUTLS_OID_X520_GIVEN_NAME = '2.5.4.42' # Variable STRING 256 | GNUTLS_OID_X520_INITIALS = '2.5.4.43' # Variable STRING 257 | GNUTLS_OID_X520_LOCALITY_NAME = '2.5.4.7' # Variable STRING 258 | GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME = '2.5.4.11' # Variable STRING 259 | GNUTLS_OID_X520_ORGANIZATION_NAME = '2.5.4.10' # Variable STRING 260 | GNUTLS_OID_X520_PSEUDONYM = '2.5.4.65' # Variable STRING 261 | GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME = '2.5.4.8' # Variable STRING 262 | GNUTLS_OID_X520_SURNAME = '2.5.4.4' # Variable STRING 263 | GNUTLS_OID_X520_TITLE = '2.5.4.12' # Variable STRING 264 | GNUTLS_OPENPGP_CERT = 0 265 | GNUTLS_OPENPGP_CERT_FINGERPRINT = 1 266 | GNUTLS_OPENPGP_FMT_BASE64 = 1 267 | GNUTLS_OPENPGP_FMT_RAW = 0 268 | GNUTLS_PARAMS_DH = 2 269 | GNUTLS_PARAMS_RSA_EXPORT = 1 270 | GNUTLS_PKCS_PLAIN = 1 271 | GNUTLS_PKCS_USE_PBES2_3DES = 16 272 | GNUTLS_PKCS_USE_PKCS12_3DES = 2 273 | GNUTLS_PKCS_USE_PKCS12_ARCFOUR = 4 274 | GNUTLS_PKCS_USE_PKCS12_RC2_40 = 8 275 | GNUTLS_PK_DSA = 2 276 | GNUTLS_PK_RSA = 1 277 | GNUTLS_PK_UNKNOWN = 0 278 | GNUTLS_PSK_KEY_HEX = 1 279 | GNUTLS_PSK_KEY_RAW = 0 280 | GNUTLS_RANDOM_SIZE = 32 # Variable c_int 281 | GNUTLS_SAN_DN = 6 282 | GNUTLS_SAN_DNSNAME = 1 283 | GNUTLS_SAN_IPADDRESS = 4 284 | GNUTLS_SAN_OTHERNAME = 5 285 | GNUTLS_SAN_OTHERNAME_XMPP = 1000 286 | GNUTLS_SAN_RFC822NAME = 2 287 | GNUTLS_SAN_URI = 3 288 | GNUTLS_SERVER = 1 289 | GNUTLS_SHUT_RDWR = 0 290 | GNUTLS_SHUT_WR = 1 291 | GNUTLS_SIGN_DSA_SHA1 = 2 292 | GNUTLS_SIGN_RSA_MD2 = 4 293 | GNUTLS_SIGN_RSA_MD5 = 3 294 | GNUTLS_SIGN_RSA_RMD160 = 5 295 | GNUTLS_SIGN_RSA_SHA1 = 1 296 | GNUTLS_SIGN_RSA_SHA224 = 9 297 | GNUTLS_SIGN_RSA_SHA256 = 6 298 | GNUTLS_SIGN_RSA_SHA384 = 7 299 | GNUTLS_SIGN_RSA_SHA512 = 8 300 | GNUTLS_SIGN_UNKNOWN = 0 301 | GNUTLS_SUPPLEMENTAL_USER_MAPPING_DATA = 0 302 | GNUTLS_SSL3 = 1 303 | GNUTLS_TLS1_0 = 2 304 | GNUTLS_TLS1_1 = 3 305 | GNUTLS_TLS1_2 = 4 306 | GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_CRT = 8 307 | GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2 = 16 308 | GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5 = 32 309 | GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT = 2 310 | GNUTLS_VERIFY_DISABLE_CA_SIGN = 1 311 | GNUTLS_VERIFY_DO_NOT_ALLOW_SAME = 4 312 | GNUTLS_VERSION_UNKNOWN = 255 313 | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED = 1 314 | GNUTLS_X509_FMT_DER = 0 315 | GNUTLS_X509_FMT_PEM = 1 316 | 317 | __all__ = sorted(name for name in dir() if name.startswith('GNUTLS_')) 318 | 319 | -------------------------------------------------------------------------------- /gnutls/library/errors.py: -------------------------------------------------------------------------------- 1 | 2 | """GNUTLS library errors""" 3 | 4 | from gnutls.errors import * 5 | from gnutls.errors import __all__ 6 | 7 | from gnutls.library.constants import GNUTLS_E_AGAIN, GNUTLS_E_INTERRUPTED, GNUTLS_E_NO_CERTIFICATE_FOUND 8 | from gnutls.library.constants import GNUTLS_E_MEMORY_ERROR, GNUTLS_E_SHORT_MEMORY_BUFFER 9 | from gnutls.library.constants import GNUTLS_E_FATAL_ALERT_RECEIVED, GNUTLS_A_BAD_CERTIFICATE 10 | from gnutls.library.constants import GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE 11 | from gnutls.library.constants import GNUTLS_A_UNKNOWN_CA, GNUTLS_A_INSUFFICIENT_SECURITY 12 | from gnutls.library.constants import GNUTLS_A_CERTIFICATE_EXPIRED, GNUTLS_A_CERTIFICATE_REVOKED 13 | from gnutls.library.functions import gnutls_strerror, gnutls_alert_get 14 | 15 | class ErrorMessage(str): 16 | def __new__(cls, code): 17 | obj = str.__new__(cls, gnutls_strerror(code)) 18 | obj.code = code 19 | return obj 20 | 21 | # Check functions which return an integer status code (negative codes being errors) 22 | # 23 | class ErrorHandler(object): 24 | alert_map = { 25 | GNUTLS_A_BAD_CERTIFICATE : CertificateError("peer rejected our certificate as invalid"), 26 | GNUTLS_A_UNKNOWN_CA : CertificateAuthorityError("peer does not trust our certificate authority"), 27 | GNUTLS_A_INSUFFICIENT_SECURITY : CertificateSecurityError("peer rejected us on insufficient security"), 28 | GNUTLS_A_CERTIFICATE_EXPIRED : CertificateExpiredError("peer rejected our certificate as expired"), 29 | GNUTLS_A_CERTIFICATE_REVOKED : CertificateRevokedError("peer rejected our certificate as revoked") 30 | } 31 | 32 | @classmethod 33 | def check_status(cls, retcode, function, args): 34 | if retcode >= 0: 35 | return retcode 36 | elif retcode == -1: 37 | raise GNUTLSError(getattr(function, 'errmsg', None) or ErrorMessage(retcode)) 38 | elif retcode == GNUTLS_E_AGAIN: 39 | raise OperationWouldBlock(gnutls_strerror(retcode)) 40 | elif retcode == GNUTLS_E_INTERRUPTED: 41 | raise OperationInterrupted(gnutls_strerror(retcode)) 42 | elif retcode in (GNUTLS_E_MEMORY_ERROR, GNUTLS_E_SHORT_MEMORY_BUFFER): 43 | raise MemoryError(ErrorMessage(retcode)) 44 | elif retcode == GNUTLS_E_NO_CERTIFICATE_FOUND: 45 | raise CertificateSecurityError(gnutls_strerror(retcode)) 46 | elif retcode == GNUTLS_E_FATAL_ALERT_RECEIVED: 47 | exception = cls.alert_map.get(gnutls_alert_get(args[0])) 48 | raise exception and exception.__class__(*exception.args) or GNUTLSError(ErrorMessage(retcode)) 49 | elif retcode == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE: 50 | raise RequestedDataNotAvailable(gnutls_strerror(retcode)) 51 | else: 52 | raise GNUTLSError(ErrorMessage(retcode)) 53 | 54 | 55 | # Attach the error checking function to all functions returning integers 56 | # 57 | from gnutls.library import functions 58 | from ctypes import c_int, c_long 59 | 60 | for func in (obj for name, obj in functions.__dict__.iteritems() if name in functions.__all__ and obj.restype in (c_int, c_long)): 61 | func.errcheck = ErrorHandler.check_status 62 | 63 | del c_int, c_long, func, functions 64 | 65 | -------------------------------------------------------------------------------- /gnutls/library/types.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | from ctypes import * 4 | 5 | # Type aliases 6 | # 7 | 8 | time_t = c_long 9 | size_t = c_size_t 10 | ssize_t = c_long 11 | 12 | gnutls_openpgp_keyid_t = c_ubyte * 8 13 | gnutls_transport_ptr_t = c_void_p 14 | gnutls_x509_dn_t = c_void_p 15 | 16 | 17 | # Enumerations 18 | # 19 | 20 | gnutls_alert_description_t = c_int # enum 21 | gnutls_alert_level_t = c_int # enum 22 | gnutls_certificate_import_flags = c_int # enum 23 | gnutls_certificate_print_formats = c_int # enum 24 | gnutls_certificate_request_t = c_int # enum 25 | gnutls_certificate_status_t = c_int # enum 26 | gnutls_certificate_type_t = c_int # enum 27 | gnutls_certificate_verify_flags = c_int # enum 28 | gnutls_cipher_algorithm_t = c_int # enum 29 | gnutls_close_request_t = c_int # enum 30 | gnutls_compression_method_t = c_int # enum 31 | gnutls_connection_end_t = c_int # enum 32 | gnutls_credentials_type_t = c_int # enum 33 | gnutls_digest_algorithm_t = c_int # enum 34 | gnutls_handshake_description_t = c_int # enum 35 | gnutls_ia_apptype_t = c_int # enum 36 | gnutls_kx_algorithm_t = c_int # enum 37 | gnutls_mac_algorithm_t = c_int # enum 38 | gnutls_openpgp_crt_fmt = c_int # enum 39 | gnutls_openpgp_crt_status_t = c_int # enum 40 | gnutls_params_type_t = c_int # enum 41 | gnutls_pk_algorithm_t = c_int # enum 42 | gnutls_pkcs_encrypt_flags_t = c_int # enum 43 | gnutls_privkey_type_t = c_int # enum 44 | gnutls_protocol_t = c_int # enum 45 | gnutls_psk_key_flags = c_int # enum 46 | gnutls_server_name_type_t = c_int # enum 47 | gnutls_sign_algorithm_t = c_int # enum 48 | gnutls_supplemental_data_format_type_t = c_int # enum 49 | gnutls_x509_crt_fmt_t = c_int # enum 50 | gnutls_x509_subject_alt_name_t = c_int # enum 51 | 52 | gnutls_certificate_print_formats_t = gnutls_certificate_print_formats 53 | gnutls_openpgp_crt_fmt_t = gnutls_openpgp_crt_fmt 54 | 55 | 56 | # Unions, structures and pointers to structure types 57 | # 58 | 59 | class gnutls_session_int(Structure): 60 | _fields_ = [] 61 | gnutls_session_t = POINTER(gnutls_session_int) 62 | 63 | class gnutls_ia_server_credentials_st(Structure): 64 | _fields_ = [] 65 | gnutls_ia_server_credentials_t = POINTER(gnutls_ia_server_credentials_st) 66 | 67 | class gnutls_ia_client_credentials_st(Structure): 68 | _fields_ = [] 69 | gnutls_ia_client_credentials_t = POINTER(gnutls_ia_client_credentials_st) 70 | 71 | class gnutls_dh_params_int(Structure): 72 | _fields_ = [] 73 | gnutls_dh_params_t = POINTER(gnutls_dh_params_int) 74 | 75 | class gnutls_x509_privkey_int(Structure): 76 | _fields_ = [] 77 | gnutls_x509_privkey_t = POINTER(gnutls_x509_privkey_int) 78 | gnutls_rsa_params_t = POINTER(gnutls_x509_privkey_int) 79 | 80 | class params(Union): 81 | _fields_ = [('dh', gnutls_dh_params_t), 82 | ('rsa_export', gnutls_rsa_params_t)] 83 | 84 | class gnutls_pkcs11_privkey_st(Structure): 85 | _fields_ = [] 86 | gnutls_pkcs11_privkey_t = POINTER(gnutls_pkcs11_privkey_st) 87 | 88 | class gnutls_priority_st(Structure): 89 | _fields_ = [] 90 | gnutls_priority_t = POINTER(gnutls_priority_st) 91 | 92 | class gnutls_datum_t(Structure): 93 | _fields_ = [('data', POINTER(c_ubyte)), 94 | ('size', c_uint)] 95 | 96 | class gnutls_params_st(Structure): 97 | _fields_ = [('type', gnutls_params_type_t), 98 | ('params', params), 99 | ('deinit', c_int)] 100 | 101 | class gnutls_certificate_credentials_st(Structure): 102 | _fields_ = [] 103 | gnutls_certificate_credentials_t = POINTER(gnutls_certificate_credentials_st) 104 | gnutls_certificate_server_credentials = gnutls_certificate_credentials_t 105 | gnutls_certificate_client_credentials = gnutls_certificate_credentials_t 106 | 107 | class gnutls_anon_server_credentials_st(Structure): 108 | _fields_ = [] 109 | gnutls_anon_server_credentials_t = POINTER(gnutls_anon_server_credentials_st) 110 | 111 | class gnutls_anon_client_credentials_st(Structure): 112 | _fields_ = [] 113 | gnutls_anon_client_credentials_t = POINTER(gnutls_anon_client_credentials_st) 114 | 115 | class gnutls_x509_crl_int(Structure): 116 | _fields_ = [] 117 | gnutls_x509_crl_t = POINTER(gnutls_x509_crl_int) 118 | 119 | class gnutls_x509_crt_int(Structure): 120 | _fields_ = [] 121 | gnutls_x509_crt_t = POINTER(gnutls_x509_crt_int) 122 | 123 | class gnutls_openpgp_keyring_int(Structure): 124 | _fields_ = [] 125 | gnutls_openpgp_keyring_t = POINTER(gnutls_openpgp_keyring_int) 126 | 127 | class gnutls_srp_server_credentials_st(Structure): 128 | _fields_ = [] 129 | gnutls_srp_server_credentials_t = POINTER(gnutls_srp_server_credentials_st) 130 | 131 | class gnutls_srp_client_credentials_st(Structure): 132 | _fields_ = [] 133 | gnutls_srp_client_credentials_t = POINTER(gnutls_srp_client_credentials_st) 134 | 135 | class gnutls_psk_server_credentials_st(Structure): 136 | _fields_ = [] 137 | gnutls_psk_server_credentials_t = POINTER(gnutls_psk_server_credentials_st) 138 | 139 | class gnutls_psk_client_credentials_st(Structure): 140 | _fields_ = [] 141 | gnutls_psk_client_credentials_t = POINTER(gnutls_psk_client_credentials_st) 142 | 143 | class gnutls_openpgp_crt_int(Structure): 144 | _fields_ = [] 145 | gnutls_openpgp_crt_t = POINTER(gnutls_openpgp_crt_int) 146 | 147 | class gnutls_openpgp_privkey_int(Structure): 148 | _fields_ = [] 149 | gnutls_openpgp_privkey_t = POINTER(gnutls_openpgp_privkey_int) 150 | 151 | class cert(Union): 152 | _fields_ = [('x509', POINTER(gnutls_x509_crt_t)), 153 | ('pgp', gnutls_openpgp_crt_t)] 154 | 155 | class key(Union): 156 | _fields_ = [('x509', gnutls_x509_privkey_t), 157 | ('pgp', gnutls_openpgp_privkey_t), 158 | ('pkcs11', gnutls_pkcs11_privkey_t)] 159 | 160 | class gnutls_retr2_st(Structure): 161 | _fields_ = [('cert_type', gnutls_certificate_type_t), 162 | ('key_type', gnutls_privkey_type_t), 163 | ('cert', cert), 164 | ('ncerts', c_uint), 165 | ('key', key), 166 | ('deinit_all', c_uint)] 167 | 168 | class gnutls_x509_ava_st(Structure): 169 | _fields_ = [('oid', gnutls_datum_t), 170 | ('value', gnutls_datum_t), 171 | ('value_tag', c_ulong)] 172 | 173 | class gnutls_pkcs7_int(Structure): 174 | _fields_ = [] 175 | gnutls_pkcs7_t = POINTER(gnutls_pkcs7_int) 176 | 177 | class gnutls_x509_crq_int(Structure): 178 | _fields_ = [] 179 | gnutls_x509_crq_t = POINTER(gnutls_x509_crq_int) 180 | 181 | 182 | # Function type declarations 183 | # 184 | 185 | gnutls_alloc_function = CFUNCTYPE(c_void_p, size_t) 186 | gnutls_calloc_function = CFUNCTYPE(c_void_p, size_t, size_t) 187 | gnutls_certificate_retrieve_function = CFUNCTYPE(c_int, gnutls_session_t, POINTER(gnutls_datum_t), c_int, POINTER(gnutls_pk_algorithm_t), c_int, POINTER(gnutls_retr2_st)) 188 | gnutls_db_remove_func = CFUNCTYPE(c_int, c_void_p, gnutls_datum_t) 189 | gnutls_db_retr_func = CFUNCTYPE(gnutls_datum_t, c_void_p, gnutls_datum_t) 190 | gnutls_db_store_func = CFUNCTYPE(c_int, c_void_p, gnutls_datum_t, gnutls_datum_t) 191 | gnutls_free_function = CFUNCTYPE(None, c_void_p) 192 | gnutls_handshake_post_client_hello_func = CFUNCTYPE(c_int, gnutls_session_t) 193 | gnutls_ia_avp_func = CFUNCTYPE(c_int, gnutls_session_t, c_void_p, c_char_p, size_t, POINTER(c_char_p), POINTER(size_t)) 194 | gnutls_is_secure_function = CFUNCTYPE(c_int, c_void_p) 195 | gnutls_log_func = CFUNCTYPE(None, c_int, c_char_p) 196 | gnutls_openpgp_recv_key_func = CFUNCTYPE(c_int, gnutls_session_t, POINTER(c_ubyte), c_uint, POINTER(gnutls_datum_t)) 197 | gnutls_oprfi_callback_func = CFUNCTYPE(c_int, gnutls_session_t, c_void_p, size_t, POINTER(c_ubyte), POINTER(c_ubyte)) 198 | gnutls_params_function = CFUNCTYPE(c_int, gnutls_session_t, gnutls_params_type_t, POINTER(gnutls_params_st)) 199 | gnutls_psk_client_credentials_function = CFUNCTYPE(c_int, gnutls_session_t, POINTER(c_char_p), POINTER(gnutls_datum_t)) 200 | gnutls_psk_server_credentials_function = CFUNCTYPE(c_int, gnutls_session_t, c_char_p, POINTER(gnutls_datum_t)) 201 | gnutls_pull_func = CFUNCTYPE(ssize_t, gnutls_transport_ptr_t, c_void_p, size_t) 202 | gnutls_push_func = CFUNCTYPE(ssize_t, gnutls_transport_ptr_t, c_void_p, size_t) 203 | gnutls_realloc_function = CFUNCTYPE(c_void_p, c_void_p, size_t) 204 | gnutls_sign_func = CFUNCTYPE(c_int, gnutls_session_t, c_void_p, gnutls_certificate_type_t, POINTER(gnutls_datum_t), POINTER(gnutls_datum_t), POINTER(gnutls_datum_t)) 205 | gnutls_srp_client_credentials_function = CFUNCTYPE(c_int, gnutls_session_t, POINTER(c_char_p), POINTER(c_char_p)) 206 | gnutls_srp_server_credentials_function = CFUNCTYPE(c_int, gnutls_session_t, c_char_p, POINTER(gnutls_datum_t), POINTER(gnutls_datum_t), POINTER(gnutls_datum_t), POINTER(gnutls_datum_t)) 207 | 208 | 209 | __all__ = sorted(name for name in sys.modules[__name__].__dict__ if name.startswith('gnutls_') or name in ('size_t', 'ssize_t', 'time_t', 'cert', 'key', 'params')) 210 | 211 | -------------------------------------------------------------------------------- /gnutls/validators.py: -------------------------------------------------------------------------------- 1 | 2 | """GNUTLS data validators""" 3 | 4 | __all__ = ['function_args', 'method_args', 'none', 'ignore', 'list_of', 'one_of'] 5 | 6 | 7 | # Helper functions (internal use) 8 | # 9 | 10 | def isclass(obj): 11 | return hasattr(obj, '__bases__') or isinstance(obj, type) 12 | 13 | # Internal validator classes 14 | # 15 | 16 | class Validator(object): 17 | _registered = [] 18 | def __init__(self, typ): 19 | self.type = typ 20 | def check(self, value): 21 | return False 22 | @staticmethod 23 | def can_validate(typ): 24 | return False 25 | @classmethod 26 | def register(cls, validator): 27 | cls._registered.append(validator) 28 | @classmethod 29 | def get(cls, typ): 30 | for validator in cls._registered: 31 | if validator.can_validate(typ): 32 | return validator(typ) 33 | else: 34 | return None 35 | @staticmethod 36 | def join_names(names): 37 | if type(names) in (tuple, list): 38 | if len(names) <= 2: 39 | return ' or '.join(names) 40 | else: 41 | return ' or '.join((', '.join(names[:-1]), names[-1])) 42 | else: 43 | return names 44 | def _type_names(self): 45 | if isinstance(self.type, tuple): 46 | return self.join_names([t.__name__.replace('NoneType', 'None') for t in self.type]) 47 | else: 48 | return self.type.__name__.replace('NoneType', 'None') 49 | @property 50 | def name(self): 51 | name = self._type_names() 52 | if name.startswith('None'): 53 | prefix = '' 54 | elif name[0] in ('a', 'e', 'i', 'o', 'u'): 55 | prefix = 'an ' 56 | else: 57 | prefix = 'a ' 58 | return prefix + name 59 | 60 | class IgnoringValidator(Validator): 61 | def __init__(self, typ): 62 | self.type = none 63 | def check(self, value): 64 | return True 65 | @staticmethod 66 | def can_validate(obj): 67 | return obj is ignore 68 | 69 | class TypeValidator(Validator): 70 | def check(self, value): 71 | return isinstance(value, self.type) 72 | @staticmethod 73 | def can_validate(obj): 74 | return isclass(obj) 75 | 76 | class MultiTypeValidator(TypeValidator): 77 | @staticmethod 78 | def can_validate(obj): 79 | return isinstance(obj, tuple) and not filter(lambda x: not isclass(x), obj) 80 | 81 | class OneOfValidator(Validator): 82 | def __init__(self, typ): 83 | self.type = typ.type 84 | def check(self, value): 85 | return value in self.type 86 | @staticmethod 87 | def can_validate(obj): 88 | return isinstance(obj, one_of) 89 | @property 90 | def name(self): 91 | return 'one of %s' % self.join_names(["`%r'" % e for e in self.type]) 92 | 93 | class ListOfValidator(Validator): 94 | def __init__(self, typ): 95 | self.type = typ.type 96 | def check(self, value): 97 | return isinstance(value, (tuple, list)) and not filter(lambda x: not isinstance(x, self.type), value) 98 | @staticmethod 99 | def can_validate(obj): 100 | return isinstance(obj, list_of) 101 | @property 102 | def name(self): 103 | return 'a list of %s' % self._type_names() 104 | 105 | class ComplexValidator(Validator): 106 | def __init__(self, typ): 107 | self.type = [Validator.get(x) for x in typ] 108 | def check(self, value): 109 | return bool(sum(t.check(value) for t in self.type)) 110 | @staticmethod 111 | def can_validate(obj): 112 | return isinstance(obj, tuple) and not filter(lambda x: Validator.get(x) is None, obj) 113 | @property 114 | def name(self): 115 | return self.join_names([x.name for x in self.type]) 116 | 117 | Validator.register(IgnoringValidator) 118 | Validator.register(TypeValidator) 119 | Validator.register(MultiTypeValidator) 120 | Validator.register(OneOfValidator) 121 | Validator.register(ListOfValidator) 122 | Validator.register(ComplexValidator) 123 | 124 | 125 | # Extra types to be used with argument validating decorators 126 | # 127 | 128 | none = type(None) 129 | 130 | class one_of(object): 131 | def __init__(self, *args): 132 | if len(args) < 2: 133 | raise ValueError("one_of must have at least 2 arguments") 134 | self.type = args 135 | 136 | class list_of(object): 137 | def __init__(self, *args): 138 | if filter(lambda x: not isclass(x), args): 139 | raise TypeError("list_of arguments must be types") 140 | if len(args) == 1: 141 | self.type = args[0] 142 | else: 143 | self.type = args 144 | 145 | ignore = type('ignore', (), {})() 146 | 147 | 148 | # Helpers for writing well behaved decorators 149 | # 150 | 151 | def decorator(func): 152 | """A syntactic marker with no other effect than improving readability.""" 153 | return func 154 | 155 | def preserve_signature(func): 156 | """Preserve the original function signature and attributes in decorator wrappers.""" 157 | from inspect import getargspec, formatargspec 158 | from gnutls.constants import GNUTLSConstant 159 | constants = [c for c in (getargspec(func)[3] or []) if isinstance(c, GNUTLSConstant)] 160 | signature = formatargspec(*getargspec(func))[1:-1] 161 | parameters = formatargspec(*getargspec(func), **{'formatvalue': lambda value: ""})[1:-1] 162 | def fix_signature(wrapper): 163 | if constants: 164 | ## import the required GNUTLSConstants used as function default arguments 165 | code = "from gnutls.constants import %s\n" % ', '.join(c.name for c in constants) 166 | exec code in locals(), locals() 167 | code = "def %s(%s): return wrapper(%s)\nnew_wrapper = %s\n" % (func.__name__, signature, parameters, func.__name__) 168 | exec code in locals(), locals() 169 | new_wrapper.__name__ = func.__name__ 170 | new_wrapper.__doc__ = func.__doc__ 171 | new_wrapper.__module__ = func.__module__ 172 | new_wrapper.__dict__.update(func.__dict__) 173 | return new_wrapper 174 | return fix_signature 175 | 176 | # Argument validating decorators 177 | # 178 | 179 | def _callable_args(*args, **kwargs): 180 | """Internal function used by argument checking decorators""" 181 | start = kwargs.get('_start', 0) 182 | validators = [] 183 | for i, arg in enumerate(args): 184 | validator = Validator.get(arg) 185 | if validator is None: 186 | raise TypeError("unsupported type `%r' at position %d for argument checking decorator" % (arg, i+1)) 187 | validators.append(validator) 188 | def check_args_decorator(func): 189 | @preserve_signature(func) 190 | def check_args(*func_args): 191 | pos = start 192 | for validator in validators: 193 | if not validator.check(func_args[pos]): 194 | raise TypeError("argument %d must be %s" % (pos+1-start, validator.name)) 195 | pos += 1 196 | return func(*func_args) 197 | return check_args 198 | return check_args_decorator 199 | 200 | @decorator 201 | def method_args(*args): 202 | """Check class or instance method arguments""" 203 | return _callable_args(*args, **{'_start': 1}) 204 | 205 | @decorator 206 | def function_args(*args): 207 | """Check functions or staticmethod arguments""" 208 | return _callable_args(*args) 209 | 210 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | import os 4 | 5 | from distutils.core import setup 6 | from gnutls import __info__ as package_info 7 | 8 | 9 | def find_packages(toplevel): 10 | return [directory.replace(os.path.sep, '.') for directory, subdirs, files in os.walk(toplevel) if '__init__.py' in files] 11 | 12 | 13 | setup( 14 | name=package_info.__project__, 15 | version=package_info.__version__, 16 | 17 | description=package_info.__summary__, 18 | long_description=open('README').read(), 19 | license=package_info.__license__, 20 | url=package_info.__webpage__, 21 | 22 | author=package_info.__author__, 23 | author_email=package_info.__email__, 24 | 25 | platforms=["Platform Independent"], 26 | classifiers=[ 27 | "Development Status :: 5 - Production/Stable", 28 | "Intended Audience :: Developers", 29 | "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", 30 | "Operating System :: OS Independent", 31 | "Programming Language :: Python", 32 | "Topic :: Software Development :: Libraries :: Python Modules" 33 | ], 34 | 35 | packages=find_packages('gnutls') 36 | ) 37 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: gnutls-client 3 | 4 | gnutls-client: gnutls-client.c 5 | gcc -Wall -O2 -g `get-wutil-flags --cflags` -o gnutls-client gnutls-client.c `get-wutil-flags --ldflags --libs` -lgnutls 6 | 7 | clean: 8 | -rm -rf gnutls-client *.o *~ *.pyc *.pyo 9 | -------------------------------------------------------------------------------- /test/gnutls-client.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Asynchronous gnutls test client, with X.509 authentication. 3 | * Uses the WUtil library for connecting on the TCP level. 4 | * 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | 19 | #define TRIES 100 20 | 21 | #define KEYFILE "../examples/certs/valid.key" 22 | #define CERTFILE "../examples/certs/valid.crt" 23 | #define CAFILE "../examples/certs/ca.pem" 24 | 25 | 26 | 27 | static int active = TRIES; 28 | static int succesful = 0; 29 | static int failed = 0; 30 | 31 | static Bool verify_peer = False; 32 | 33 | static int verbose = 0; 34 | 35 | static struct timeval start={0, 0}, end={0, 0}; 36 | 37 | typedef struct TLSSession { 38 | gnutls_session_t session; /* the TLS session */ 39 | Bool handshakeDone; /* the TLS handshake was completed */ 40 | Bool doingBye; /* processing the TLS bye handshake */ 41 | } TLSSession; 42 | 43 | static TLSSession tlsSession[TRIES]; 44 | static ConnectionDelegate socketDelegate[TRIES]; 45 | 46 | static void didReceiveInput(ConnectionDelegate *self, WMConnection *cPtr); 47 | 48 | static void connectionDidDie(ConnectionDelegate *self, WMConnection *cPtr); 49 | 50 | static void didInitialize(ConnectionDelegate *self, WMConnection *cPtr); 51 | 52 | 53 | void 54 | my_exit(void) 55 | { 56 | double seconds; 57 | 58 | gettimeofday(&end, NULL); 59 | seconds = (end.tv_sec + (double)end.tv_usec/1000000.0 60 | - start.tv_sec - (double)start.tv_usec/1000000.0); 61 | printf("%.2f seconds; %.2f requests/sec; GNUTLS C async client\n", 62 | seconds, TRIES/seconds); 63 | 64 | if (failed) { 65 | printf("%d out of %d connection have failed\n", failed, TRIES); 66 | } 67 | 68 | exit(0); 69 | } 70 | 71 | 72 | void 73 | wAbort(Bool foo) 74 | { 75 | exit(1); 76 | } 77 | 78 | 79 | static Bool 80 | verifyPeerCertificate(gnutls_session_t session, char **reason) 81 | { 82 | char buffer[1024], *dummy; 83 | unsigned int status; 84 | int res; 85 | 86 | if (!verify_peer) 87 | return True; 88 | 89 | if (reason==NULL) 90 | reason = &dummy; 91 | 92 | res = gnutls_certificate_verify_peers2(session, &status); 93 | if (res < 0) { 94 | snprintf(buffer, 1024, "Couldn't verify certificate: %d, %s", res, 95 | gnutls_strerror(res)); 96 | *reason = buffer; 97 | return False; 98 | } else { 99 | if (status & GNUTLS_CERT_INVALID) { 100 | *reason = "Certificate is invalid"; 101 | return False; 102 | } else if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) { 103 | *reason = "Signer not found"; 104 | return False; 105 | } else if (status & GNUTLS_CERT_REVOKED) { 106 | *reason = "Certificate is revoked"; 107 | return False; 108 | } 109 | } 110 | 111 | return True; 112 | } 113 | 114 | 115 | static void 116 | connectionFailed(WMConnection *cPtr, Bool need_close) 117 | { 118 | if (need_close) 119 | WMCloseConnection(cPtr); 120 | active--; 121 | failed++; 122 | if (active == 0) { 123 | my_exit(); 124 | } 125 | } 126 | 127 | 128 | static void 129 | connectionDone(WMConnection *cPtr) 130 | { 131 | WMCloseConnection(cPtr); 132 | active--; 133 | succesful++; 134 | if (active == 0) { 135 | my_exit(); 136 | } 137 | } 138 | 139 | 140 | static void 141 | didReceiveInput(ConnectionDelegate *self, WMConnection *cPtr) 142 | { 143 | char buffer[65536], *reason; 144 | int res; 145 | TLSSession *tls = self->data; 146 | 147 | if (!tls->handshakeDone) { 148 | res = gnutls_handshake(tls->session); 149 | if (res == 0) { 150 | tls->handshakeDone = True; 151 | if (!verifyPeerCertificate(tls->session, &reason)) { 152 | if (verbose) 153 | printf("Peer verification failed: %s\n", reason); 154 | connectionFailed(cPtr, True); 155 | } else { 156 | gnutls_record_send(tls->session, "GET /\r\n", 7); 157 | } 158 | } else if (res != GNUTLS_E_AGAIN) { 159 | connectionFailed(cPtr, True); 160 | } 161 | return; 162 | } else if (tls->doingBye) { 163 | res = gnutls_bye(tls->session, GNUTLS_SHUT_RDWR); 164 | if (res == GNUTLS_E_AGAIN) 165 | return; 166 | connectionDone(cPtr); 167 | return; 168 | } 169 | 170 | res = gnutls_record_recv(tls->session, (void*)buffer, 65535); 171 | if (verbose >= 2) 172 | printf("received: %d: %s\n", res, buffer); 173 | 174 | res = gnutls_bye(tls->session, GNUTLS_SHUT_RDWR); 175 | if (res == GNUTLS_E_AGAIN) { 176 | tls->doingBye = True; 177 | return; 178 | } 179 | 180 | connectionDone(cPtr); 181 | } 182 | 183 | 184 | static void 185 | connectionDidDie(ConnectionDelegate *self, WMConnection *cPtr) 186 | { 187 | WMCloseConnection(cPtr); 188 | if (verbose) 189 | fprintf(stderr, "Connection closed by peer.\n"); 190 | exit(0); 191 | } 192 | 193 | 194 | static void 195 | didInitialize(ConnectionDelegate *self, WMConnection *cPtr) 196 | { 197 | int state = WMGetConnectionState(cPtr); 198 | TLSSession *tls = self->data; 199 | int res; 200 | 201 | if (state == WCConnected) { 202 | tls->handshakeDone = False; 203 | res = gnutls_handshake(tls->session); 204 | return; 205 | } else { 206 | if (verbose) 207 | wsyserrorwithcode(WCErrorCode, "Unable to connect"); 208 | connectionFailed(cPtr, False); 209 | } 210 | } 211 | 212 | 213 | void 214 | print_help(char *ProgName) 215 | { 216 | printf("Usage: %s [options] [host]\n", ProgName); 217 | #define P(m) puts(m) 218 | P(""); 219 | P(" -p, --port port to connect to (10000)"); 220 | P(" -v, --verify verify peer certificates"); 221 | P(" -n, --no-certs do not send any certificates"); 222 | P(" -V --verbose be verbose (twice for extra verbosity)"); 223 | P(" -h --help show this help message and exit"); 224 | #undef P 225 | } 226 | 227 | 228 | int 229 | main(int argc, char **argv) 230 | { 231 | char *ProgName, *host, *port; 232 | int i, sock, send_certs; 233 | gnutls_certificate_credentials_t x509_cred; 234 | WMConnection *sPtr[TRIES]; 235 | TLSSession *tls; 236 | 237 | wsetabort(wAbort); 238 | 239 | WMInitializeApplication("connect", &argc, argv); 240 | 241 | ProgName = strrchr(argv[0],'/'); 242 | if (!ProgName) 243 | ProgName = argv[0]; 244 | else 245 | ProgName++; 246 | 247 | verbose = 0; 248 | 249 | host = NULL; 250 | port = "10000"; 251 | verify_peer = False; 252 | send_certs = True; 253 | 254 | if (argc>1) { 255 | for (i=1; i=argc) { 262 | wfatal("too few arguments for %s\n", argv[i-1]); 263 | exit(1); 264 | } 265 | port = argv[i]; 266 | } else if (strcmp(argv[i], "--verify")==0 || strcmp(argv[i], "-v")==0) { 267 | verify_peer = True; 268 | } else if (strcmp(argv[i], "--no-certs")==0 || strcmp(argv[i], "-n")==0) { 269 | send_certs = False; 270 | } else if (strcmp(argv[i], "--verbose")==0 || strcmp(argv[i], "-V")==0) { 271 | verbose++; 272 | } else { 273 | if (!host) { 274 | host = argv[i]; 275 | } else { 276 | printf("%s: invalid argument '%s'\n", argv[0], argv[i]); 277 | printf("Try '%s --help' for more information\n", argv[0]); 278 | exit(1); 279 | } 280 | } 281 | } 282 | } 283 | 284 | gnutls_global_init(); 285 | gnutls_certificate_allocate_credentials(&x509_cred); 286 | gnutls_certificate_set_x509_trust_file(x509_cred, CAFILE, 287 | GNUTLS_X509_FMT_PEM); 288 | if (send_certs) { 289 | gnutls_certificate_set_x509_key_file(x509_cred, CERTFILE, KEYFILE, 290 | GNUTLS_X509_FMT_PEM); 291 | } 292 | 293 | 294 | //printf("Attempting connection to %s:%s\n", host?host:"localhost", port); 295 | 296 | gettimeofday(&start, NULL); 297 | 298 | for (i=0; isession), GNUTLS_CLIENT); 308 | gnutls_set_default_priority(tls->session); 309 | 310 | gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, x509_cred); 311 | 312 | sock = WMGetConnectionSocket(sPtr[i]); 313 | gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr_t)sock); 314 | 315 | tls->handshakeDone = False; 316 | tls->doingBye = False; 317 | 318 | socketDelegate[i].didDie = connectionDidDie; 319 | socketDelegate[i].didInitialize = didInitialize; 320 | socketDelegate[i].didReceiveInput = didReceiveInput; 321 | socketDelegate[i].data = tls; 322 | 323 | WMSetConnectionDelegate(sPtr[i], &socketDelegate[i]); 324 | } 325 | 326 | active = TRIES; 327 | 328 | while (1) { 329 | WHandleEvents(); 330 | } 331 | 332 | return 0; 333 | 334 | } 335 | 336 | 337 | -------------------------------------------------------------------------------- /test/gnutls-server: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec gnutls-serv --x509cafile ../examples/certs/ca.pem \ 4 | --x509keyfile ../examples/certs/valid.key \ 5 | --x509certfile ../examples/certs/valid.crt \ 6 | --quiet --port 10000 "$@" 7 | 8 | -------------------------------------------------------------------------------- /test/openssl-server: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | exec openssl s_server -cert ../examples/certs/valid.crt \ 4 | -key ../examples/certs/valid.key \ 5 | -CAfile ../examples/certs/ca.pem \ 6 | -quiet -accept 10000 -www "$@" 7 | 8 | -------------------------------------------------------------------------------- /test/tc-gnutls.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | import sys, os 4 | script_path = os.path.realpath(os.path.dirname(sys.argv[0])) 5 | gnutls_path = os.path.realpath(os.path.join(script_path, '..')) 6 | sys.path[0:0] = [gnutls_path] 7 | 8 | from optparse import OptionParser 9 | from time import time 10 | 11 | from twisted.internet.protocol import ClientFactory 12 | from twisted.protocols.basic import LineOnlyReceiver 13 | from twisted.internet import reactor 14 | 15 | from gnutls.crypto import * 16 | from gnutls.connection import * 17 | from gnutls.errors import * 18 | from gnutls.interfaces.twisted import TLSContext, X509Credentials 19 | 20 | 21 | class EchoProtocol(LineOnlyReceiver): 22 | 23 | def connectionMade(self): 24 | self.sendLine('GET /') 25 | #self.transport.loseConnection() 26 | 27 | def lineReceived(self, line): 28 | self.transport.loseConnection() 29 | 30 | def connectionLost(self, reason): 31 | global active, succesful 32 | succesful += 1 33 | active -= 1 34 | if active == 0: 35 | reactor.stop() 36 | 37 | 38 | class EchoFactory(ClientFactory): 39 | protocol = EchoProtocol 40 | 41 | def clientConnectionFailed(self, connector, err): 42 | global active, failed 43 | failed += 1 44 | active -= 1 45 | if active == 0: 46 | reactor.stop() 47 | 48 | 49 | parser = OptionParser(usage="%prog [host]") 50 | parser.add_option("-c", "--count", dest="count", type="int", default=100, 51 | help="how many connections to establish (default = 100)", 52 | metavar="N") 53 | parser.add_option("-p", "--port", dest="port", type="int", default=10000, 54 | help="specify port to connect (default = 10000)", 55 | metavar="port") 56 | parser.add_option("-v", "--verify", dest="verify", action="store_true", 57 | default=False, help="verify peer certificates") 58 | parser.add_option("-n", "--no-certs", dest="send_certs", action="store_false", 59 | default=True, help="do not send any certificates") 60 | parser.add_option("-m", "--memory", dest="memory", action="store_true", default=0, 61 | help="debug memory leaks") 62 | 63 | options, args = parser.parse_args() 64 | 65 | if options.memory: 66 | from application.debug.memory import * 67 | 68 | host, port = args and args[0] or 'localhost', options.port 69 | count = options.count 70 | 71 | active = count 72 | succesful = 0 73 | failed = 0 74 | 75 | certs_path = os.path.join(gnutls_path, 'examples/certs') 76 | 77 | cert = X509Certificate(open(certs_path + '/valid.crt').read()) 78 | key = X509PrivateKey(open(certs_path + '/valid.key').read()) 79 | ca = X509Certificate(open(certs_path + '/ca.pem').read()) 80 | crl = X509CRL(open(certs_path + '/crl.pem').read()) 81 | if options.send_certs: 82 | cred = X509Credentials(cert, key, [ca]) 83 | else: 84 | cred = X509Credentials(trusted=[ca]) 85 | cred.verify_peer = options.verify 86 | context = TLSContext(cred) 87 | 88 | echo_factory = EchoFactory() 89 | 90 | start_time = time() 91 | 92 | for x in range(count): 93 | reactor.connectTLS(host, port, echo_factory, context) 94 | reactor.run() 95 | 96 | duration = time() - start_time 97 | rate = count / duration 98 | print "time={:.2f} sec; rate={} requests/sec with {}:{}".format(duration, int(rate), host, port) 99 | 100 | if failed > 0: 101 | print "{} out of {} connections have failed".format(failed, count) 102 | 103 | if options.memory: 104 | memory_dump() 105 | -------------------------------------------------------------------------------- /test/tc-openssl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | import sys, os 4 | script_path = os.path.realpath(os.path.dirname(sys.argv[0])) 5 | gnutls_path = os.path.realpath(os.path.join(script_path, '..')) 6 | sys.path[0:0] = [gnutls_path] 7 | 8 | from optparse import OptionParser 9 | from time import time 10 | 11 | from twisted.internet.protocol import ClientFactory 12 | from twisted.protocols.basic import LineOnlyReceiver 13 | from twisted.internet import reactor 14 | 15 | import itertools, md5 16 | from OpenSSL import SSL, crypto 17 | from twisted.python import reflect, util 18 | from application import log 19 | 20 | 21 | # Private - shared between all ServerContextFactories, counts up to 22 | # provide a unique session id for each context 23 | _sessionCounter = itertools.count().next 24 | 25 | 26 | class _SSLApplicationData(object): 27 | def __init__(self): 28 | self.problems = [] 29 | 30 | 31 | # use twisted.internet._sslverify for this context factory, when it becomes available in the debian package -Mircea 32 | class OpenSSLContextFactory(object): 33 | """A factory for SSL context objects, for server SSL connections.""" 34 | 35 | _context = None 36 | # Older versions of PyOpenSSL didn't provide OP_ALL. Fudge it here, just in case. 37 | _OP_ALL = getattr(SSL, 'OP_ALL', 0x0000FFFF) 38 | 39 | method = SSL.TLSv1_METHOD 40 | 41 | def __init__(self, privateKey=None, certificate=None, method=None, verify=False, caCerts=None, 42 | enableSessions=True): 43 | """ 44 | Create an OpenSSL context SSL connection context factory. 45 | 46 | @param privateKey: A PKey object holding the private key. 47 | 48 | @param certificate: An X509 object holding the certificate. 49 | 50 | @param method: The SSL protocol to use, one of SSLv23_METHOD, 51 | SSLv2_METHOD, SSLv3_METHOD, TLSv1_METHOD. Defaults to TLSv1_METHOD. 52 | 53 | @param verify: If True, verify certificates received from the peer and 54 | fail the handshake if verification fails. Otherwise, allow anonymous 55 | sessions and sessions with certificates which fail validation. By 56 | default this is False. 57 | 58 | @param caCerts: List of certificate authority certificates to 59 | send to the client when requesting a certificate. Only used if verify 60 | is True, and if verify is True, either this must be specified or 61 | caCertsFile must be given. Since verify is False by default, 62 | this is None by default. 63 | 64 | @param enableSessions: If True, set a session ID on each context. This 65 | allows a shortened handshake to be used when a known client reconnects. 66 | """ 67 | 68 | assert (privateKey is None) == (certificate is None), "Specify neither or both of privateKey and certificate" 69 | self.privateKey = privateKey 70 | self.certificate = certificate 71 | if method is not None: 72 | self.method = method 73 | 74 | self.verify = verify 75 | assert ((verify and caCerts) or 76 | (not verify)), "Specify client CA certificate information if and only if enabling certificate verification" 77 | 78 | self.caCerts = caCerts 79 | self.enableSessions = enableSessions 80 | 81 | def getContext(self): 82 | """Return a SSL.Context object. 83 | """ 84 | if self._context is None: 85 | self._context = self._makeContext() 86 | return self._context 87 | 88 | def _makeContext(self): 89 | ctx = SSL.Context(self.method) 90 | ctx.set_app_data(_SSLApplicationData()) 91 | 92 | if self.certificate is not None and self.privateKey is not None: 93 | ctx.use_certificate(self.certificate) 94 | ctx.use_privatekey(self.privateKey) 95 | # Sanity check 96 | ctx.check_privatekey() 97 | 98 | verifyFlags = SSL.VERIFY_NONE 99 | if self.verify: 100 | verifyFlags = SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT 101 | if self.caCerts: 102 | store = ctx.get_cert_store() 103 | for cert in self.caCerts: 104 | store.add_cert(cert) 105 | 106 | def _trackVerificationProblems(conn,cert,errno,depth,preverify_ok): 107 | return True 108 | 109 | ctx.set_verify(verifyFlags, _trackVerificationProblems) 110 | 111 | if self.enableSessions: 112 | sessionName = md5.md5("%s-%d" % (reflect.qual(self.__class__), _sessionCounter())).hexdigest() 113 | ctx.set_session_id(sessionName) 114 | 115 | return ctx 116 | 117 | 118 | class Certificate(object): 119 | """Configuration data type. Used to create a OpenSSL.crypto.X509 object from a file given in the configuration file.""" 120 | def __new__(typ, value): 121 | if isinstance(value, basestring): 122 | try: 123 | f = open(value, 'rt') 124 | except: 125 | log.warn("Certificate file '%s' could not be open" % value) 126 | return None 127 | try: 128 | try: 129 | return crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) 130 | except crypto.Error, e: 131 | log.warn("Certificate file '%s' could not be loaded: %s" % (value, str(e))) 132 | return None 133 | finally: 134 | f.close() 135 | else: 136 | raise TypeError, 'value should be a string' 137 | 138 | 139 | class PrivateKey(object): 140 | """Configuration data type. Used to create a OpenSSL.crypto.PKey object from a file given in the configuration file.""" 141 | def __new__(typ, value): 142 | if isinstance(value, basestring): 143 | try: 144 | f = open(value, 'rt') 145 | except: 146 | log.warn("Private key file '%s' could not be open" % value) 147 | return None 148 | try: 149 | try: 150 | return crypto.load_privatekey(crypto.FILETYPE_PEM, f.read()) 151 | except crypto.Error, e: 152 | log.warn("Private key file '%s' could not be loaded: %s" % (value, str(e))) 153 | return None 154 | finally: 155 | f.close() 156 | else: 157 | raise TypeError, 'value should be a string' 158 | 159 | 160 | class EchoProtocol(LineOnlyReceiver): 161 | 162 | def connectionMade(self): 163 | self.sendLine('GET /') 164 | #self.transport.loseConnection() 165 | 166 | def lineReceived(self, line): 167 | #print 'received: ', line 168 | self.transport.loseConnection() 169 | 170 | def connectionLost(self, reason): 171 | global active, succesful 172 | succesful += 1 173 | active -= 1 174 | if active == 0: 175 | reactor.stop() 176 | 177 | class EchoFactory(ClientFactory): 178 | protocol = EchoProtocol 179 | 180 | def clientConnectionFailed(self, connector, err): 181 | global active, failed 182 | failed += 1 183 | active -= 1 184 | if active == 0: 185 | reactor.stop() 186 | 187 | 188 | parser = OptionParser(usage="%prog [host]") 189 | parser.add_option("-c", "--count", dest="count", type="int", default=100, 190 | help="how many connections to establish (default = 100)", 191 | metavar="N") 192 | parser.add_option("-p", "--port", dest="port", type="int", default=10000, 193 | help="specify port to connect (default = 10000)", 194 | metavar="port") 195 | parser.add_option("-v", "--verify", dest="verify", action="store_true", 196 | default=False, help="verify peer certificates") 197 | parser.add_option("-n", "--no-certs", dest="send_certs", action="store_false", 198 | default=True, help="do not send any certificates") 199 | 200 | options, args = parser.parse_args() 201 | 202 | host, port = args and args[0] or 'localhost', options.port 203 | count = options.count 204 | 205 | active = count 206 | succesful = 0 207 | failed = 0 208 | 209 | certs_path = os.path.join(gnutls_path, 'examples/certs') 210 | 211 | cert = Certificate(certs_path + '/valid.crt') 212 | key = PrivateKey(certs_path + '/valid.key') 213 | ca = Certificate(certs_path + '/ca.pem') 214 | if options.send_certs: 215 | ctx_factory = OpenSSLContextFactory(key, cert, verify=options.verify, caCerts=[ca]) 216 | else: 217 | ctx_factory = OpenSSLContextFactory(verify=options.verify, caCerts=[ca]) 218 | 219 | echo_factory = EchoFactory() 220 | 221 | start_time = time() 222 | 223 | for x in range(count): 224 | reactor.connectSSL(host, port, echo_factory, ctx_factory) 225 | reactor.run() 226 | 227 | duration = time() - start_time 228 | rate = count / duration 229 | print "time={:.2f} sec; rate={} requests/sec with {}:{}".format(duration, int(rate), host, port) 230 | 231 | if failed > 0: 232 | print "{} out of {} connections have failed".format(failed, count) 233 | -------------------------------------------------------------------------------- /test/ts-gnutls.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | import sys, os 4 | script_path = os.path.realpath(os.path.dirname(sys.argv[0])) 5 | gnutls_path = os.path.realpath(os.path.join(script_path, '..')) 6 | sys.path[0:0] = [gnutls_path] 7 | 8 | # This has the side effect of starting logging. 9 | # Do not delete it, even if it is not used anywhere. 10 | from application import log 11 | 12 | from optparse import OptionParser 13 | 14 | from twisted.internet.protocol import Factory 15 | from twisted.protocols.basic import LineOnlyReceiver 16 | from twisted.internet.error import CannotListenError, ConnectionDone 17 | from twisted.internet import reactor 18 | 19 | from gnutls.crypto import * 20 | from gnutls.errors import * 21 | from gnutls.interfaces.twisted import TLSContext, X509Credentials 22 | 23 | class EchoProtocol(LineOnlyReceiver): 24 | 25 | def connectionMade(self): 26 | if not options.verbose: 27 | return 28 | session = self.transport.socket 29 | try: 30 | peer_name = session.peer_certificate.subject 31 | except AttributeError: 32 | peer_name = 'Unknown' 33 | print '\nNew connection from:', peer_name 34 | print 'Protocol: ', session.protocol 35 | print 'KX algorithm: ', session.kx_algorithm 36 | print 'Cipher: ', session.cipher 37 | print 'MAC algorithm:', session.mac_algorithm 38 | print 'Compression: ', session.compression 39 | 40 | def lineReceived(self, line): 41 | if line == 'quit': 42 | self.transport.loseConnection() 43 | return 44 | self.sendLine(line) 45 | 46 | def connectionLost(self, reason): 47 | if options.verbose and reason.type != ConnectionDone: 48 | print "Connection was lost:", str(reason.value) 49 | 50 | 51 | class EchoFactory(Factory): 52 | protocol = EchoProtocol 53 | noisy = False 54 | 55 | parser = OptionParser() 56 | parser.add_option("-p", "--port", dest="port", type="int", default=10000, 57 | help="specify port to listen on (default = 10000)", 58 | metavar="port") 59 | parser.add_option("-v", "--verify", dest="verify", action="store_true", default=0, 60 | help="verify peer certificates") 61 | parser.add_option("-V", "--verbose", dest="verbose", action="store_true", default=0, 62 | help="verbose output") 63 | parser.add_option("-m", "--memory", dest="memory", action="store_true", default=0, 64 | help="debug memory leaks") 65 | 66 | options, args = parser.parse_args() 67 | 68 | if options.memory: 69 | from application.debug.memory import * 70 | 71 | certs_path = os.path.join(gnutls_path, 'examples/certs') 72 | 73 | cert = X509Certificate(open(certs_path + '/valid.crt').read()) 74 | key = X509PrivateKey(open(certs_path + '/valid.key').read()) 75 | ca = X509Certificate(open(certs_path + '/ca.pem').read()) 76 | crl = X509CRL(open(certs_path + '/crl.pem').read()) 77 | cred = X509Credentials(cert, key, [ca], [crl]) 78 | cred.verify_peer = options.verify 79 | context = TLSContext(cred) 80 | 81 | reactor.listenTLS(options.port, EchoFactory(), context) 82 | reactor.run() 83 | 84 | if options.memory: 85 | memory_dump() 86 | -------------------------------------------------------------------------------- /test/ts-openssl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | 3 | import sys, os 4 | script_path = os.path.realpath(os.path.dirname(sys.argv[0])) 5 | gnutls_path = os.path.realpath(os.path.join(script_path, '..')) 6 | sys.path[0:0] = [gnutls_path] 7 | 8 | from optparse import OptionParser 9 | 10 | from twisted.internet.protocol import Factory 11 | from twisted.protocols.basic import LineOnlyReceiver 12 | from twisted.internet.error import CannotListenError, ConnectionDone 13 | from twisted.internet import reactor 14 | 15 | import itertools, md5 16 | from OpenSSL import SSL, crypto 17 | from twisted.python import reflect, util 18 | from application.process import process 19 | from application import log 20 | 21 | # Private - shared between all ServerContextFactories, counts up to 22 | # provide a unique session id for each context 23 | _sessionCounter = itertools.count().next 24 | 25 | 26 | class _SSLApplicationData(object): 27 | def __init__(self): 28 | self.problems = [] 29 | 30 | 31 | # use twisted.internet._sslverify for this context factory, when it becomes available in the debian package -Mircea 32 | class OpenSSLContextFactory(object): 33 | """A factory for SSL context objects, for server SSL connections.""" 34 | 35 | _context = None 36 | # Older versions of PyOpenSSL didn't provide OP_ALL. Fudge it here, just in case. 37 | _OP_ALL = getattr(SSL, 'OP_ALL', 0x0000FFFF) 38 | 39 | method = SSL.TLSv1_METHOD 40 | 41 | def __init__(self, privateKey=None, certificate=None, method=None, verify=False, caCerts=None, 42 | enableSessions=True): 43 | """ 44 | Create an OpenSSL context SSL connection context factory. 45 | 46 | @param privateKey: A PKey object holding the private key. 47 | 48 | @param certificate: An X509 object holding the certificate. 49 | 50 | @param method: The SSL protocol to use, one of SSLv23_METHOD, 51 | SSLv2_METHOD, SSLv3_METHOD, TLSv1_METHOD. Defaults to TLSv1_METHOD. 52 | 53 | @param verify: If True, verify certificates received from the peer and 54 | fail the handshake if verification fails. Otherwise, allow anonymous 55 | sessions and sessions with certificates which fail validation. By 56 | default this is False. 57 | 58 | @param caCerts: List of certificate authority certificates to 59 | send to the client when requesting a certificate. Only used if verify 60 | is True, and if verify is True, either this must be specified or 61 | caCertsFile must be given. Since verify is False by default, 62 | this is None by default. 63 | 64 | @param enableSessions: If True, set a session ID on each context. This 65 | allows a shortened handshake to be used when a known client reconnects. 66 | """ 67 | 68 | assert (privateKey is None) == (certificate is None), "Specify neither or both of privateKey and certificate" 69 | self.privateKey = privateKey 70 | self.certificate = certificate 71 | if method is not None: 72 | self.method = method 73 | 74 | self.verify = verify 75 | assert ((verify and caCerts) or 76 | (not verify)), "Specify client CA certificate information if and only if enabling certificate verification" 77 | 78 | self.caCerts = caCerts 79 | self.enableSessions = enableSessions 80 | 81 | def getContext(self): 82 | """Return a SSL.Context object. 83 | """ 84 | if self._context is None: 85 | self._context = self._makeContext() 86 | return self._context 87 | 88 | def _makeContext(self): 89 | ctx = SSL.Context(self.method) 90 | ctx.set_app_data(_SSLApplicationData()) 91 | 92 | if self.certificate is not None and self.privateKey is not None: 93 | ctx.use_certificate(self.certificate) 94 | ctx.use_privatekey(self.privateKey) 95 | # Sanity check 96 | ctx.check_privatekey() 97 | 98 | verifyFlags = SSL.VERIFY_NONE 99 | if self.verify: 100 | verifyFlags = SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT 101 | if self.caCerts: 102 | store = ctx.get_cert_store() 103 | for cert in self.caCerts: 104 | store.add_cert(cert) 105 | 106 | def _trackVerificationProblems(conn,cert,errno,depth,preverify_ok): 107 | return True 108 | 109 | ctx.set_verify(verifyFlags, _trackVerificationProblems) 110 | 111 | if self.enableSessions: 112 | sessionName = md5.md5("%s-%d" % (reflect.qual(self.__class__), _sessionCounter())).hexdigest() 113 | ctx.set_session_id(sessionName) 114 | 115 | return ctx 116 | 117 | 118 | class Certificate(object): 119 | """Configuration data type. Used to create a OpenSSL.crypto.X509 object from a file given in the configuration file.""" 120 | def __new__(typ, value): 121 | if isinstance(value, basestring): 122 | try: 123 | f = open(value, 'rt') 124 | except: 125 | log.warn("Certificate file '%s' could not be open" % value) 126 | return None 127 | try: 128 | try: 129 | return crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) 130 | except crypto.Error, e: 131 | log.warn("Certificate file '%s' could not be loaded: %s" % (value, str(e))) 132 | return None 133 | finally: 134 | f.close() 135 | else: 136 | raise TypeError, 'value should be a string' 137 | 138 | 139 | class PrivateKey(object): 140 | """Configuration data type. Used to create a OpenSSL.crypto.PKey object from a file given in the configuration file.""" 141 | def __new__(typ, value): 142 | if isinstance(value, basestring): 143 | try: 144 | f = open(value, 'rt') 145 | except: 146 | log.warn("Private key file '%s' could not be open" % value) 147 | return None 148 | try: 149 | try: 150 | return crypto.load_privatekey(crypto.FILETYPE_PEM, f.read()) 151 | except crypto.Error, e: 152 | log.warn("Private key file '%s' could not be loaded: %s" % (value, str(e))) 153 | return None 154 | finally: 155 | f.close() 156 | else: 157 | raise TypeError, 'value should be a string' 158 | 159 | 160 | class EchoProtocol(LineOnlyReceiver): 161 | 162 | def connectionMade(self): 163 | session = self.transport.socket 164 | 165 | def lineReceived(self, line): 166 | if line == 'quit': 167 | self.transport.loseConnection() 168 | return 169 | self.sendLine(line) 170 | 171 | class EchoFactory(Factory): 172 | protocol = EchoProtocol 173 | noisy = False 174 | 175 | 176 | parser = OptionParser() 177 | parser.add_option("-p", "--port", dest="port", type="int", default=10000, 178 | help="specify port to listen on (default = 10000)", 179 | metavar="port") 180 | parser.add_option("-v", "--verify", dest="verify", action="store_true", default=0, 181 | help="verify peer certificates (default = no)") 182 | 183 | options, args = parser.parse_args() 184 | 185 | 186 | certs_path = os.path.join(gnutls_path, 'examples/certs') 187 | 188 | cert = Certificate(certs_path + '/valid.crt') 189 | key = PrivateKey(certs_path + '/valid.key') 190 | ca = Certificate(certs_path + '/ca.pem') 191 | ctx_factory = OpenSSLContextFactory(key, cert, verify=options.verify, caCerts=[ca]) 192 | 193 | echo_factory = EchoFactory() 194 | 195 | reactor.listenSSL(options.port, EchoFactory(), ctx_factory) 196 | reactor.run() 197 | --------------------------------------------------------------------------------